From 4070f1cca3c0875f2822ab4b1eb7ea7582dcf437 Mon Sep 17 00:00:00 2001 From: xiwa Date: Sun, 10 Dec 2023 23:05:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E4=BF=AE=E5=A4=8D=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E9=87=8D=E5=90=AF=E6=8A=A5=E9=94=99=E3=80=81=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?iotdb=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- iot-dao/iot-data-model/pom.xml | 4 +- iot-dao/iot-data-service/pom.xml | 4 +- iot-dao/iot-data-serviceImpl-cache/pom.xml | 4 +- iot-dao/iot-data-serviceImpl-rdb/pom.xml | 4 +- iot-dao/iot-temporal-service/pom.xml | 4 +- iot-dao/iot-temporal-serviceImpl-es/pom.xml | 2 +- .../iot-temporal-serviceImpl-iotdb/pom.xml | 57 +++ .../temporal/iotdb/config/IotDbConf.java | 38 ++ .../temporal/iotdb/dao/IotDbTemplate.java | 74 ++++ .../iotkit/temporal/iotdb/model/Record.java | 23 ++ .../iotdb/service/DbStructureDataImpl.java | 46 +++ .../iotdb/service/DevicePropertyDataImpl.java | 72 ++++ .../iotdb/service/RuleLogDataImpl.java | 32 ++ .../iotdb/service/TaskLogDataImpl.java | 32 ++ .../service/ThingModelMessageDataImpl.java | 44 ++ .../service/VirtualDeviceLogDataImpl.java | 28 ++ iot-dao/iot-temporal-serviceImpl-td/pom.xml | 4 +- iot-dao/iot-temporal-serviceImpl-ts/pom.xml | 4 +- iot-dao/pom.xml | 3 +- iot-module/iot-manager/pom.xml | 2 +- .../service/impl/PluginServiceImpl.java | 24 ++ iot-module/iot-message-notify/pom.xml | 2 +- iot-module/iot-openapi/pom.xml | 2 +- iot-module/iot-plugin/iot-plugin-core/pom.xml | 2 +- .../iotkit/plugin/core/LocalPluginScript.java | 3 +- iot-module/iot-plugin/iot-plugin-main/pom.xml | 2 +- .../cc/iotkit/plugin/main/PluginMainImpl.java | 22 +- .../cc/iotkit/plugin/main/script/Chan.java | 44 ++ .../plugin/main/script/DataDecoder.java | 46 +++ .../plugin/main/script/DataEncoder.java | 42 ++ .../plugin/main/script/DataPackage.java | 45 +++ .../iotkit/plugin/main/script/DataReader.java | 45 +++ .../main/script/PluginScriptEngine.java | 77 ++++ .../main/script/PluginScriptServer.java | 48 +++ .../main/script/ScriptClientVerticle.java | 83 ++++ .../main/script/ScriptServerConfig.java | 30 ++ .../plugin/main/script/ScriptVerticle.java | 142 +++++++ .../plugin/main/script/VertxTcpClient.java | 94 +++++ iot-module/iot-plugin/pom.xml | 3 +- .../spring-brick-maven-packager/pom.xml | 101 +++++ .../pack/AbstractDependencyFilterMojo.java | 108 +++++ .../plugin/pack/AbstractPackagerMojo.java | 93 +++++ .../plugin/pack/BasicRepackager.java | 380 ++++++++++++++++++ .../gitee/starblues/plugin/pack/Constant.java | 85 ++++ .../starblues/plugin/pack/Dependency.java | 38 ++ .../plugin/pack/DependencyPlugin.java | 73 ++++ .../plugin/pack/LoadMainResourcePattern.java | 38 ++ .../starblues/plugin/pack/LoadToMain.java | 35 ++ .../starblues/plugin/pack/PluginInfo.java | 92 +++++ .../starblues/plugin/pack/RepackageMojo.java | 133 ++++++ .../starblues/plugin/pack/Repackager.java | 39 ++ .../starblues/plugin/pack/dev/Dependency.java | 41 ++ .../starblues/plugin/pack/dev/DevConfig.java | 44 ++ .../plugin/pack/dev/DevRepackager.java | 102 +++++ .../plugin/pack/encrypt/AesConfig.java | 33 ++ .../plugin/pack/encrypt/AesEncryptPlugin.java | 43 ++ .../plugin/pack/encrypt/EncryptConfig.java | 41 ++ .../plugin/pack/encrypt/EncryptPlugin.java | 40 ++ .../pack/encrypt/EncryptPluginFactory.java | 50 +++ .../plugin/pack/encrypt/RsaConfig.java | 36 ++ .../plugin/pack/encrypt/RsaEncryptPlugin.java | 57 +++ .../plugin/pack/filter/DependencyFilter.java | 75 ++++ .../starblues/plugin/pack/filter/Exclude.java | 35 ++ .../plugin/pack/filter/ExcludeFilter.java | 51 +++ .../pack/filter/FilterableDependency.java | 38 ++ .../starblues/plugin/pack/filter/Include.java | 27 ++ .../plugin/pack/filter/IncludeFilter.java | 46 +++ .../plugin/pack/main/JarNestPackager.java | 138 +++++++ .../plugin/pack/main/JarOuterPackager.java | 146 +++++++ .../plugin/pack/main/MainConfig.java | 68 ++++ .../plugin/pack/main/MainRepackager.java | 136 +++++++ .../plugin/pack/prod/DirProdRepackager.java | 156 +++++++ .../pack/prod/JarNestedProdRepackager.java | 77 ++++ .../pack/prod/JarOuterProdRepackager.java | 56 +++ .../plugin/pack/prod/ProdConfig.java | 59 +++ .../plugin/pack/prod/ProdRepackager.java | 95 +++++ .../pack/prod/ZipOuterProdRepackager.java | 128 ++++++ .../plugin/pack/prod/ZipProdRepackager.java | 197 +++++++++ .../plugin/pack/utils/CommonUtils.java | 100 +++++ .../plugin/pack/utils/PackageJar.java | 58 +++ .../plugin/pack/utils/PackageZip.java | 249 ++++++++++++ .../plugin-help.xml | 168 ++++++++ .../main/resources/META-INF/maven/plugin.xml | 168 ++++++++ iot-module/iot-rule-engine/pom.xml | 2 +- iot-module/iot-screen/pom.xml | 2 +- iot-module/iot-system/pom.xml | 2 +- iot-module/pom.xml | 2 +- iot-starter/pom.xml | 2 +- .../src/main/resources/application.yml | 36 +- iot-test-tool/iot-virtual-device/pom.xml | 2 +- iot-test-tool/pom.xml | 2 +- pom.xml | 4 +- 92 files changed, 5199 insertions(+), 65 deletions(-) create mode 100644 iot-dao/iot-temporal-serviceImpl-iotdb/pom.xml create mode 100644 iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/config/IotDbConf.java create mode 100644 iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/dao/IotDbTemplate.java create mode 100644 iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/model/Record.java create mode 100644 iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/DbStructureDataImpl.java create mode 100644 iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/DevicePropertyDataImpl.java create mode 100644 iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/RuleLogDataImpl.java create mode 100644 iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/TaskLogDataImpl.java create mode 100644 iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/ThingModelMessageDataImpl.java create mode 100644 iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/VirtualDeviceLogDataImpl.java create mode 100644 iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/Chan.java create mode 100644 iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataDecoder.java create mode 100644 iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataEncoder.java create mode 100644 iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataPackage.java create mode 100644 iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataReader.java create mode 100644 iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/PluginScriptEngine.java create mode 100644 iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/PluginScriptServer.java create mode 100644 iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/ScriptClientVerticle.java create mode 100644 iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/ScriptServerConfig.java create mode 100644 iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/ScriptVerticle.java create mode 100644 iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/VertxTcpClient.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/pom.xml create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractDependencyFilterMojo.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractPackagerMojo.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/BasicRepackager.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Constant.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Dependency.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/DependencyPlugin.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/LoadMainResourcePattern.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/LoadToMain.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/PluginInfo.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/RepackageMojo.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Repackager.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/Dependency.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevConfig.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevRepackager.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesConfig.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesEncryptPlugin.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptConfig.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPlugin.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPluginFactory.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaConfig.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaEncryptPlugin.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/DependencyFilter.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/Exclude.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/ExcludeFilter.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/FilterableDependency.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/Include.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/IncludeFilter.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarNestPackager.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarOuterPackager.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainConfig.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainRepackager.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/DirProdRepackager.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/JarNestedProdRepackager.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/JarOuterProdRepackager.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ProdConfig.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ProdRepackager.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ZipOuterProdRepackager.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ZipProdRepackager.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/CommonUtils.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageJar.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageZip.java create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/resources/META-INF/maven/com.gitee.starblues.springboot-plugin-maven-packager/plugin-help.xml create mode 100644 iot-module/iot-plugin/spring-brick-maven-packager/src/main/resources/META-INF/maven/plugin.xml diff --git a/iot-dao/iot-data-model/pom.xml b/iot-dao/iot-data-model/pom.xml index eba07622..8b287a3d 100644 --- a/iot-dao/iot-data-model/pom.xml +++ b/iot-dao/iot-data-model/pom.xml @@ -5,9 +5,9 @@ iot-dao cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 iot-data-model diff --git a/iot-dao/iot-data-service/pom.xml b/iot-dao/iot-data-service/pom.xml index a48c2b8c..2de342e0 100644 --- a/iot-dao/iot-data-service/pom.xml +++ b/iot-dao/iot-data-service/pom.xml @@ -5,10 +5,10 @@ iot-dao cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT iot-data-service diff --git a/iot-dao/iot-data-serviceImpl-cache/pom.xml b/iot-dao/iot-data-serviceImpl-cache/pom.xml index 79161757..e8907de6 100644 --- a/iot-dao/iot-data-serviceImpl-cache/pom.xml +++ b/iot-dao/iot-data-serviceImpl-cache/pom.xml @@ -5,10 +5,10 @@ iot-dao cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT iot-data-serviceImpl-cache diff --git a/iot-dao/iot-data-serviceImpl-rdb/pom.xml b/iot-dao/iot-data-serviceImpl-rdb/pom.xml index cfd6a0c8..bc27179f 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/pom.xml +++ b/iot-dao/iot-data-serviceImpl-rdb/pom.xml @@ -5,9 +5,9 @@ iot-dao cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 iot-data-serviceImpl-rdb diff --git a/iot-dao/iot-temporal-service/pom.xml b/iot-dao/iot-temporal-service/pom.xml index 66820e0a..506dbb3a 100644 --- a/iot-dao/iot-temporal-service/pom.xml +++ b/iot-dao/iot-temporal-service/pom.xml @@ -5,10 +5,10 @@ iot-dao cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT iot-temporal-service diff --git a/iot-dao/iot-temporal-serviceImpl-es/pom.xml b/iot-dao/iot-temporal-serviceImpl-es/pom.xml index 0e6f4829..bdbbb71e 100644 --- a/iot-dao/iot-temporal-serviceImpl-es/pom.xml +++ b/iot-dao/iot-temporal-serviceImpl-es/pom.xml @@ -5,7 +5,7 @@ iot-dao cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 diff --git a/iot-dao/iot-temporal-serviceImpl-iotdb/pom.xml b/iot-dao/iot-temporal-serviceImpl-iotdb/pom.xml new file mode 100644 index 00000000..2c342d2a --- /dev/null +++ b/iot-dao/iot-temporal-serviceImpl-iotdb/pom.xml @@ -0,0 +1,57 @@ + + + + iot-dao + cc.iotkit + 0.5.1-SNAPSHOT + + 4.0.0 + + iot-temporal-serviceImpl-iotdb + + + + + cc.iotkit + iot-temporal-service + + + + cc.iotkit + iot-data-serviceImpl-cache + + + + + + org.apache.iotdb + iotdb-session + 1.2.2 + + + + org.springframework + spring-context + + + + org.projectlombok + lombok + provided + + + + com.fasterxml.jackson.core + jackson-annotations + + + + io.github.linpeilie + mapstruct-plus-spring-boot-starter + + + + + \ No newline at end of file diff --git a/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/config/IotDbConf.java b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/config/IotDbConf.java new file mode 100644 index 00000000..22576eae --- /dev/null +++ b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/config/IotDbConf.java @@ -0,0 +1,38 @@ +package cc.iotkit.temporal.iotdb.config; + + +import org.apache.iotdb.session.pool.SessionPool; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * iotdb数据库配置 + * + * @author sjg + */ +@Configuration +public class IotDbConf { + + @Value("${spring.iotdb-datasource.host}") + private String host; + + @Value("${spring.iotdb-datasource.port}") + private int port; + + @Value("${spring.iotdb-datasource.username}") + private String username; + + @Value("${spring.iotdb-datasource.password}") + private String password; + + @Bean + public SessionPool getSession() { + return new SessionPool.Builder() + .host(host) + .port(port) + .user(username) + .password(password) + .build(); + } +} diff --git a/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/dao/IotDbTemplate.java b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/dao/IotDbTemplate.java new file mode 100644 index 00000000..e0971fd1 --- /dev/null +++ b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/dao/IotDbTemplate.java @@ -0,0 +1,74 @@ +package cc.iotkit.temporal.iotdb.dao; + +import lombok.Data; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.iotdb.isession.pool.SessionDataSetWrapper; +import org.apache.iotdb.session.pool.SessionPool; +import org.apache.iotdb.tsfile.read.common.Field; +import org.apache.iotdb.tsfile.read.common.RowRecord; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author sjg + */ +@Slf4j +@Component +@Data +public class IotDbTemplate { + + @Autowired + private SessionPool sessionPool; + + private static String group = "root.iotkit"; + + private String getPath(String productKey, String deviceId) { + return group + "." + productKey + "." + deviceId; + } + + /** + * 对齐插入时序序列 + * @param productKey 产品key + * @param deviceId 设备id + * @param time 数据时间 + * @param data 数据键值对 + */ + @SneakyThrows + public void insert(String productKey, String deviceId, long time, Map data) { + String path = getPath(productKey, deviceId); + List measurements = new ArrayList<>(); + // 需要服务器做类型判断 + List values = new ArrayList<>(); + for (String key : data.keySet()) { + measurements.add(key); + values.add(String.valueOf(data.get(key))); + } + //对齐插入,使用PREVIOUS填充查询 + sessionPool.insertAlignedRecord(path, time, measurements, values); + } + + @SneakyThrows + public List> query(String productKey, String deviceId,long startTime,long endTime) { + List> list = new ArrayList<>(); + SessionDataSetWrapper dataSetWrapper = sessionPool.executeRawDataQuery( + List.of(getPath(productKey,deviceId)),startTime,endTime,5000); + while (dataSetWrapper.hasNext()) { + RowRecord record = dataSetWrapper.next(); + Map data = new HashMap<>(record.getFields().size() + 1); + long time = record.getTimestamp(); + data.put("time", time); + for (Field field : record.getFields()) { + field.getObjectValue(field.getDataType()); + } + list.add(data); + } + return list; + } + +} diff --git a/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/model/Record.java b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/model/Record.java new file mode 100644 index 00000000..c22bc3a8 --- /dev/null +++ b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/model/Record.java @@ -0,0 +1,23 @@ +package cc.iotkit.temporal.iotdb.model; + + +/** + * @author sjg + */ +public interface Record { + + /** + * 设备Id + * + * @return string + */ + String getDeviceId(); + + /** + * 时间 + * + * @return long + */ + Long getTime(); + +} diff --git a/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/DbStructureDataImpl.java b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/DbStructureDataImpl.java new file mode 100644 index 00000000..eb0a4920 --- /dev/null +++ b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/DbStructureDataImpl.java @@ -0,0 +1,46 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.temporal.iotdb.service; + +import cc.iotkit.common.enums.ErrCode; +import cc.iotkit.common.exception.BizException; +import cc.iotkit.model.product.ThingModel; +import cc.iotkit.temporal.IDbStructureData; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; + +@Slf4j +@Service +public class DbStructureDataImpl implements IDbStructureData { + + @SneakyThrows + @Override + public void defineThingModel(ThingModel thingModel) { + //无须处理,自动创建 + } + + @Override + public void updateThingModel(ThingModel thingModel) { + throw new BizException(ErrCode.UNSUPPORTED_OPERATION_EXCEPTION); + } + + /** + * 初始化其它数据结构 + */ + @Override + @PostConstruct + public void initDbStructure() { + + } + +} diff --git a/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/DevicePropertyDataImpl.java b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/DevicePropertyDataImpl.java new file mode 100644 index 00000000..59b3a439 --- /dev/null +++ b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/DevicePropertyDataImpl.java @@ -0,0 +1,72 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.temporal.iotdb.service; + +import cc.iotkit.data.manager.IDeviceInfoData; +import cc.iotkit.model.device.DeviceInfo; +import cc.iotkit.model.device.message.DeviceProperty; +import cc.iotkit.model.device.message.DevicePropertyCache; +import cc.iotkit.temporal.IDevicePropertyData; +import cc.iotkit.temporal.iotdb.dao.IotDbTemplate; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Slf4j +@Service +public class DevicePropertyDataImpl implements IDevicePropertyData { + + @Autowired + @Qualifier("deviceInfoDataCache") + private IDeviceInfoData deviceInfoData; + + @Autowired + private IotDbTemplate dbTemplate; + + @Override + public List findDevicePropertyHistory(String deviceId, String name, long start, long end, int size) { + DeviceInfo device = deviceInfoData.findByDeviceId(deviceId); + if (device == null) { + return new ArrayList<>(); + } + List list=new ArrayList<>(); + List> records = dbTemplate.query(device.getProductKey(), deviceId, start, end); + int i=0; + for (Map record : records) { + Object val = record.get(name); + list.add(new DeviceProperty(String.valueOf(++i),deviceId,name,val, (Long) record.get("time"))); + } + + return list; + } + + @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); + Map data = new HashMap<>(oldProperties.size()); + oldProperties.forEach((k, v) -> data.put(k, v.getValue())); + //添加对齐序列 + dbTemplate.insert(device.getProductKey(), deviceId, System.currentTimeMillis(), data); + } + +} diff --git a/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/RuleLogDataImpl.java b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/RuleLogDataImpl.java new file mode 100644 index 00000000..32aa6ba6 --- /dev/null +++ b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/RuleLogDataImpl.java @@ -0,0 +1,32 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.temporal.iotdb.service; + +import cc.iotkit.common.api.Paging; +import cc.iotkit.model.rule.RuleLog; +import cc.iotkit.temporal.IRuleLogData; +import org.springframework.stereotype.Service; + +@Service +public class RuleLogDataImpl implements IRuleLogData { + + @Override + public void deleteByRuleId(String ruleId) { + } + + @Override + public Paging findByRuleId(String ruleId, int page, int size) { + return new Paging<>(); + } + + @Override + public void add(RuleLog log) { + } +} diff --git a/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/TaskLogDataImpl.java b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/TaskLogDataImpl.java new file mode 100644 index 00000000..dded0549 --- /dev/null +++ b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/TaskLogDataImpl.java @@ -0,0 +1,32 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.temporal.iotdb.service; + +import cc.iotkit.common.api.Paging; +import cc.iotkit.model.rule.TaskLog; +import cc.iotkit.temporal.ITaskLogData; +import org.springframework.stereotype.Service; + +@Service +public class TaskLogDataImpl implements ITaskLogData { + + @Override + public void deleteByTaskId(String taskId) { + } + + @Override + public Paging findByTaskId(String taskId, int page, int size) { + return new Paging<>(); + } + + @Override + public void add(TaskLog log) { + } +} diff --git a/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/ThingModelMessageDataImpl.java b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/ThingModelMessageDataImpl.java new file mode 100644 index 00000000..b97fc6e3 --- /dev/null +++ b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/ThingModelMessageDataImpl.java @@ -0,0 +1,44 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.temporal.iotdb.service; + +import cc.iotkit.common.api.Paging; +import cc.iotkit.common.thing.ThingModelMessage; +import cc.iotkit.model.stats.TimeData; +import cc.iotkit.temporal.IThingModelMessageData; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class ThingModelMessageDataImpl implements IThingModelMessageData { + + @Override + public Paging findByTypeAndIdentifier(String deviceId, String type, + String identifier, + int page, int size) { + return new Paging<>(); + } + + @Override + public List getDeviceMessageStatsWithUid(String uid, long start, long end) { + return new ArrayList<>(); + } + + @Override + public void add(ThingModelMessage msg) { + } + + @Override + public long count() { + return 0L; + } +} diff --git a/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/VirtualDeviceLogDataImpl.java b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/VirtualDeviceLogDataImpl.java new file mode 100644 index 00000000..15a86183 --- /dev/null +++ b/iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/VirtualDeviceLogDataImpl.java @@ -0,0 +1,28 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.temporal.iotdb.service; + +import cc.iotkit.common.api.Paging; +import cc.iotkit.model.device.VirtualDeviceLog; +import cc.iotkit.temporal.IVirtualDeviceLogData; +import org.springframework.stereotype.Service; + +@Service +public class VirtualDeviceLogDataImpl implements IVirtualDeviceLogData { + + @Override + public Paging findByVirtualDeviceId(String virtualDeviceId, int page, int size) { + return new Paging<>(); + } + + @Override + public void add(VirtualDeviceLog log) { + } +} diff --git a/iot-dao/iot-temporal-serviceImpl-td/pom.xml b/iot-dao/iot-temporal-serviceImpl-td/pom.xml index d141b4b5..788f9a0e 100644 --- a/iot-dao/iot-temporal-serviceImpl-td/pom.xml +++ b/iot-dao/iot-temporal-serviceImpl-td/pom.xml @@ -5,10 +5,10 @@ iot-dao cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT iot-temporal-serviceImpl-td diff --git a/iot-dao/iot-temporal-serviceImpl-ts/pom.xml b/iot-dao/iot-temporal-serviceImpl-ts/pom.xml index 9024b0dd..b9678089 100644 --- a/iot-dao/iot-temporal-serviceImpl-ts/pom.xml +++ b/iot-dao/iot-temporal-serviceImpl-ts/pom.xml @@ -6,9 +6,9 @@ iot-dao cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT iot-temporal-serviceImpl-ts diff --git a/iot-dao/pom.xml b/iot-dao/pom.xml index e1a82f60..8b4902d1 100644 --- a/iot-dao/pom.xml +++ b/iot-dao/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 pom @@ -23,6 +23,7 @@ iot-temporal-service iot-temporal-serviceImpl-td iot-temporal-serviceImpl-es + iot-temporal-serviceImpl-iotdb iot-dao diff --git a/iot-module/iot-manager/pom.xml b/iot-module/iot-manager/pom.xml index bcdecb1e..168219c1 100644 --- a/iot-module/iot-manager/pom.xml +++ b/iot-module/iot-manager/pom.xml @@ -5,7 +5,7 @@ iot-module cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/PluginServiceImpl.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/PluginServiceImpl.java index bec64db7..3f18fba2 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/PluginServiceImpl.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/PluginServiceImpl.java @@ -15,14 +15,18 @@ 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.AutoIntegrationConfiguration; 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.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import java.io.File; import java.nio.charset.Charset; +import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -33,6 +37,9 @@ import java.util.jar.JarFile; @Service public class PluginServiceImpl implements IPluginService { + @Autowired + private AutoIntegrationConfiguration autoIntegrationConfiguration; + @Autowired private IPluginInfoData pluginInfoData; @@ -58,6 +65,17 @@ public class PluginServiceImpl implements IPluginService { pluginOperator.uninstall(pluginId, true, false); //兼容相同版本包,先删除,再上传 FileUtils.del(pluginInfo.getPluginDescriptor().getPluginPath()); + } else { + //删除对应插件的所有包 + for (String pluginPath : autoIntegrationConfiguration.getPluginPath()) { + List fileNames = FileUtils.listFileNames(new File(pluginPath).getAbsolutePath()); + for (String fileName : fileNames) { + if (!fileName.startsWith(pluginId)) { + continue; + } + FileUtils.del(new File(pluginPath + "/" + fileName)); + } + } } } @@ -175,10 +193,16 @@ public class PluginServiceImpl implements IPluginService { //停止插件 pluginOperator.stop(pluginId); } + } else { + //已经停止,未获取到插件 + if (PluginInfo.STATE_RUNNING.equals(state)) { + throw new BizException(ErrCode.PLUGIN_INSTALL_FAILED, "插件启动失败"); + } } old.setState(state); pluginInfoData.save(old); + } } diff --git a/iot-module/iot-message-notify/pom.xml b/iot-module/iot-message-notify/pom.xml index f45f0d69..2edd5f55 100644 --- a/iot-module/iot-message-notify/pom.xml +++ b/iot-module/iot-message-notify/pom.xml @@ -5,7 +5,7 @@ iot-module cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 diff --git a/iot-module/iot-openapi/pom.xml b/iot-module/iot-openapi/pom.xml index 3aa4d05a..abc9694c 100644 --- a/iot-module/iot-openapi/pom.xml +++ b/iot-module/iot-openapi/pom.xml @@ -5,7 +5,7 @@ iot-module cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 diff --git a/iot-module/iot-plugin/iot-plugin-core/pom.xml b/iot-module/iot-plugin/iot-plugin-core/pom.xml index 40dcf529..5b11f3f9 100644 --- a/iot-module/iot-plugin/iot-plugin-core/pom.xml +++ b/iot-module/iot-plugin/iot-plugin-core/pom.xml @@ -5,7 +5,7 @@ iot-plugin cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 diff --git a/iot-module/iot-plugin/iot-plugin-core/src/main/java/cc/iotkit/plugin/core/LocalPluginScript.java b/iot-module/iot-plugin/iot-plugin-core/src/main/java/cc/iotkit/plugin/core/LocalPluginScript.java index 0a758281..da82eb3e 100644 --- a/iot-module/iot-plugin/iot-plugin-core/src/main/java/cc/iotkit/plugin/core/LocalPluginScript.java +++ b/iot-module/iot-plugin/iot-plugin-core/src/main/java/cc/iotkit/plugin/core/LocalPluginScript.java @@ -35,8 +35,7 @@ public class LocalPluginScript implements IPluginScript { return null; } - scriptEngine = ScriptEngineFactory.getScriptEngine("js"); - scriptEngine.setScript(script); + scriptEngine = ScriptEngineFactory.getJsEngine(script); return scriptEngine; } diff --git a/iot-module/iot-plugin/iot-plugin-main/pom.xml b/iot-module/iot-plugin/iot-plugin-main/pom.xml index 65b0c777..43489ebe 100644 --- a/iot-module/iot-plugin/iot-plugin-main/pom.xml +++ b/iot-module/iot-plugin/iot-plugin-main/pom.xml @@ -5,7 +5,7 @@ iot-plugin cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/PluginMainImpl.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/PluginMainImpl.java index 7c17c551..014aeb03 100644 --- a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/PluginMainImpl.java +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/PluginMainImpl.java @@ -7,7 +7,6 @@ import cc.iotkit.common.thing.DeviceService; import cc.iotkit.common.thing.ThingModelMessage; import cc.iotkit.common.thing.ThingService; import cc.iotkit.common.utils.JsonUtils; -import cc.iotkit.common.utils.StringUtils; import cc.iotkit.data.manager.IDeviceInfoData; import cc.iotkit.data.manager.IPluginInfoData; import cc.iotkit.data.manager.IProductData; @@ -21,8 +20,8 @@ import cc.iotkit.plugin.core.thing.actions.ActionResult; import cc.iotkit.plugin.core.thing.actions.down.PropertyGet; import cc.iotkit.plugin.core.thing.actions.down.PropertySet; import cc.iotkit.plugin.core.thing.actions.down.ServiceInvoke; +import cc.iotkit.plugin.main.script.PluginScriptServer; import cc.iotkit.script.IScriptEngine; -import cc.iotkit.script.ScriptEngineFactory; import com.gitee.starblues.integration.user.PluginUser; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -67,29 +66,16 @@ public class PluginMainImpl implements IPluginMain, DeviceService { @Autowired private MqProducer producer; - public IScriptEngine initScriptEngine(String pluginId) { - PluginInfo pluginInfo = pluginInfoData.findByPluginId(pluginId); - if (pluginInfo == null) { - return null; - } - String script = pluginInfo.getScript(); - if (StringUtils.isBlank(script)) { - return null; - } - - IScriptEngine scriptEngine = ScriptEngineFactory.getScriptEngine("js"); - scriptEngine.setScript(script); - return scriptEngine; - } + @Autowired + private PluginScriptServer pluginScriptServer; @Override public IScriptEngine getScriptEngine(String pluginId) { - return initScriptEngine(pluginId); + return pluginScriptServer.getScriptEngine(pluginId); } @Override public void reloadScript(String pluginId) { - initScriptEngine(pluginId); } @Override diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/Chan.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/Chan.java new file mode 100644 index 00000000..911fdf0e --- /dev/null +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/Chan.java @@ -0,0 +1,44 @@ +package cc.iotkit.plugin.main.script; + +import cc.iotkit.common.utils.JsonUtils; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.locks.LockSupport; + +@Slf4j +public class Chan { + + private static final long THREAD_WAIT_TIME = 1000_000L * 10_000; + + private volatile T data; + + private volatile Thread t; + + private Chan() { + + } + + public static Chan getInstance() { + return ChanSingleton.INSTANCE; + } + + public T get(Object blocker) { + this.t = Thread.currentThread(); + LockSupport.parkNanos(blocker, THREAD_WAIT_TIME); + this.t = null; + return data; + } + + public void put(T data) { + this.data = data; + if (t == null) { + return; + } + log.debug("put message data:{}", JsonUtils.toJsonString(data)); + LockSupport.unpark(t); + } + + private static class ChanSingleton { + private static final Chan INSTANCE = new Chan<>(); + } +} \ No newline at end of file diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataDecoder.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataDecoder.java new file mode 100644 index 00000000..e924092a --- /dev/null +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataDecoder.java @@ -0,0 +1,46 @@ +package cc.iotkit.plugin.main.script; + +import io.vertx.core.buffer.Buffer; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +/** + * 数据解码 + * + * @author sjg + */ +@Slf4j +public class DataDecoder { + + public static DataPackage decode(Buffer buffer) { + DataPackage data = new DataPackage(); + ReadField rf = new ReadField(0, buffer); + + data.setMid(rf.read()); + data.setPluginId(rf.read()); + data.setMethod(rf.read()); + data.setArgs(rf.read()); + data.setResult(rf.read()); + return data; + } + + + @Data + @AllArgsConstructor + private static class ReadField { + + private int idx = 0; + + private Buffer buffer; + + private String read() { + int len = buffer.getInt(idx); + idx += 4; + String s = new String(buffer.getBytes(idx, idx + len)); + idx += len; + return s; + } + + } +} diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataEncoder.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataEncoder.java new file mode 100644 index 00000000..5eef225c --- /dev/null +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataEncoder.java @@ -0,0 +1,42 @@ +package cc.iotkit.plugin.main.script; + +import io.vertx.core.buffer.Buffer; +import lombok.extern.slf4j.Slf4j; + +/** + * 数据编码 + * + * @author sjg + */ +@Slf4j +public class DataEncoder { + + public static Buffer encode(DataPackage data) { + + Buffer body = Buffer.buffer(); + + append(data.getMid(), body); + + append(data.getPluginId(), body); + + append(data.getMethod(), body); + + append(data.getArgs(), body); + + append(data.getResult(), body); + + Buffer buffer = Buffer.buffer(); + + byte[] bytes = body.getBytes(); + buffer.appendInt(bytes.length); + buffer.appendBytes(bytes); + + return buffer; + } + + private static void append(String s, Buffer buffer) { + byte[] bytes = s == null ? new byte[]{} : s.getBytes(); + buffer.appendInt(bytes.length); + buffer.appendBytes(bytes); + } +} diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataPackage.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataPackage.java new file mode 100644 index 00000000..c12923ed --- /dev/null +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataPackage.java @@ -0,0 +1,45 @@ +package cc.iotkit.plugin.main.script; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + + +/** + * 数据包 + * + * @author sjg + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class DataPackage { + + /** + * 消息id + */ + private String mid; + + /** + * 插件id + */ + private String pluginId; + + /** + * 调用方法 + */ + private String method; + + /** + * 方法参数 + */ + private String args; + + /** + * 执行结果 + */ + private String result; + +} diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataReader.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataReader.java new file mode 100644 index 00000000..88b76226 --- /dev/null +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/DataReader.java @@ -0,0 +1,45 @@ +package cc.iotkit.plugin.main.script; + + +import io.vertx.core.Handler; +import io.vertx.core.buffer.Buffer; +import io.vertx.core.parsetools.RecordParser; + +import java.util.function.Consumer; + +/** + * 数据包读取器 + * + * @author sjg + */ +public class DataReader { + + public static RecordParser getParser(Consumer receiveHandler) { + RecordParser parser = RecordParser.newFixed(4); + // 设置处理器 + parser.setOutput(new Handler<>() { + // 表示当前数据长度 + int size = -1; + + @Override + public void handle(Buffer buffer) { + //-1表示当前还没有长度信息,需要从收到的数据中取出长度 + if (-1 == size) { + //取出长度 + size = buffer.getInt(0); + //动态修改长度 + parser.fixedSizeMode(size); + } else { + //如果size != -1, 说明已经接受到长度信息了,接下来的数据就是protobuf可识别的字节数组 + byte[] buf = buffer.getBytes(); + receiveHandler.accept(Buffer.buffer(buf)); + //处理完后要将长度改回 + parser.fixedSizeMode(4); + //重置size变量 + size = -1; + } + } + }); + return parser; + } +} diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/PluginScriptEngine.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/PluginScriptEngine.java new file mode 100644 index 00000000..56024c67 --- /dev/null +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/PluginScriptEngine.java @@ -0,0 +1,77 @@ +package cc.iotkit.plugin.main.script; + +import cc.iotkit.common.utils.JsonUtils; +import cc.iotkit.script.IScriptEngine; +import cc.iotkit.script.JavaScriptEngine; +import cn.hutool.core.util.IdUtil; +import com.fasterxml.jackson.core.type.TypeReference; +import io.vertx.core.Future; +import io.vertx.core.Vertx; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; + +/** + * 用于插件的脚本引擎,为了规避graalvm js加载问题,不直接调用使用tcp通讯交互 + * + * @author sjg + */ +@Slf4j +@Data +public class PluginScriptEngine implements IScriptEngine { + + private String pluginId; + + private ScriptClientVerticle scriptClientVerticle = new ScriptClientVerticle(); + + public PluginScriptEngine(String pluginId) { + this.pluginId = pluginId; + Vertx vertx = Vertx.vertx(); + Future future = vertx.deployVerticle(scriptClientVerticle); + future.onSuccess((s -> { + log.info("tcp client started success"); + })); + future.onFailure((e) -> { + log.error("tcp client startup failed", e); + }); + } + + @Override + public void setScript(String s) { + + } + + @Override + public void putScriptEnv(String s, Object o) { + + } + + @Override + public void invokeMethod(String s, Object... args) { + throw new UnsupportedOperationException(); + } + + @Override + public T invokeMethod(TypeReference type, String method, Object... args) { + List argJson = new ArrayList<>(); + for (Object arg : args) { + argJson.add(JsonUtils.toJsonString(arg)); + } + + String json = scriptClientVerticle.send(DataPackage.builder() + .pluginId(pluginId) + .mid(IdUtil.getSnowflakeNextIdStr()) + .method(method) + .args(JsonUtils.toJsonString(argJson)) + .build()); + return json == null ? null : JsonUtils.parseObject(json, type); + } + + @Override + public String invokeMethod(String s, String s1) { + throw new UnsupportedOperationException(); + } + +} diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/PluginScriptServer.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/PluginScriptServer.java new file mode 100644 index 00000000..5fd13d37 --- /dev/null +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/PluginScriptServer.java @@ -0,0 +1,48 @@ +package cc.iotkit.plugin.main.script; + +import cc.iotkit.data.manager.IPluginInfoData; +import cc.iotkit.script.IScriptEngine; +import io.vertx.core.Future; +import io.vertx.core.Vertx; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.util.HashMap; +import java.util.Map; + +/** + * 用于插件的脚本引擎,为了规避graalvm js加载问题,不直接调用使用tcp通讯交互 + * + * @author sjg + */ +@Slf4j +@Service +public class PluginScriptServer { + @Autowired + private IPluginInfoData pluginInfoData; + + @Autowired + private ScriptVerticle scriptVerticle; + + private static final Map PLUGIN_SCRIPT_ENGINES = new HashMap<>(); + + @PostConstruct + public void init() { + Vertx vertx = Vertx.vertx(); + Future future = vertx.deployVerticle(scriptVerticle); + future.onSuccess((s -> { + log.info("plugin script server started success"); + })); + future.onFailure(Throwable::printStackTrace); + } + + public IScriptEngine getScriptEngine(String pluginId) { + if (!PLUGIN_SCRIPT_ENGINES.containsKey(pluginId)) { + PLUGIN_SCRIPT_ENGINES.put(pluginId,new PluginScriptEngine(pluginId)); + } + return PLUGIN_SCRIPT_ENGINES.get(pluginId); + } + +} diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/ScriptClientVerticle.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/ScriptClientVerticle.java new file mode 100644 index 00000000..6f654baf --- /dev/null +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/ScriptClientVerticle.java @@ -0,0 +1,83 @@ +package cc.iotkit.plugin.main.script; + +import cn.hutool.core.util.HexUtil; +import io.vertx.core.AbstractVerticle; +import io.vertx.core.buffer.Buffer; +import io.vertx.core.net.NetClient; +import io.vertx.core.net.NetClientOptions; +import io.vertx.core.net.NetSocket; +import io.vertx.core.parsetools.RecordParser; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author sjg + */ +@Slf4j +public class ScriptClientVerticle extends AbstractVerticle { + + private NetClient netClient; + + private NetSocket socket; + + private AtomicInteger atMid = new AtomicInteger(0); + + @Override + public void start() { + initClient(); + } + + @Override + public void stop() { + if (null != netClient) { + netClient.close(); + } + } + + private void initClient() { + NetClientOptions options = new NetClientOptions(); + options.setReconnectAttempts(Integer.MAX_VALUE); + options.setReconnectInterval(20000L); + netClient = vertx.createNetClient(options); + RecordParser parser = DataReader.getParser(this::handle); + + netClient.connect(new ScriptServerConfig().getPort(), "127.0.0.1", result -> { + if (result.succeeded()) { + log.debug("connect tcp success"); + socket = result.result(); + socket.handler(parser); + } else { + log.error("connect tcp error", result.cause()); + } + }); + } + + private short getMid() { + atMid.compareAndSet(254, 0); + return (short) atMid.getAndIncrement(); + } + + public String send(DataPackage data) { + Buffer buffer = DataEncoder.encode(data); + log.info("send data:{}", HexUtil.encodeHexStr(buffer.getBytes())); + socket.write(buffer); + Chan chan = Chan.getInstance(); + DataPackage receiver = chan.get(data.getMid()); + if (receiver == null) { + return null; + } + if (receiver.getMid().equals(data.getMid())) { + return receiver.getResult(); + } + return null; + } + + public void handle(Buffer buffer) { + log.info("receive server data:{}", buffer.toString()); + DataPackage data = DataDecoder.decode(buffer); + Chan chan = Chan.getInstance(); + chan.put(data); + } + +} \ No newline at end of file diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/ScriptServerConfig.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/ScriptServerConfig.java new file mode 100644 index 00000000..cbab0987 --- /dev/null +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/ScriptServerConfig.java @@ -0,0 +1,30 @@ +package cc.iotkit.plugin.main.script; + +import cn.hutool.core.util.RandomUtil; +import io.vertx.core.net.SocketAddress; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; + +/** + * @author sjg + */ +public class ScriptServerConfig { + private static int _port; + + static { + _port = RandomUtil.randomInt(11024, 12024); + } + + @Getter + private String host = "localhost"; + + @Getter + private int port = _port; + + public SocketAddress createSocketAddress() { + if (StringUtils.isEmpty(host)) { + host = "localhost"; + } + return SocketAddress.inetSocketAddress(port, host); + } +} diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/ScriptVerticle.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/ScriptVerticle.java new file mode 100644 index 00000000..668a810d --- /dev/null +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/ScriptVerticle.java @@ -0,0 +1,142 @@ +package cc.iotkit.plugin.main.script; + +import cc.iotkit.common.utils.StringUtils; +import cc.iotkit.data.manager.IPluginInfoData; +import cc.iotkit.model.plugin.PluginInfo; +import cc.iotkit.script.IScriptEngine; +import cc.iotkit.script.ScriptEngineFactory; +import cn.hutool.core.util.IdUtil; +import io.vertx.core.AbstractVerticle; +import io.vertx.core.buffer.Buffer; +import io.vertx.core.net.NetServer; +import io.vertx.core.net.NetServerOptions; +import io.vertx.core.net.NetSocket; +import io.vertx.core.parsetools.RecordParser; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +@Component +public class ScriptVerticle extends AbstractVerticle { + + private final Map clientMap = new ConcurrentHashMap<>(); + + private static final Map PLUGIN_SCRIPT_ENGINES = new HashMap<>(); + + @Setter + private long keepAliveTimeout = Duration.ofSeconds(30).toMillis(); + + @Autowired + private IPluginInfoData pluginInfoData; + + public IScriptEngine initScriptEngine(String pluginId) { + PluginInfo pluginInfo = pluginInfoData.findByPluginId(pluginId); + if (pluginInfo == null) { + return null; + } + String script = pluginInfo.getScript(); + if (StringUtils.isBlank(script)) { + return null; + } + + IScriptEngine jsEngine = ScriptEngineFactory.getJsEngine(script); + PLUGIN_SCRIPT_ENGINES.put(pluginId, ScriptEngineFactory.getJsEngine(script)); + return jsEngine; + } + + public IScriptEngine getScriptEngine(String pluginId) { + if (!PLUGIN_SCRIPT_ENGINES.containsKey(pluginId)) { + return initScriptEngine(pluginId); + } + return PLUGIN_SCRIPT_ENGINES.get(pluginId); + } + + @Override + public void start() { + initTcpServer(); + log.info("init tcp server failed"); + } + + @Override + public void stop() { + log.info("tcp server stopped"); + } + + /** + * 初始TCP服务 + */ + private void initTcpServer() { + ScriptServerConfig config = new ScriptServerConfig(); + NetServer netServer = vertx.createNetServer( + new NetServerOptions().setHost("127.0.0.1") + .setPort(config.getPort())); + netServer.connectHandler(this::acceptTcpConnection); + netServer.listen(config.createSocketAddress(), result -> { + if (result.succeeded()) { + log.info("tcp server startup on {}", result.result().actualPort()); + } else { + result.cause().printStackTrace(); + } + }); + } + + /** + * TCP连接处理逻辑 + * + * @param socket socket + */ + protected void acceptTcpConnection(NetSocket socket) { + // 客户端连接处理 + String clientId = IdUtil.simpleUUID() + "_" + socket.remoteAddress(); + VertxTcpClient client = new VertxTcpClient(clientId); + client.setKeepAliveTimeoutMs(keepAliveTimeout); + try { + // TCP异常和关闭处理 + socket.exceptionHandler(Throwable::printStackTrace).closeHandler(nil -> { + log.debug("tcp server client [{}] closed", socket.remoteAddress()); + client.shutdown(); + }); + // 这个地方是在TCP服务初始化的时候设置的 parserSupplier + client.setKeepAliveTimeoutMs(keepAliveTimeout); + client.setSocket(socket); + RecordParser parser = DataReader.getParser(buffer -> { + try { + DataPackage data = DataDecoder.decode(buffer); + String pluginId = data.getPluginId(); + clientMap.put(pluginId, client); + IScriptEngine scriptEngine = getScriptEngine(pluginId); + if(scriptEngine==null){ + data.setResult(""); + }else { + //调用执行脚本方法返回结果 + String result = scriptEngine.invokeMethod(data.getMethod(), data.getArgs()); + data.setResult(result); + } + sendMsg(pluginId, DataEncoder.encode(data)); + } catch (Exception e) { + log.error("decode error", e); + } + }); + client.setParser(parser); + log.debug("accept tcp client [{}] connection", socket.remoteAddress()); + } catch (Exception e) { + log.error("acceptTcpConnection error", e); + client.shutdown(); + } + } + + public void sendMsg(String pluginId, Buffer msg) { + VertxTcpClient tcpClient = clientMap.get(pluginId); + if (tcpClient != null) { + tcpClient.sendMessage(msg); + } + } + +} diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/VertxTcpClient.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/VertxTcpClient.java new file mode 100644 index 00000000..6edf637b --- /dev/null +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/script/VertxTcpClient.java @@ -0,0 +1,94 @@ +package cc.iotkit.plugin.main.script; + +import io.vertx.core.buffer.Buffer; +import io.vertx.core.net.NetSocket; +import io.vertx.core.parsetools.RecordParser; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.binary.Hex; + +import java.time.Duration; + +/** + * @author sjg + */ +@Slf4j +public class VertxTcpClient { + @Getter + private String id; + public NetSocket socket; + @Setter + private long keepAliveTimeoutMs = Duration.ofSeconds(30).toMillis(); + private volatile long lastKeepAliveTime = System.currentTimeMillis(); + + @Setter + private RecordParser parser; + + public VertxTcpClient(String id) { + this.id = id; + } + + public void keepAlive() { + lastKeepAliveTime = System.currentTimeMillis(); + } + + public boolean isOnline() { + return System.currentTimeMillis() - lastKeepAliveTime < keepAliveTimeoutMs; + } + + public void setSocket(NetSocket socket) { + synchronized (this) { + if (this.socket != null && this.socket != socket) { + this.socket.close(); + } + + this.socket = socket + .closeHandler(v -> shutdown()) + .handler(buffer -> { + if (log.isDebugEnabled()) { + log.debug("handle tcp client[{}] payload:[{}]", + socket.remoteAddress(), + Hex.encodeHexString(buffer.getBytes())); + } + keepAlive(); + parser.handle(buffer); + if (this.socket != socket) { + log.warn("tcp client [{}] memory leak ", socket.remoteAddress()); + socket.close(); + } + }); + } + } + + public void shutdown() { + log.debug("tcp client [{}] disconnect", getId()); + synchronized (this) { + if (null != socket) { + execute(socket::close); + this.socket = null; + } + } + } + + public void sendMessage(Buffer buffer) { + log.info("wirte data:{}", buffer.toString()); + socket.write(buffer, r -> { + keepAlive(); + if (r.succeeded()) { + log.info("client msg send success"); + } else { + log.error("client msg send failed", r.cause()); + } + }); + } + + private void execute(Runnable runnable) { + try { + runnable.run(); + } catch (Exception e) { + log.warn("close tcp client error", e); + } + } + +} diff --git a/iot-module/iot-plugin/pom.xml b/iot-module/iot-plugin/pom.xml index f82d69cd..33210fa0 100644 --- a/iot-module/iot-plugin/pom.xml +++ b/iot-module/iot-plugin/pom.xml @@ -5,7 +5,7 @@ iot-module cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 @@ -15,6 +15,7 @@ iot-plugin-core iot-plugin-main + spring-brick-maven-packager \ No newline at end of file diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/pom.xml b/iot-module/iot-plugin/spring-brick-maven-packager/pom.xml new file mode 100644 index 00000000..c8fe8488 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/pom.xml @@ -0,0 +1,101 @@ + + + 4.0.0 + + + iot-plugin + cc.iotkit + 0.5.1-SNAPSHOT + + + com.gitee.starblues + 3.1.3 + spring-brick-maven-packager + jar + + 用于打包主程序/插件模块 + + + 8 + 3.0.0 + ${java.version} + ${java.version} + UTF-8 + UTF-8 + UTF-8 + + 3.8.4 + 3.6.2 + 3.2.0 + 1.21 + 2.11.0 + 1.18.20 + 3.8.1 + + 3.6.0 + + + + + + com.gitee.starblues + spring-brick-common + ${spring-brick.version} + + + + org.apache.maven + maven-plugin-api + ${maven-plugin-api.version} + + + + org.apache.maven.plugin-tools + maven-plugin-annotations + ${maven-plugin-annotations.version} + + + + org.apache.maven.shared + maven-common-artifact-filters + ${maven-common-artifact-filters.version} + + + + org.apache.commons + commons-compress + ${commons-compress.version} + + + + commons-io + commons-io + ${commons-io.version} + + + + org.projectlombok + lombok + + + + junit + junit + ${junit.version} + test + + + + + + + + org.apache.maven.plugins + maven-plugin-plugin + ${maven-plugin-plugin.version} + + + + \ No newline at end of file diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractDependencyFilterMojo.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractDependencyFilterMojo.java new file mode 100644 index 00000000..ff061cfd --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractDependencyFilterMojo.java @@ -0,0 +1,108 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack; + +import com.gitee.starblues.plugin.pack.filter.Exclude; +import com.gitee.starblues.plugin.pack.filter.ExcludeFilter; +import com.gitee.starblues.plugin.pack.filter.Include; +import com.gitee.starblues.plugin.pack.filter.IncludeFilter; +import com.gitee.starblues.plugin.pack.utils.CommonUtils; +import com.gitee.starblues.utils.ObjectUtils; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; +import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; +import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +/** + * 抽象可过滤依赖的 mojo + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public abstract class AbstractDependencyFilterMojo extends AbstractMojo { + + + @Parameter(property = "spring-brick-packager.includes") + private List includes; + + @Parameter(property = "spring-brick-packager.excludes") + private List excludes; + + + protected final Set filterDependencies(Set dependencies, FilterArtifacts filters) + throws MojoExecutionException { + try { + Set filtered = new LinkedHashSet<>(dependencies); + filtered.retainAll(filters.filter(dependencies)); + return filtered; + } + catch (ArtifactFilterException ex) { + throw new MojoExecutionException(ex.getMessage(), ex); + } + } + + protected final FilterArtifacts getFilters(ArtifactsFilter... additionalFilters) { + FilterArtifacts filters = new FilterArtifacts(); + for (ArtifactsFilter additionalFilter : additionalFilters) { + filters.addFilter(additionalFilter); + } + if (!ObjectUtils.isEmpty(includes)) { + filters.addFilter(new IncludeFilter(this.includes)); + } + if(ObjectUtils.isEmpty(excludes)){ + excludes = new ArrayList<>(); + } + // 添加主框架排除 + addPluginFrameworkExclude(); + // 添加spring web 环境排除 + addSpringWebEnvExclude(); + filters.addFilter(new ExcludeFilter(this.excludes)); + return filters; + } + + private void addPluginFrameworkExclude(){ + excludes.add(CommonUtils.getPluginFrameworkExclude()); + } + + private void addSpringWebEnvExclude(){ + excludes.add(Exclude.get("org.springframework.boot", "spring-boot-starter-web")); + excludes.add(Exclude.get("org.springframework.boot", "spring-boot-starter-tomcat")); + excludes.add(Exclude.get("org.springframework.boot", "spring-boot-starter-json")); + excludes.add(Exclude.get("org.springframework", "spring-webmvc")); + excludes.add(Exclude.get("org.springframework", "spring-web")); + + // jackson + excludes.add(Exclude.get("com.fasterxml.jackson.core", "jackson-core")); + excludes.add(Exclude.get("com.fasterxml.jackson.core", "jackson-databind")); + excludes.add(Exclude.get("com.fasterxml.jackson.core", "jackson-annotations")); + excludes.add(Exclude.get("com.fasterxml.jackson.module", "jackson-module-parameter-names")); + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractPackagerMojo.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractPackagerMojo.java new file mode 100644 index 00000000..629649d5 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/AbstractPackagerMojo.java @@ -0,0 +1,93 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; + +import java.io.File; +import java.util.Set; + +/** + * 抽象的重新打包 mojo + * + * @author starBlues + * @since 3.0.0 + * @version 3.1.1 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo{ + + @Parameter(defaultValue = "${project}", readonly = true, required = true) + private MavenProject project; + + @Parameter(defaultValue = "${project.build.directory}", required = true) + private File outputDirectory; + + @Parameter(property = "spring-brick-packager.mode", defaultValue = "dev", required = true) + private String mode; + + @Parameter(property = "spring-brick-packager.skip", defaultValue = "false") + private boolean skip; + + @Parameter + private String classifier; + + @Parameter(property = "spring-brick-packager.pluginInfo") + private PluginInfo pluginInfo; + + @Parameter(property = "spring-brick-packager.loadMainResourcePattern", required = false) + private LoadMainResourcePattern loadMainResourcePattern; + + @Parameter(property = "spring-brick-packager.includeSystemScope", defaultValue = "true", required = false) + private Boolean includeSystemScope; + + @Override + public final void execute() throws MojoExecutionException, MojoFailureException { + if(Constant.isPom(this.getProject().getPackaging())){ + getLog().debug("repackage goal could not be applied to pom project."); + return; + } + if (this.skip) { + getLog().debug("skipping plugin package."); + return; + } + pack(); + } + + /** + * 打包 + * @throws MojoExecutionException MojoExecutionException + * @throws MojoFailureException MojoFailureException + */ + protected abstract void pack() throws MojoExecutionException, MojoFailureException; + + public final Set getFilterDependencies() throws MojoExecutionException { + Set artifacts = project.getArtifacts(); + return filterDependencies(artifacts, getFilters()); + } + + public final Set getSourceDependencies() throws MojoExecutionException { + return project.getArtifacts(); + } +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/BasicRepackager.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/BasicRepackager.java new file mode 100644 index 00000000..bfe59b6f --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/BasicRepackager.java @@ -0,0 +1,380 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack; + +import com.gitee.starblues.common.*; +import com.gitee.starblues.plugin.pack.utils.CommonUtils; +import com.gitee.starblues.utils.FilesUtils; +import com.gitee.starblues.utils.ObjectUtils; +import lombok.Getter; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.*; +import java.util.jar.Attributes; +import java.util.jar.JarFile; +import java.util.jar.Manifest; + +import static com.gitee.starblues.common.PackageStructure.*; +import static com.gitee.starblues.common.PluginDescriptorKey.*; + +/** + * 基础打包 + * + * @author starBlues + * @since 3.0.0 + * @version 3.1.1 + */ +public class BasicRepackager implements Repackager{ + + @Getter + private String rootDir; + private String relativeManifestPath; + private String relativePluginMetaPath; + private String relativeResourcesDefinePath; + + protected File resourcesDefineFile; + + protected final RepackageMojo repackageMojo; + protected JarFile sourceJarFile; + + public BasicRepackager(RepackageMojo repackageMojo) { + this.repackageMojo = repackageMojo; + } + + @Override + public void repackage() throws MojoExecutionException, MojoFailureException { + sourceJarFile = CommonUtils.getSourceJarFile(repackageMojo.getProject()); + checkPluginInfo(); + rootDir = createRootDir(); + relativeManifestPath = getRelativeManifestPath(); + relativePluginMetaPath = getRelativePluginMetaPath(); + relativeResourcesDefinePath = getRelativeResourcesDefinePath(); + try { + Manifest manifest = getManifest(); + writeManifest(manifest); + } catch (Exception e) { + repackageMojo.getLog().error(e.getMessage(), e); + throw new MojoFailureException(e); + } finally { + IOUtils.closeQuietly(sourceJarFile); + } + } + + private void checkPluginInfo() throws MojoExecutionException { + PluginInfo pluginInfo = repackageMojo.getPluginInfo(); + if(pluginInfo == null){ + throw new MojoExecutionException("configuration.pluginInfo config cannot be empty"); + } + if(ObjectUtils.isEmpty(pluginInfo.getId())){ + throw new MojoExecutionException("configuration.pluginInfo.id config cannot be empty"); + } else { + String id = pluginInfo.getId(); + String illegal = PackageStructure.getIllegal(id); + if(illegal != null){ + throw new MojoExecutionException("configuration.pluginInfo.id config can't contain: " + illegal); + } + } + if(ObjectUtils.isEmpty(pluginInfo.getBootstrapClass())){ + throw new MojoExecutionException("configuration.pluginInfo.bootstrapClass config cannot be empty"); + } + if(ObjectUtils.isEmpty(pluginInfo.getVersion())){ + throw new MojoExecutionException("configuration.pluginInfo.version config cannot be empty"); + } else { + String version = pluginInfo.getVersion(); + String illegal = PackageStructure.getIllegal(version); + if(illegal != null){ + throw new MojoExecutionException("configuration.pluginInfo.version config can't contain: " + illegal); + } + } + } + + protected String getRelativeManifestPath(){ + return MANIFEST; + } + + protected String getRelativeResourcesDefinePath(){ + return RESOURCES_DEFINE_NAME; + } + + protected String getRelativePluginMetaPath(){ + return PLUGIN_META_NAME; + } + + protected String createRootDir() throws MojoFailureException { + String rootDirPath = getBasicRootDir(); + File rootDir = new File(rootDirPath); + CommonUtils.deleteFile(rootDir); + if(rootDir.mkdir()){ + return rootDirPath; + } + throw new MojoFailureException("Failed to create the plugin root directory. " + rootDirPath); + } + + protected String getBasicRootDir(){ + File outputDirectory = repackageMojo.getOutputDirectory(); + return FilesUtils.joiningFilePath(outputDirectory.getPath(), PackageStructure.META_INF_NAME); + } + + protected void writeManifest(Manifest manifest) throws Exception { + String manifestPath = FilesUtils.joiningFilePath(rootDir, resolvePath(this.relativeManifestPath)); + File file = new File(manifestPath); + FileOutputStream outputStream = null; + try { + FileUtils.forceMkdirParent(file); + if(file.createNewFile()){ + outputStream = new FileOutputStream(file, false); + manifest.write(outputStream); + } + } finally { + if(outputStream != null){ + try { + outputStream.close(); + } catch (IOException e) { + repackageMojo.getLog().error(e.getMessage(), e); + } + } + } + } + + protected Manifest getManifest() throws Exception{ + Manifest manifest = null; + if(sourceJarFile != null){ + manifest = sourceJarFile.getManifest(); + } else { + manifest = new Manifest(); + } + Attributes attributes = manifest.getMainAttributes(); + attributes.putValue(ManifestKey.MANIFEST_VERSION, ManifestKey.MANIFEST_VERSION_1_0); + attributes.putValue(ManifestKey.BUILD_TIME, CommonUtils.getDateTime()); + attributes.putValue(ManifestKey.PLUGIN_META_PATH, getPluginMetaInfoPath()); + attributes.putValue(ManifestKey.PLUGIN_PACKAGE_TYPE, PackageType.PLUGIN_PACKAGE_TYPE_DEV); + // 增加jar包title和version属性 + MavenProject mavenProject = this.repackageMojo.getProject(); + attributes.putValue(ManifestKey.IMPLEMENTATION_TITLE, mavenProject.getArtifactId()); + attributes.putValue(ManifestKey.IMPLEMENTATION_VERSION, mavenProject.getVersion()); + return manifest; + } + + /** + * 得到插件信息存储文件路径 + * @return 插件信息存储文件路径 + * @throws Exception Exception + */ + protected String getPluginMetaInfoPath() throws Exception { + Properties pluginMetaInfo = createPluginMetaInfo(); + return writePluginMetaInfo(pluginMetaInfo); + } + + /** + * 创建插件信息 + * @return Properties + * @throws Exception Exception + */ + protected Properties createPluginMetaInfo() throws Exception { + Properties properties = new Properties(); + PluginInfo pluginInfo = repackageMojo.getPluginInfo(); + properties.put(PLUGIN_ID, pluginInfo.getId()); + properties.put(PLUGIN_BOOTSTRAP_CLASS, pluginInfo.getBootstrapClass()); + properties.put(PLUGIN_VERSION, pluginInfo.getVersion()); + properties.put(PLUGIN_PATH, getPluginPath()); + + String resourcesDefineFilePath = writeResourcesDefineFile(getResourcesDefineContent()); + if(!ObjectUtils.isEmpty(resourcesDefineFilePath)){ + properties.put(PLUGIN_RESOURCES_CONFIG, resourcesDefineFilePath); + } + String configFileName = pluginInfo.getConfigFileName(); + if(!ObjectUtils.isEmpty(configFileName)){ + properties.put(PLUGIN_CONFIG_FILE_NAME, configFileName); + } + String configFileLocation = pluginInfo.getConfigFileLocation(); + if(!ObjectUtils.isEmpty(configFileLocation)){ + properties.put(PLUGIN_CONFIG_FILE_LOCATION, configFileLocation); + } + String args = pluginInfo.getArgs(); + if(!ObjectUtils.isEmpty(args)){ + properties.put(PLUGIN_ARGS, args); + } + String provider = pluginInfo.getProvider(); + if(!ObjectUtils.isEmpty(provider)){ + properties.put(PLUGIN_PROVIDER, provider); + } + String requires = pluginInfo.getRequires(); + if(!ObjectUtils.isEmpty(requires)){ + properties.put(PLUGIN_REQUIRES, requires); + } + String dependencyPlugins = getDependencyPlugin(pluginInfo); + if(!ObjectUtils.isEmpty(dependencyPlugins)){ + properties.put(PLUGIN_DEPENDENCIES, dependencyPlugins); + } + String description = pluginInfo.getDescription(); + if(!ObjectUtils.isEmpty(description)){ + properties.put(PLUGIN_DESCRIPTION, description); + } + String license = pluginInfo.getLicense(); + if(!ObjectUtils.isEmpty(license)){ + properties.put(PLUGIN_LICENSE, license); + } + return properties; + } + + protected String getDependencyPlugin(PluginInfo pluginInfo){ + List dependencyPlugins = pluginInfo.getDependencyPlugins(); + return AbstractDependencyPlugin.toStr(dependencyPlugins); + } + + /** + * 写入插件信息 + * @param properties properties + * @return String + * @throws IOException IOException + */ + protected String writePluginMetaInfo(Properties properties) throws Exception { + File pluginMetaFile = createPluginMetaFile(); + try (OutputStreamWriter writer = new OutputStreamWriter( + Files.newOutputStream(pluginMetaFile.toPath()), StandardCharsets.UTF_8)){ + properties.store(writer, Constant.PLUGIN_METE_COMMENTS); + return pluginMetaFile.getPath(); + } + } + + /** + * 创建插件信息存储文件 + * @return File + * @throws IOException 创建文件异常 + */ + protected File createPluginMetaFile() throws IOException { + String path = FilesUtils.joiningFilePath(rootDir, resolvePath(relativePluginMetaPath)); + return FilesUtils.createFile(path); + } + + /** + * 获取插件路径 + * @return 插件路径 + */ + protected String getPluginPath(){ + return repackageMojo.getProject().getBuild().getOutputDirectory(); + } + + protected String writeResourcesDefineFile(String resourcesDefineContent) throws Exception{ + resourcesDefineFile = createResourcesDefineFile(); + FileUtils.write(resourcesDefineFile, resourcesDefineContent, CHARSET_NAME, true); + return resourcesDefineFile.getPath(); + } + + protected File createResourcesDefineFile() throws IOException { + String path = FilesUtils.joiningFilePath(rootDir, resolvePath(relativeResourcesDefinePath)); + return FilesUtils.createFile(path); + } + + protected String getResourcesDefineContent() throws Exception { + String dependenciesIndex = getDependenciesIndex(); + String loadMainResources = getLoadMainResources(); + boolean indexIsEmpty = ObjectUtils.isEmpty(dependenciesIndex); + boolean resourceIsEmpty = ObjectUtils.isEmpty(loadMainResources); + + if(!indexIsEmpty && !resourceIsEmpty){ + return dependenciesIndex + "\n" + loadMainResources; + } else if(!indexIsEmpty){ + return dependenciesIndex; + } else if(!resourceIsEmpty){ + return loadMainResources; + } else { + return ""; + } + } + + protected String getDependenciesIndex() throws Exception { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(RESOURCES_DEFINE_DEPENDENCIES).append("\n"); + Set libIndex = getDependenciesIndexSet(); + for (String index : libIndex) { + stringBuilder.append(index).append("\n"); + } + return stringBuilder.toString(); + } + + protected String getLoadMainResources(){ + LoadMainResourcePattern loadMainResourcePattern = repackageMojo.getLoadMainResourcePattern(); + if(loadMainResourcePattern == null){ + return null; + } + String[] includes = loadMainResourcePattern.getIncludes(); + String[] excludes = loadMainResourcePattern.getExcludes(); + StringBuilder stringBuilder = new StringBuilder(); + addLoadMainResources(stringBuilder, RESOURCES_DEFINE_LOAD_MAIN_INCLUDES, includes); + addLoadMainResources(stringBuilder, RESOURCES_DEFINE_LOAD_MAIN_EXCLUDES, excludes); + return stringBuilder.toString(); + } + + protected Set getDependenciesIndexSet() throws Exception { + Set dependencies = repackageMojo.getFilterDependencies(); + Set libPaths = new LinkedHashSet<>(dependencies.size()); + for (Artifact artifact : dependencies) { + if(filterArtifact(artifact)){ + continue; + } + libPaths.add(getLibIndex(artifact)); + } + return libPaths; + } + + protected String getLibIndex(Artifact artifact){ + return artifact.getFile().getPath() + repackageMojo.resolveLoadToMain(artifact); + } + + private void addLoadMainResources(StringBuilder stringBuilder, String header, String[] patterns){ + if(ObjectUtils.isEmpty(patterns)){ + return; + } + Set patternSet = new LinkedHashSet<>(Arrays.asList(patterns)); + stringBuilder.append(header).append("\n"); + for (String patternStr : patternSet) { + if(ObjectUtils.isEmpty(patternStr)){ + continue; + } + stringBuilder.append(resolvePattern(patternStr)).append("\n"); + } + } + + protected String resolvePattern(String patternStr){ + return patternStr.replace(".", "/"); + } + + /** + * 过滤Artifact + * @param artifact Artifact + * @return 返回true表示被过滤掉 + */ + protected boolean filterArtifact(Artifact artifact){ + return Constant.filterMainTypeArtifact(artifact) || + Constant.filterArtifact(artifact, repackageMojo.getIncludeSystemScope()); + } + + + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Constant.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Constant.java new file mode 100644 index 00000000..0225ae53 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Constant.java @@ -0,0 +1,85 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack; + +import org.apache.maven.artifact.Artifact; + +/** + * 静态类 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public class Constant { + + public static final String PACKAGING_POM = "pom"; + public static final String SCOPE_PROVIDED = "provided"; + public static final String SCOPE_COMPILE = "compile"; + public static final String SCOPE_SYSTEM = "system"; + public static final String SCOPE_TEST = "test"; + + public static final String MAVEN_POM_TYPE = "pom"; + + public static final String MAVEN_MAIN_TYPE = "main"; + + public static final String MODE_MAIN = "main"; + public static final String MODE_DEV = "dev"; + public static final String MODE_PROD = "prod"; + + public static final String PLUGIN_METE_COMMENTS = "plugin meta configuration"; + + /** + * 开发模式方法名称 + */ + public static final String DEVELOPMENT_MODE_METHOD_NAME = "developmentMode"; + + + public static boolean isPom(String packageType){ + return PACKAGING_POM.equalsIgnoreCase(packageType); + } + + public static boolean filterArtifact(Artifact artifact, Boolean includeSystemScope){ + boolean scopeFilter = Constant.scopeFilter(artifact.getScope()); + if(scopeFilter){ + return true; + } + if(Constant.isSystemScope(artifact.getScope())){ + return includeSystemScope == null || !includeSystemScope; + } + return Constant.filterPomTypeArtifact(artifact); + } + + public static boolean filterMainTypeArtifact(Artifact artifact){ + // 配置了为main的依赖, 则对其过滤 + return MAVEN_MAIN_TYPE.equalsIgnoreCase(artifact.getType()); + } + + public static boolean filterPomTypeArtifact(Artifact artifact){ + return MAVEN_POM_TYPE.equalsIgnoreCase(artifact.getType()); + } + + public static boolean scopeFilter(String scope){ + return SCOPE_PROVIDED.equalsIgnoreCase(scope) + || SCOPE_TEST.equalsIgnoreCase(scope); + } + + public static boolean isSystemScope(String scope){ + return SCOPE_SYSTEM.equalsIgnoreCase(scope); + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Dependency.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Dependency.java new file mode 100644 index 00000000..7e2b1e01 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Dependency.java @@ -0,0 +1,38 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack; + +import lombok.Data; +import org.apache.maven.plugins.annotations.Parameter; + +/** + * 依赖Bean + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +@Data +public class Dependency { + + @Parameter(required = true) + private String groupId; + + @Parameter(required = true) + private String artifactId; + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/DependencyPlugin.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/DependencyPlugin.java new file mode 100644 index 00000000..44dfcdf2 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/DependencyPlugin.java @@ -0,0 +1,73 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack; + +import com.gitee.starblues.common.AbstractDependencyPlugin; +import org.apache.maven.plugins.annotations.Parameter; + +/** + * 依赖的插件 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public class DependencyPlugin extends AbstractDependencyPlugin { + + @Parameter(required = true) + private String id; + + @Parameter(required = true) + private String version; + + @Parameter(required = false, defaultValue = "true") + private Boolean optional = false; + + @Override + public String getId() { + return id; + } + + @Override + public String getVersion() { + return version; + } + + @Override + public Boolean getOptional() { + if(optional == null){ + return false; + } + return optional; + } + + @Override + public void setId(String id) { + this.id = id; + } + + @Override + public void setVersion(String version) { + this.version = version; + } + + @Override + public void setOptional(Boolean optional) { + this.optional = optional; + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/LoadMainResourcePattern.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/LoadMainResourcePattern.java new file mode 100644 index 00000000..a9a3b7ab --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/LoadMainResourcePattern.java @@ -0,0 +1,38 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack; + +import lombok.Data; +import org.apache.maven.plugins.annotations.Parameter; + +/** + * 从主程序加载资源配置 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +@Data +public class LoadMainResourcePattern { + + @Parameter(name = "includes") + private String[] includes; + + @Parameter(name = "excludes") + private String[] excludes; + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/LoadToMain.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/LoadToMain.java new file mode 100644 index 00000000..9892b980 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/LoadToMain.java @@ -0,0 +1,35 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack; + +import lombok.Data; + +import java.util.List; + +/** + * 定义依赖加载到主程序中 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +@Data +public class LoadToMain { + + private List dependencies; + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/PluginInfo.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/PluginInfo.java new file mode 100644 index 00000000..7265f0b1 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/PluginInfo.java @@ -0,0 +1,92 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack; + +import lombok.Data; +import org.apache.maven.plugins.annotations.Parameter; + +import java.util.List; + +/** + * 插件信息 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +@Data +public class PluginInfo { + + /** + * 插件id + */ + @Parameter(required = true) + private String id; + + /** + * 插件引导启动类 + */ + @Parameter(required = true) + private String bootstrapClass; + + /** + * 插件版本 + */ + @Parameter(required = true) + private String version; + + /** + * 插件配置文件名称。 + */ + private String configFileName; + + /** + * 插件配置文件所在目录。如果不填写, 默认从 target/classes 下读取 + */ + private String configFileLocation; + + /** + * 插件启动入口参数配置 + */ + private String args; + + /** + * 插件描述 + */ + private String description; + + /** + * 插件提供者 + */ + private String provider; + + /** + * 需要安装的主程序版本 + */ + private String requires; + + /** + * 插件 license + */ + private String license; + + /** + * 依赖的插件 + */ + private List dependencyPlugins; + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/RepackageMojo.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/RepackageMojo.java new file mode 100644 index 00000000..cf2f360a --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/RepackageMojo.java @@ -0,0 +1,133 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack; + +import com.gitee.starblues.common.Constants; +import com.gitee.starblues.plugin.pack.dev.DevConfig; +import com.gitee.starblues.plugin.pack.dev.DevRepackager; +import com.gitee.starblues.plugin.pack.encrypt.*; +import com.gitee.starblues.plugin.pack.main.MainConfig; +import com.gitee.starblues.plugin.pack.main.MainRepackager; +import com.gitee.starblues.plugin.pack.prod.ProdConfig; +import com.gitee.starblues.plugin.pack.prod.ProdRepackager; +import com.gitee.starblues.plugin.pack.utils.CommonUtils; +import com.gitee.starblues.utils.ObjectUtils; +import lombok.Getter; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; + +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +/** + * 重新打包 mojo + * + * @author starBlues + * @since 3.0.0 + * @version 3.1.1 + */ +@Mojo(name = "repackage", defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true, threadSafe = true, + requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, + requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME) +@Getter +public class RepackageMojo extends AbstractPackagerMojo { + + + @Parameter(property = "spring-brick-packager.devConfig") + private DevConfig devConfig; + + @Parameter(property = "spring-brick-packager.prodConfig") + private ProdConfig prodConfig; + + @Parameter(property = "spring-brick-packager.mainConfig") + private MainConfig mainConfig; + + @Parameter(property = "spring-brick-packager.mainLoad") + private LoadToMain loadToMain; + + @Parameter(property = "spring-brick-packager.encryptConfig") + private EncryptConfig encryptConfig; + + private final Set loadToMainSet = new LinkedHashSet<>(); + + @Override + protected void pack() throws MojoExecutionException, MojoFailureException { + initLoadToMainSet(); + String mode = getMode(); + try { + encrypt(); + } catch (Exception e) { + throw new MojoExecutionException("encrypt failed: " + e.getMessage()); + } + if(Constant.MODE_PROD.equalsIgnoreCase(mode)){ + new ProdRepackager(this).repackage(); + } else if(Constant.MODE_DEV.equalsIgnoreCase(mode)){ + new DevRepackager(this).repackage(); + } else if(Constant.MODE_MAIN.equalsIgnoreCase(mode)){ + new MainRepackager(this).repackage(); + } else { + throw new MojoExecutionException(mode +" model not supported, mode support : " + + Constant.MODE_DEV + "/" + Constant.MODE_PROD); + } + } + + public String resolveLoadToMain(Artifact artifact){ + if(artifact == null){ + return ""; + } + if(loadToMainSet.contains(artifact.getGroupId() + artifact.getArtifactId())){ + return Constants.LOAD_TO_MAIN_SIGN; + } + return ""; + } + + private void initLoadToMainSet(){ + if(loadToMain == null){ + return; + } + List dependencies = loadToMain.getDependencies(); + if(ObjectUtils.isEmpty(dependencies)){ + return; + } + for (Dependency dependency : dependencies) { + loadToMainSet.add(dependency.getGroupId() + dependency.getArtifactId()); + } + } + + /** + * 加密 + * @throws Exception 加密异常 + */ + private void encrypt() throws Exception { + if(encryptConfig == null){ + return; + } + EncryptPlugin encryptPlugin = new EncryptPluginFactory(); + PluginInfo pluginInfo = encryptPlugin.encrypt(encryptConfig, getPluginInfo()); + if(pluginInfo != null){ + setPluginInfo(pluginInfo); + } + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Repackager.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Repackager.java new file mode 100644 index 00000000..1877f9ea --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/Repackager.java @@ -0,0 +1,39 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +/** + * 重新打包接口 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public interface Repackager { + + /** + * 重新打包 + * @throws MojoExecutionException MojoExecutionException + * @throws MojoFailureException MojoFailureException + */ + void repackage() throws MojoExecutionException, MojoFailureException; + + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/Dependency.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/Dependency.java new file mode 100644 index 00000000..a99bba69 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/Dependency.java @@ -0,0 +1,41 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.dev; + +import lombok.Data; +import org.apache.maven.plugins.annotations.Parameter; + +/** + * 开发环境下配置本地依赖的Bean + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +@Data +public class Dependency { + + @Parameter(required = true) + private String groupId; + + @Parameter(required = true) + private String artifactId; + + @Parameter(required = true) + private String classesPath; + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevConfig.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevConfig.java new file mode 100644 index 00000000..74d6440e --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevConfig.java @@ -0,0 +1,44 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.dev; + +import lombok.Data; + +import java.util.List; + +/** + * 开发模式配置 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +@Data +public class DevConfig { + + /** + * 当前项目依赖其他模块的定义。 + * 主要定义依赖模块target->classes的目录, 方便开发调试 + */ + private List moduleDependencies; + + /** + * 本地jar依赖文件定义 + */ + private List localJars; + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevRepackager.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevRepackager.java new file mode 100644 index 00000000..2880f022 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/dev/DevRepackager.java @@ -0,0 +1,102 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.dev; + +import com.gitee.starblues.plugin.pack.BasicRepackager; +import com.gitee.starblues.plugin.pack.Constant; +import com.gitee.starblues.plugin.pack.RepackageMojo; +import com.gitee.starblues.plugin.pack.utils.CommonUtils; +import com.gitee.starblues.utils.FilesUtils; +import com.gitee.starblues.utils.ObjectUtils; +import lombok.Getter; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; + +import java.util.*; + +/** + * 开发环境打包 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public class DevRepackager extends BasicRepackager { + + @Getter + private Map moduleDependencies = Collections.emptyMap(); + + public DevRepackager(RepackageMojo repackageMojo) { + super(repackageMojo); + } + + @Override + protected Set getDependenciesIndexSet() throws Exception { + DevConfig devConfig = repackageMojo.getDevConfig(); + if(devConfig == null){ + return super.getDependenciesIndexSet(); + } + moduleDependencies = getModuleDependencies(devConfig); + Set dependenciesIndexSet = super.getDependenciesIndexSet(); + for (Dependency dependency : moduleDependencies.values()) { + dependenciesIndexSet.add(dependency.getClassesPath()); + } + List localJars = devConfig.getLocalJars(); + if(!ObjectUtils.isEmpty(localJars)){ + dependenciesIndexSet.addAll(localJars); + } + return dependenciesIndexSet; + } + + @Override + protected boolean filterArtifact(Artifact artifact) { + if(super.filterArtifact(artifact)){ + return true; + } + String moduleDependencyKey = getModuleDependencyKey(artifact.getGroupId(), artifact.getArtifactId()); + Dependency dependency = moduleDependencies.get(moduleDependencyKey); + return dependency != null && !ObjectUtils.isEmpty(dependency.getClassesPath()); + } + + protected Map getModuleDependencies(DevConfig devConfig) { + if(devConfig == null){ + return Collections.emptyMap(); + } + List moduleDependencies = devConfig.getModuleDependencies(); + if(ObjectUtils.isEmpty(moduleDependencies)){ + return Collections.emptyMap(); + } + Map moduleDependenciesMap = new HashMap<>(); + for (Dependency dependency : moduleDependencies) { + String moduleDependencyKey = getModuleDependencyKey(dependency.getGroupId(), + dependency.getArtifactId()); + if(moduleDependencyKey == null){ + continue; + } + moduleDependenciesMap.put(moduleDependencyKey, dependency); + } + return moduleDependenciesMap; + } + + protected String getModuleDependencyKey(String groupId, String artifactId){ + if(ObjectUtils.isEmpty(groupId) || ObjectUtils.isEmpty(artifactId)){ + return null; + } + return groupId + artifactId; + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesConfig.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesConfig.java new file mode 100644 index 00000000..a7d4afd3 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesConfig.java @@ -0,0 +1,33 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.encrypt; + +import lombok.Data; + +/** + * aes 加密配置 + * + * @author starBlues + * @since 3.0.1 + * @version 3.0.1 + */ +@Data +public class AesConfig { + + private String secretKey; + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesEncryptPlugin.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesEncryptPlugin.java new file mode 100644 index 00000000..4b2b0f6b --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesEncryptPlugin.java @@ -0,0 +1,43 @@ +package com.gitee.starblues.plugin.pack.encrypt; + +import com.gitee.starblues.common.cipher.AbstractPluginCipher; +import com.gitee.starblues.common.cipher.AesPluginCipher; +import com.gitee.starblues.plugin.pack.PluginInfo; +import com.gitee.starblues.utils.ObjectUtils; +import org.apache.maven.plugin.MojoExecutionException; + +import java.util.HashMap; +import java.util.Map; + +/** + * rsa 加密者 + * + * @author starBlues + * @since 3.0.1 + * @version 3.0.1 + */ +public class AesEncryptPlugin implements EncryptPlugin{ + + + @Override + public PluginInfo encrypt(EncryptConfig encryptConfig, PluginInfo pluginInfo) throws Exception{ + AesConfig aesConfig = encryptConfig.getAes(); + if(aesConfig == null){ + return null; + } + + String secretKey = aesConfig.getSecretKey(); + if(ObjectUtils.isEmpty(secretKey)){ + throw new MojoExecutionException("encryptConfig.aes.secretKey can't be empty"); + } + AbstractPluginCipher pluginCipher = new AesPluginCipher(); + Map params = new HashMap<>(); + params.put(AesPluginCipher.SECRET_KEY, secretKey); + pluginCipher.initParams(params); + + String bootstrapClass = pluginInfo.getBootstrapClass(); + String encrypt = pluginCipher.encrypt(bootstrapClass); + pluginInfo.setBootstrapClass(encrypt); + return pluginInfo; + } +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptConfig.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptConfig.java new file mode 100644 index 00000000..769b8db1 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptConfig.java @@ -0,0 +1,41 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.encrypt; + +import lombok.Data; + +/** + * 加密配置 + * + * @author starBlues + * @since 3.0.1 + * @version 3.0.1 + */ +@Data +public class EncryptConfig { + + /** + * rsa 配置 + */ + private RsaConfig rsa; + + /** + * aes 配置 + */ + private AesConfig aes; + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPlugin.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPlugin.java new file mode 100644 index 00000000..5a22feee --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPlugin.java @@ -0,0 +1,40 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.encrypt; + +import com.gitee.starblues.plugin.pack.PluginInfo; + +/** + * 加密插件 + * + * @author starBlues + * @since 3.0.1 + * @version 3.0.1 + */ +public interface EncryptPlugin { + + + /** + * 加密 + * @param pluginInfo 当前插件信息 + * @param encryptConfig 加密配置 + * @return 加密后得字符 + * @throws Exception 加密异常 + */ + PluginInfo encrypt(EncryptConfig encryptConfig, PluginInfo pluginInfo) throws Exception; + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPluginFactory.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPluginFactory.java new file mode 100644 index 00000000..c52148ca --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPluginFactory.java @@ -0,0 +1,50 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.encrypt; + +import com.gitee.starblues.plugin.pack.PluginInfo; + +import java.util.ArrayList; +import java.util.List; + +/** + * 加密插件工厂 + * + * @author starBlues + * @since 3.0.1 + * @version 3.0.1 + */ +public class EncryptPluginFactory implements EncryptPlugin { + + private final List encryptPlugins = new ArrayList<>(); + + public EncryptPluginFactory(){ + encryptPlugins.add(new AesEncryptPlugin()); + encryptPlugins.add(new RsaEncryptPlugin()); + } + + @Override + public PluginInfo encrypt(EncryptConfig encryptConfig, PluginInfo pluginInfo) throws Exception{ + for (EncryptPlugin encryptPlugin : encryptPlugins) { + PluginInfo encrypt = encryptPlugin.encrypt(encryptConfig, pluginInfo); + if(encrypt != null){ + return encrypt; + } + } + return pluginInfo; + } +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaConfig.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaConfig.java new file mode 100644 index 00000000..09a85972 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaConfig.java @@ -0,0 +1,36 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.encrypt; + +import lombok.Data; + +/** + * rsa 加密配置 + * + * @author starBlues + * @since 3.0.1 + * @version 3.0.1 + */ +@Data +public class RsaConfig { + + /** + * rsa 公钥 + */ + private String publicKey; + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaEncryptPlugin.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaEncryptPlugin.java new file mode 100644 index 00000000..2e1f1904 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaEncryptPlugin.java @@ -0,0 +1,57 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.encrypt; + +import com.gitee.starblues.common.cipher.AbstractPluginCipher; +import com.gitee.starblues.common.cipher.RsaPluginCipher; +import com.gitee.starblues.plugin.pack.PluginInfo; +import com.gitee.starblues.utils.ObjectUtils; +import org.apache.maven.plugin.MojoExecutionException; + +import java.util.HashMap; +import java.util.Map; + +/** + * rsa 算法插件加密 + * + * @author starBlues + * @since 3.0.1 + * @version 3.0.1 + */ +public class RsaEncryptPlugin implements EncryptPlugin{ + + @Override + public PluginInfo encrypt(EncryptConfig encryptConfig, PluginInfo pluginInfo) throws Exception { + RsaConfig rsaConfig = encryptConfig.getRsa(); + if(rsaConfig == null){ + return null; + } + + String publicKey = rsaConfig.getPublicKey(); + if(ObjectUtils.isEmpty(publicKey)){ + throw new MojoExecutionException("encryptConfig.rsa.publicKey can't be empty"); + } + AbstractPluginCipher pluginCipher = new RsaPluginCipher(); + Map params = new HashMap<>(); + params.put(RsaPluginCipher.PUBLIC_KEY, publicKey); + pluginCipher.initParams(params); + + String bootstrapClass = pluginInfo.getBootstrapClass(); + pluginInfo.setBootstrapClass(pluginCipher.encrypt(bootstrapClass)); + return pluginInfo; + } +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/DependencyFilter.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/DependencyFilter.java new file mode 100644 index 00000000..1150a26c --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/DependencyFilter.java @@ -0,0 +1,75 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.filter; + +import com.gitee.starblues.utils.ObjectUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.shared.artifact.filter.collection.AbstractArtifactsFilter; +import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +/** + * 依赖过滤 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public abstract class DependencyFilter extends AbstractArtifactsFilter { + + private final List filters; + + public DependencyFilter(List dependencies) { + this.filters = dependencies; + } + + @Override + public Set filter(Set artifacts) throws ArtifactFilterException { + if(ObjectUtils.isEmpty(artifacts)){ + return artifacts; + } + Set result = new LinkedHashSet<>(); + for (Artifact artifact : artifacts) { + if (!filter(artifact)) { + result.add(artifact); + } + } + return result; + } + + /** + * 子类过滤结果 + * @param artifact artifact + * @return boolean + */ + protected abstract boolean filter(Artifact artifact); + + protected final boolean equals(Artifact artifact, FilterableDependency dependency) { + if (!dependency.getGroupId().equals(artifact.getGroupId())) { + return false; + } + return dependency.getArtifactId().equals(artifact.getArtifactId()); + } + + protected final List getFilters() { + return this.filters; + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/Exclude.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/Exclude.java new file mode 100644 index 00000000..0aaff1f2 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/Exclude.java @@ -0,0 +1,35 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.filter; + +/** + * 排除的依赖定义 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public class Exclude extends FilterableDependency{ + + public static Exclude get(String groupId, String artifactId){ + Exclude exclude = new Exclude(); + exclude.setGroupId(groupId); + exclude.setArtifactId(artifactId); + return exclude; + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/ExcludeFilter.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/ExcludeFilter.java new file mode 100644 index 00000000..cb564bf7 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/ExcludeFilter.java @@ -0,0 +1,51 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.filter; + +import org.apache.maven.artifact.Artifact; + +import java.util.Arrays; +import java.util.List; + +/** + * 排除过滤 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public class ExcludeFilter extends DependencyFilter { + + public ExcludeFilter(Exclude... excludes) { + this(Arrays.asList(excludes)); + } + + public ExcludeFilter(List excludes) { + super(excludes); + } + + @Override + protected boolean filter(Artifact artifact) { + for (FilterableDependency dependency : getFilters()) { + if (equals(artifact, dependency)) { + return true; + } + } + return false; + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/FilterableDependency.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/FilterableDependency.java new file mode 100644 index 00000000..d51b6032 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/FilterableDependency.java @@ -0,0 +1,38 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.filter; + +import lombok.Data; +import org.apache.maven.plugins.annotations.Parameter; + +/** + * 可过滤依赖bean + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +@Data +public abstract class FilterableDependency { + + @Parameter(required = true) + private String groupId; + + @Parameter(required = true) + private String artifactId; + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/Include.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/Include.java new file mode 100644 index 00000000..c2bfb7a2 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/Include.java @@ -0,0 +1,27 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.filter; + +/** + * 包含的依赖定义 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public class Include extends FilterableDependency{ +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/IncludeFilter.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/IncludeFilter.java new file mode 100644 index 00000000..c9e83858 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/filter/IncludeFilter.java @@ -0,0 +1,46 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.filter; + +import org.apache.maven.artifact.Artifact; + +import java.util.List; + +/** + * 包含过滤器 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public class IncludeFilter extends DependencyFilter { + + public IncludeFilter(List includes) { + super(includes); + } + + @Override + protected boolean filter(Artifact artifact) { + for (FilterableDependency dependency : getFilters()) { + if (equals(artifact, dependency)) { + return false; + } + } + return true; + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarNestPackager.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarNestPackager.java new file mode 100644 index 00000000..804d778c --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarNestPackager.java @@ -0,0 +1,138 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.main; + +import com.gitee.starblues.common.PackageType; +import com.gitee.starblues.plugin.pack.Constant; +import com.gitee.starblues.plugin.pack.RepackageMojo; +import com.gitee.starblues.plugin.pack.Repackager; +import com.gitee.starblues.plugin.pack.utils.CommonUtils; +import com.gitee.starblues.plugin.pack.utils.PackageJar; +import org.apache.commons.io.IOUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; + +import java.io.File; +import java.util.List; +import java.util.Set; +import java.util.jar.Attributes; +import java.util.jar.JarFile; +import java.util.jar.Manifest; + +import static com.gitee.starblues.common.PackageStructure.*; +import static com.gitee.starblues.common.ManifestKey.*; + +/** + * 嵌套jar打包 + * + * @author starBlues + * @since 3.0.0 + * @version 3.1.1 + */ +public class JarNestPackager implements Repackager { + + protected final MainConfig mainConfig; + protected final RepackageMojo repackageMojo; + + protected PackageJar packageJar; + + private JarFile sourceJarFile; + + public JarNestPackager(MainRepackager mainRepackager) { + this.mainConfig = mainRepackager.getMainConfig(); + this.repackageMojo = mainRepackager.getRepackageMojo(); + } + + @Override + public void repackage() throws MojoExecutionException, MojoFailureException { + try { + sourceJarFile = CommonUtils.getSourceJarFile(repackageMojo.getProject()); + packageJar = new PackageJar(mainConfig.getOutputDirectory(), mainConfig.getFileName()); + writeClasses(); + writeDependencies(); + writeManifest(); + } catch (Exception e) { + repackageMojo.getLog().error(e.getMessage(), e); + throw new MojoFailureException(e); + } finally { + IOUtils.closeQuietly(packageJar); + IOUtils.closeQuietly(sourceJarFile); + } + } + + protected void writeManifest() throws Exception { + Manifest manifest = getManifest(); + packageJar.putDirEntry(META_INF_NAME + SEPARATOR); + packageJar.write(PROD_MANIFEST_PATH, manifest::write); + } + + protected Manifest getManifest() throws Exception{ + Manifest manifest = null; + if(sourceJarFile != null){ + manifest = sourceJarFile.getManifest(); + } else { + manifest = new Manifest(); + } + Attributes attributes = manifest.getMainAttributes(); + attributes.putValue(MANIFEST_VERSION, MANIFEST_VERSION_1_0); + attributes.putValue(BUILD_TIME, CommonUtils.getDateTime()); + attributes.putValue(START_CLASS, mainConfig.getMainClass()); + attributes.putValue(MAIN_CLASS, MAIN_CLASS_VALUE); + attributes.putValue(MAIN_PACKAGE_TYPE, PackageType.MAIN_PACKAGE_TYPE_JAR); + attributes.putValue(DEVELOPMENT_MODE, mainConfig.getDevelopmentMode()); + + // 增加jar包title和version属性 + MavenProject mavenProject = this.repackageMojo.getProject(); + attributes.putValue(IMPLEMENTATION_TITLE, mavenProject.getArtifactId()); + attributes.putValue(IMPLEMENTATION_VERSION, mavenProject.getVersion()); + return manifest; + } + + protected void writeClasses() throws Exception { + String buildDir = repackageMojo.getProject().getBuild().getOutputDirectory(); + packageJar.copyDirToPackage(new File(buildDir), null); + } + + protected void writeDependencies() throws Exception { + Set dependencies = repackageMojo.getSourceDependencies(); + String libDirEntryName = createLibEntry(); + for (Artifact artifact : dependencies) { + if(filterArtifact(artifact)){ + continue; + } + if(CommonUtils.isPluginFrameworkLoader(artifact)){ + // 本框架loader依赖 + packageJar.copyZipToPackage(artifact.getFile()); + } else { + packageJar.writeDependency(artifact.getFile(), libDirEntryName); + } + } + } + + protected boolean filterArtifact(Artifact artifact) { + return Constant.filterArtifact(artifact, repackageMojo.getIncludeSystemScope()); + } + + protected String createLibEntry() throws Exception { + String libDirEntryName = PROD_LIB_PATH; + packageJar.putDirEntry(libDirEntryName); + return libDirEntryName; + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarOuterPackager.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarOuterPackager.java new file mode 100644 index 00000000..eb9e8864 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/JarOuterPackager.java @@ -0,0 +1,146 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.main; + +import com.gitee.starblues.common.PackageStructure; +import com.gitee.starblues.common.PackageType; +import com.gitee.starblues.plugin.pack.utils.CommonUtils; +import com.gitee.starblues.utils.FilesUtils; +import com.gitee.starblues.utils.ObjectUtils; +import org.apache.commons.io.FileUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; + +import java.io.File; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import static com.gitee.starblues.common.ManifestKey.*; + +/** + * jar 外置包 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.2 + */ +public class JarOuterPackager extends JarNestPackager { + + private static final String LIB_INDEXES_SPLIT = " "; + + private final Set dependencyIndexNames = new LinkedHashSet<>(); + + public JarOuterPackager(MainRepackager mainRepackager) { + super(mainRepackager); + } + + @Override + public void repackage() throws MojoExecutionException, MojoFailureException { + // 生成依赖文件夹 + String rootDir = createRootDir(); + mainConfig.setOutputDirectory(rootDir); + super.repackage(); + } + + @Override + protected void writeClasses() throws Exception { + String buildDir = repackageMojo.getProject().getBuild().getOutputDirectory(); + packageJar.copyDirToPackage(new File(buildDir), null); + } + + private String createRootDir() throws MojoFailureException{ + String outputDirectory = mainConfig.getOutputDirectory(); + String fileName = mainConfig.getFileName(); + String rootDirPath = FilesUtils.joiningFilePath(outputDirectory, fileName); + File rootFile = new File(rootDirPath); + CommonUtils.deleteFile(rootFile); + if(rootFile.mkdirs()){ + return rootDirPath; + } else { + throw new MojoFailureException("Create dir failure : " + rootDirPath); + } + } + + @Override + protected Manifest getManifest() throws Exception { + Manifest manifest = new Manifest(); + Attributes attributes = manifest.getMainAttributes(); + attributes.putValue(MANIFEST_VERSION, MANIFEST_VERSION_1_0); + attributes.putValue(START_CLASS, mainConfig.getMainClass()); + attributes.putValue(MAIN_CLASS, MAIN_CLASS_VALUE); + attributes.putValue(MAIN_PACKAGE_TYPE, PackageType.MAIN_PACKAGE_TYPE_JAR_OUTER); + attributes.putValue(MAIN_LIB_DIR, getLibPath()); + attributes.putValue(DEVELOPMENT_MODE, mainConfig.getDevelopmentMode()); + + // 增加jar包title和version属性 + MavenProject mavenProject = this.repackageMojo.getProject(); + attributes.putValue(IMPLEMENTATION_TITLE, mavenProject.getArtifactId()); + attributes.putValue(IMPLEMENTATION_VERSION, mavenProject.getVersion()); + return manifest; + } + + + private String getLibIndexes() throws Exception { + if(dependencyIndexNames.isEmpty()){ + return ""; + } + StringBuilder libName = new StringBuilder(); + for (String dependencyIndexName : dependencyIndexNames) { + libName.append(dependencyIndexName).append(LIB_INDEXES_SPLIT); + } + return libName.toString(); + } + + @Override + protected void writeDependencies() throws Exception { + Set dependencies = repackageMojo.getSourceDependencies(); + for (Artifact artifact : dependencies) { + if(filterArtifact(artifact)){ + continue; + } + if(CommonUtils.isPluginFrameworkLoader(artifact)){ + // 本框架loader依赖 + packageJar.copyZipToPackage(artifact.getFile()); + } else { + File artifactFile = artifact.getFile(); + String libPath = getLibPath(); + if(FilesUtils.isRelativePath(libPath)){ + libPath = FilesUtils.resolveRelativePath(mainConfig.getOutputDirectory(), getLibPath()); + } else { + libPath = FilesUtils.joiningFilePath(mainConfig.getOutputDirectory(), libPath); + } + String targetFilePath = FilesUtils.joiningFilePath(libPath, artifactFile.getName()); + FileUtils.copyFile(artifactFile, new File(targetFilePath)); + dependencyIndexNames.add(artifactFile.getName()); + } + } + } + + private String getLibPath(){ + String libDir = PackageStructure.LIB_NAME; + if(!ObjectUtils.isEmpty(mainConfig.getLibDir())){ + libDir = mainConfig.getLibDir(); + } + return libDir; + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainConfig.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainConfig.java new file mode 100644 index 00000000..8b9101f7 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainConfig.java @@ -0,0 +1,68 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.main; + +import lombok.Data; +import org.apache.maven.plugins.annotations.Parameter; + +/** + * 主程序打包配置 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +@Data +public class MainConfig { + + /** + * 主启动类 + */ + @Parameter(required = true) + private String mainClass; + + /** + * 打包类型。默认:jar + * {@link com.gitee.starblues.common.PackageType#MAIN_PACKAGE_TYPE_JAR} + * {@link com.gitee.starblues.common.PackageType#MAIN_PACKAGE_TYPE_JAR_OUTER} + */ + private String packageType; + + /** + * 文件名称。默认 artifactId-version-repackage + */ + private String fileName; + + /** + * 依赖包所在目录 + */ + private String libDir; + + /** + * 输出文件目录。默认target + */ + private String outputDirectory; + + /** + * 开发模式: + * isolation: 隔离模式[默认] + * coexist: 共享模式 + * simple: 简单模式 + */ + private String developmentMode; + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainRepackager.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainRepackager.java new file mode 100644 index 00000000..f46ac0c5 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/main/MainRepackager.java @@ -0,0 +1,136 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.main; + +import com.gitee.starblues.common.PackageType; +import com.gitee.starblues.plugin.pack.Constant; +import com.gitee.starblues.plugin.pack.RepackageMojo; +import com.gitee.starblues.plugin.pack.Repackager; +import com.gitee.starblues.plugin.pack.utils.CommonUtils; +import com.gitee.starblues.utils.ObjectUtils; +import com.gitee.starblues.utils.ReflectionUtils; +import lombok.Getter; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; + +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Set; + +/** + * 主程序打包 + * + * @author starBlues + * @since 3.0.0 + * @version 3.1.1 + */ +@Getter +public class MainRepackager implements Repackager { + + private final RepackageMojo repackageMojo; + private final MainConfig mainConfig; + + public MainRepackager(RepackageMojo repackageMojo) { + this.repackageMojo = repackageMojo; + this.mainConfig = repackageMojo.getMainConfig(); + } + + @Override + public void repackage() throws MojoExecutionException, MojoFailureException { + checkConfig(); + setDevelopmentMode(); + String packageType = mainConfig.getPackageType(); + Repackager repackager = null; + if(PackageType.MAIN_PACKAGE_TYPE_JAR.equalsIgnoreCase(packageType)){ + repackager = new JarNestPackager(this); + } else if(PackageType.MAIN_PACKAGE_TYPE_JAR_OUTER.equalsIgnoreCase(packageType)){ + repackager = new JarOuterPackager(this); + } else { + throw new MojoFailureException("Not found packageType : " + packageType); + } + repackager.repackage(); + } + + private void checkConfig() throws MojoFailureException { + if(mainConfig == null){ + throw new MojoFailureException("configuration.mainConfig config cannot be empty"); + } + if(ObjectUtils.isEmpty(mainConfig.getMainClass())) { + throw new MojoFailureException("configuration.mainConfig.mainClass config cannot be empty"); + } + String fileName = mainConfig.getFileName(); + if(ObjectUtils.isEmpty(fileName)) { + MavenProject project = repackageMojo.getProject(); + mainConfig.setFileName(project.getArtifactId() + "-" + project.getVersion() + "-repackage"); + } + String packageType = mainConfig.getPackageType(); + if(ObjectUtils.isEmpty(packageType)) { + mainConfig.setPackageType(PackageType.MAIN_PACKAGE_TYPE_JAR); + } + String outputDirectory = mainConfig.getOutputDirectory(); + if(ObjectUtils.isEmpty(outputDirectory)){ + mainConfig.setOutputDirectory(repackageMojo.getOutputDirectory().getPath()); + } + } + + private void setDevelopmentMode() throws MojoFailureException{ + String developmentMode = mainConfig.getDevelopmentMode(); + if(!ObjectUtils.isEmpty(developmentMode)){ + return; + } + try { + File file = new File(repackageMojo.getProject().getBuild().getOutputDirectory()); + Set artifacts = repackageMojo.getProject().getArtifacts(); + + URL[] urls = new URL[artifacts.size() + 1]; + int i = 0; + for (Artifact artifact : artifacts) { + urls[i] = artifact.getFile().toURI().toURL(); + i++; + } + urls[i] = file.toURI().toURL(); + URLClassLoader urlClassLoader = new URLClassLoader(urls, null); + + String mainClass = repackageMojo.getMainConfig().getMainClass(); + if(ObjectUtils.isEmpty(mainClass)){ + throw new Exception("mainConfig.mainClass config can't be empty"); + } + Class aClass = urlClassLoader.loadClass(mainClass); + Method method = ReflectionUtils.findMethod(aClass, Constant.DEVELOPMENT_MODE_METHOD_NAME); + String methodKey = aClass.getName() + "#" + Constant.DEVELOPMENT_MODE_METHOD_NAME + "()"; + if(method == null){ + throw new Exception("Not found method : " + methodKey); + } + method.setAccessible(true); + Object o = aClass.getConstructor().newInstance(); + Object result = method.invoke(o); + if(ObjectUtils.isEmpty(result)){ + throw new Exception(methodKey + " return value can't be empty"); + } + getMainConfig().setDevelopmentMode(String.valueOf(result)); + } catch (Exception e) { + throw new MojoFailureException("Set developmentMode failure:" + e.getMessage()); + } + } + + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/DirProdRepackager.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/DirProdRepackager.java new file mode 100644 index 00000000..8f9118ea --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/DirProdRepackager.java @@ -0,0 +1,156 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.prod; + +import com.gitee.starblues.common.*; +import com.gitee.starblues.plugin.pack.RepackageMojo; +import com.gitee.starblues.plugin.pack.dev.DevRepackager; +import com.gitee.starblues.plugin.pack.utils.CommonUtils; +import com.gitee.starblues.utils.FilesUtils; +import com.gitee.starblues.utils.ObjectUtils; +import org.apache.commons.io.FileUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Properties; +import java.util.Set; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import static com.gitee.starblues.common.PackageStructure.*; + +/** + * 文件夹包生成 + * + * @author starBlues + * @since 3.0.0 + * @version 3.1.1 + */ +public class DirProdRepackager extends DevRepackager { + + protected final ProdConfig prodConfig; + + + public DirProdRepackager(RepackageMojo repackageMojo, ProdConfig prodConfig) { + super(repackageMojo); + this.prodConfig = prodConfig; + } + + @Override + public void repackage() throws MojoExecutionException, MojoFailureException { + super.repackage(); + try { + resolveClasses(); + logSuccess(); + } catch (Exception e) { + repackageMojo.getLog().error(e.getMessage(), e); + throw new MojoFailureException(e); + } + } + + protected void logSuccess(){ + repackageMojo.getLog().info("Success package prod dir file : " + getRootDir()); + } + + @Override + protected String createRootDir() throws MojoFailureException { + String fileName = prodConfig.getFileName(); + String dirPath = FilesUtils.joiningFilePath(prodConfig.getOutputDirectory(), fileName); + File dirFile = new File(dirPath); + CommonUtils.deleteFile(dirFile); + if(!dirFile.mkdirs()){ + throw new MojoFailureException("Create package dir failure: " + dirFile.getPath()); + } + return dirFile.getPath(); + } + + @Override + protected String getRelativeManifestPath() { + return FilesUtils.joiningFilePath(META_INF_NAME, MANIFEST); + } + + @Override + protected String getRelativePluginMetaPath() { + return FilesUtils.joiningFilePath(META_INF_NAME, PLUGIN_META_NAME); + } + + @Override + protected String getRelativeResourcesDefinePath() { + return FilesUtils.joiningFilePath(META_INF_NAME, RESOURCES_DEFINE_NAME); + } + + @Override + protected Manifest getManifest() throws Exception { + Manifest manifest = super.getManifest(); + Attributes attributes = manifest.getMainAttributes(); + attributes.putValue(ManifestKey.PLUGIN_META_PATH, PROD_PLUGIN_META_PATH); + attributes.putValue(ManifestKey.PLUGIN_PACKAGE_TYPE, PackageType.PLUGIN_PACKAGE_TYPE_DIR); + return manifest; + } + + @Override + protected Properties createPluginMetaInfo() throws Exception { + Properties properties = super.createPluginMetaInfo(); + properties.put(PluginDescriptorKey.PLUGIN_PATH, CLASSES_NAME); + properties.put(PluginDescriptorKey.PLUGIN_RESOURCES_CONFIG, PROD_RESOURCES_DEFINE_PATH); + String libDir = prodConfig.getLibDir(); + if(ObjectUtils.isEmpty(libDir)){ + libDir = Constants.RELATIVE_SIGN + PackageStructure.PROD_LIB_PATH; + } + properties.put(PluginDescriptorKey.PLUGIN_LIB_DIR, libDir); + return properties; + } + + protected void resolveClasses() throws Exception { + String buildDir = repackageMojo.getProject().getBuild().getOutputDirectory(); + String path = FilesUtils.joiningFilePath(getRootDir(), CLASSES_NAME); + File file = new File(path); + FileUtils.forceMkdir(file); + FileUtils.copyDirectory(new File(buildDir), file); + } + + @Override + protected Set getDependenciesIndexSet() throws Exception { + Set dependencies = repackageMojo.getFilterDependencies(); + String libDir = createLibDir(); + Set dependencyIndexNames = new LinkedHashSet<>(dependencies.size()); + for (Artifact artifact : dependencies) { + if(filterArtifact(artifact)){ + continue; + } + File artifactFile = artifact.getFile(); + FileUtils.copyFile(artifactFile, new File(FilesUtils.joiningFilePath(libDir, artifactFile.getName()))); + dependencyIndexNames.add(artifactFile.getName() + repackageMojo.resolveLoadToMain(artifact)); + } + return dependencyIndexNames; + } + + protected String createLibDir() throws IOException { + String dir = FilesUtils.joiningFilePath(getRootDir(), PackageStructure.LIB_NAME); + File file = new File(dir); + if(file.mkdir()){ + return dir; + } + throw new IOException("Create " + PackageStructure.LIB_NAME + " dir failure"); + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/JarNestedProdRepackager.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/JarNestedProdRepackager.java new file mode 100644 index 00000000..052eaf2c --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/JarNestedProdRepackager.java @@ -0,0 +1,77 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.prod; + +import com.gitee.starblues.common.ManifestKey; +import com.gitee.starblues.common.PackageType; +import com.gitee.starblues.common.PluginDescriptorKey; +import com.gitee.starblues.plugin.pack.RepackageMojo; +import com.gitee.starblues.plugin.pack.utils.PackageJar; +import com.gitee.starblues.plugin.pack.utils.PackageZip; +import org.apache.commons.compress.archivers.ArchiveOutputStream; +import org.apache.commons.compress.archivers.jar.JarArchiveEntry; +import org.apache.commons.compress.archivers.jar.JarArchiveOutputStream; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +import java.io.*; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import static com.gitee.starblues.common.PackageStructure.PROD_CLASSES_PATH; +import static com.gitee.starblues.common.PackageStructure.PROD_RESOURCES_DEFINE_PATH; + +/** + * jar包生成 + * + * @author starBlues + * @since 3.0.0 + * @version 3.1.1 + */ +public class JarNestedProdRepackager extends ZipProdRepackager { + + + public JarNestedProdRepackager(RepackageMojo repackageMojo, ProdConfig prodConfig) { + super(repackageMojo, prodConfig); + } + + @Override + public void repackage() throws MojoExecutionException, MojoFailureException { + super.repackage(); + } + + protected void logSuccess(){ + repackageMojo.getLog().info("Success package prod jar file : " + + packageZip.getFile().getPath()); + } + + @Override + protected PackageZip getPackageZip() throws Exception { + return new PackageJar(prodConfig.getOutputDirectory(), prodConfig.getFileName()); + } + + @Override + protected Manifest getManifest() throws Exception { + Manifest manifest = super.getManifest(); + manifest.getMainAttributes().putValue( + ManifestKey.PLUGIN_PACKAGE_TYPE, PackageType.PLUGIN_PACKAGE_TYPE_JAR); + return manifest; + } + + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/JarOuterProdRepackager.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/JarOuterProdRepackager.java new file mode 100644 index 00000000..4d1eaf07 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/JarOuterProdRepackager.java @@ -0,0 +1,56 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.prod; + +import com.gitee.starblues.common.ManifestKey; +import com.gitee.starblues.common.PackageType; +import com.gitee.starblues.common.PluginDescriptorKey; +import com.gitee.starblues.plugin.pack.RepackageMojo; +import com.gitee.starblues.plugin.pack.utils.PackageJar; +import com.gitee.starblues.plugin.pack.utils.PackageZip; + +import java.util.jar.Manifest; + +/** + * jar-outer包生成 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public class JarOuterProdRepackager extends ZipOuterProdRepackager { + + + public JarOuterProdRepackager(RepackageMojo repackageMojo, ProdConfig prodConfig) { + super(repackageMojo, prodConfig); + } + + @Override + protected PackageZip getPackageZip(String rootDir) throws Exception { + return new PackageJar(rootDir, super.prodConfig.getFileName()); + } + + @Override + protected Manifest getManifest() throws Exception { + Manifest manifest = super.getManifest(); + manifest.getMainAttributes().putValue(ManifestKey.PLUGIN_PACKAGE_TYPE, + PackageType.PLUGIN_PACKAGE_TYPE_JAR_OUTER); + return manifest; + } + + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ProdConfig.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ProdConfig.java new file mode 100644 index 00000000..10c334b9 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ProdConfig.java @@ -0,0 +1,59 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.prod; + + +import lombok.Data; +import org.apache.maven.plugins.annotations.Parameter; + +/** + * 生产环境打包配置 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.2 + */ +@Data +public class ProdConfig { + + /** + * 打包类型。默认jar包 + * {@link com.gitee.starblues.common.PackageType#PLUGIN_PACKAGE_TYPE_JAR} + * {@link com.gitee.starblues.common.PackageType#PLUGIN_PACKAGE_TYPE_JAR_OUTER} + * {@link com.gitee.starblues.common.PackageType#PLUGIN_PACKAGE_TYPE_ZIP} + * {@link com.gitee.starblues.common.PackageType#PLUGIN_PACKAGE_TYPE_ZIP_OUTER} + * {@link com.gitee.starblues.common.PackageType#PLUGIN_PACKAGE_TYPE_DIR} + */ + @Parameter(required = true, defaultValue = "jar") + private String packageType = "jar"; + + /** + * 文件名称。默认 pluginId-version-repackage + */ + private String fileName; + + /** + * 输出文件目录。默认target + */ + private String outputDirectory; + + /** + * jar-outer、zip-outer、dir 类型可指定依赖包目录 + */ + private String libDir; + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ProdRepackager.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ProdRepackager.java new file mode 100644 index 00000000..629d8160 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ProdRepackager.java @@ -0,0 +1,95 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.prod; + +import com.gitee.starblues.common.PackageType; +import com.gitee.starblues.plugin.pack.PluginInfo; +import com.gitee.starblues.plugin.pack.RepackageMojo; +import com.gitee.starblues.plugin.pack.Repackager; +import com.gitee.starblues.plugin.pack.dev.DevRepackager; +import com.gitee.starblues.utils.ObjectUtils; +import lombok.Getter; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + + +/** + * 生产环境打包 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public class ProdRepackager implements Repackager { + + @Getter + private ProdConfig prodConfig; + + private final RepackageMojo repackageMojo; + private final Repackager repackager; + + public ProdRepackager(RepackageMojo repackageMojo) { + this.repackageMojo = repackageMojo; + this.repackager = new DevRepackager(repackageMojo); + } + + @Override + public void repackage() throws MojoExecutionException, MojoFailureException { + repackager.repackage(); + this.prodConfig = getProdConfig(repackageMojo); + String packageType = prodConfig.getPackageType(); + Repackager repackager = null; + + if(PackageType.PLUGIN_PACKAGE_TYPE_ZIP.equalsIgnoreCase(packageType)){ + repackager = new ZipProdRepackager(repackageMojo, prodConfig); + } else if(PackageType.PLUGIN_PACKAGE_TYPE_JAR.equalsIgnoreCase(packageType)){ + repackager = new JarNestedProdRepackager(repackageMojo, prodConfig); + } else if(PackageType.PLUGIN_PACKAGE_TYPE_ZIP_OUTER.equalsIgnoreCase(packageType)){ + repackager = new ZipOuterProdRepackager(repackageMojo, prodConfig); + } else if(PackageType.PLUGIN_PACKAGE_TYPE_JAR_OUTER.equalsIgnoreCase(packageType)){ + repackager = new JarOuterProdRepackager(repackageMojo, prodConfig); + } else if(PackageType.PLUGIN_PACKAGE_TYPE_DIR.equalsIgnoreCase(packageType)){ + repackager = new DirProdRepackager(repackageMojo, prodConfig); + } else { + throw new MojoFailureException("Not found packageType : " + packageType); + } + repackager.repackage(); + } + + protected ProdConfig getProdConfig(RepackageMojo repackageMojo){ + ProdConfig prodConfig = repackageMojo.getProdConfig(); + if(prodConfig == null){ + prodConfig = new ProdConfig(); + } + if(ObjectUtils.isEmpty(prodConfig.getPackageType())){ + prodConfig.setPackageType(PackageType.PLUGIN_PACKAGE_TYPE_JAR); + } + String fileName = prodConfig.getFileName(); + if(ObjectUtils.isEmpty(fileName)) { + PluginInfo pluginInfo = repackageMojo.getPluginInfo(); + prodConfig.setFileName(pluginInfo.getId() + "-" + pluginInfo.getVersion() + "-repackage"); + } + String outputDirectory = prodConfig.getOutputDirectory(); + if(ObjectUtils.isEmpty(outputDirectory)){ + prodConfig.setOutputDirectory(repackageMojo.getOutputDirectory().getPath()); + } + return prodConfig; + } + + + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ZipOuterProdRepackager.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ZipOuterProdRepackager.java new file mode 100644 index 00000000..87b1f134 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ZipOuterProdRepackager.java @@ -0,0 +1,128 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.prod; + +import com.gitee.starblues.common.ManifestKey; +import com.gitee.starblues.common.PackageType; +import com.gitee.starblues.common.PluginDescriptorKey; +import com.gitee.starblues.plugin.pack.Constant; +import com.gitee.starblues.plugin.pack.RepackageMojo; +import com.gitee.starblues.plugin.pack.utils.PackageJar; +import com.gitee.starblues.plugin.pack.utils.PackageZip; +import com.gitee.starblues.utils.FilesUtils; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +import java.io.File; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import static com.gitee.starblues.common.PackageStructure.*; + +/** + * zip-outer 包生成 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public class ZipOuterProdRepackager extends DirProdRepackager { + + protected PackageZip packageZip; + + public ZipOuterProdRepackager(RepackageMojo repackageMojo, ProdConfig prodConfig) { + super(repackageMojo, prodConfig); + } + + @Override + public void repackage() throws MojoExecutionException, MojoFailureException { + try { + super.repackage(); + } catch (Exception e){ + throw new MojoFailureException(e); + } finally { + if(packageZip != null){ + IOUtils.closeQuietly(packageZip); + } + } + } + + @Override + protected String createRootDir() throws MojoFailureException { + String rootDir = super.createRootDir(); + try { + packageZip = getPackageZip(rootDir); + return rootDir; + } catch (Exception e) { + throw new MojoFailureException(e); + } + } + + protected PackageZip getPackageZip(String rootDir) throws Exception { + return new PackageZip(rootDir, super.prodConfig.getFileName()); + } + + @Override + protected void resolveClasses() throws Exception { + String buildDir = repackageMojo.getProject().getBuild().getOutputDirectory(); + packageZip.copyDirToPackage(new File(buildDir), ""); + } + + @Override + protected Manifest getManifest() throws Exception { + Manifest manifest = super.getManifest(); + Attributes attributes = manifest.getMainAttributes(); + attributes.putValue(ManifestKey.PLUGIN_META_PATH, PROD_PLUGIN_META_PATH); + attributes.putValue(ManifestKey.PLUGIN_PACKAGE_TYPE, PackageType.PLUGIN_PACKAGE_TYPE_ZIP_OUTER); + return manifest; + } + + @Override + protected Properties createPluginMetaInfo() throws Exception { + Properties properties = super.createPluginMetaInfo(); + properties.put(PluginDescriptorKey.PLUGIN_PATH, packageZip.getFileName()); + return properties; + } + @Override + protected void writeManifest(Manifest manifest) throws Exception { + packageZip.writeManifest(manifest); + } + + @Override + protected String writePluginMetaInfo(Properties properties) throws Exception { + packageZip.write(PROD_PLUGIN_META_PATH, outputStream->{ + properties.store(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8), + Constant.PLUGIN_METE_COMMENTS); + }); + return PROD_PLUGIN_META_PATH; + } + + + @Override + protected String writeResourcesDefineFile(String resourcesDefineContent) throws Exception { + packageZip.write(PROD_RESOURCES_DEFINE_PATH, resourcesDefineContent); + return PROD_RESOURCES_DEFINE_PATH; + } +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ZipProdRepackager.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ZipProdRepackager.java new file mode 100644 index 00000000..42ed36ff --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/prod/ZipProdRepackager.java @@ -0,0 +1,197 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.prod; + +import com.gitee.starblues.common.ManifestKey; +import com.gitee.starblues.common.PackageStructure; +import com.gitee.starblues.common.PackageType; +import com.gitee.starblues.common.PluginDescriptorKey; +import com.gitee.starblues.plugin.pack.Constant; +import com.gitee.starblues.plugin.pack.RepackageMojo; +import com.gitee.starblues.plugin.pack.dev.Dependency; +import com.gitee.starblues.plugin.pack.dev.DevConfig; +import com.gitee.starblues.plugin.pack.dev.DevRepackager; +import com.gitee.starblues.plugin.pack.utils.CommonUtils; +import com.gitee.starblues.plugin.pack.utils.PackageZip; +import com.gitee.starblues.utils.FilesUtils; +import com.gitee.starblues.utils.ObjectUtils; +import org.apache.commons.compress.archivers.ArchiveOutputStream; +import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import static com.gitee.starblues.common.PackageStructure.*; + +/** + * zip 打包 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public class ZipProdRepackager extends DevRepackager { + + + protected final ProdConfig prodConfig; + + protected PackageZip packageZip; + + public ZipProdRepackager(RepackageMojo repackageMojo, ProdConfig prodConfig) { + super(repackageMojo); + this.prodConfig = prodConfig; + } + + @Override + public void repackage() throws MojoExecutionException, MojoFailureException { + try { + packageZip = getPackageZip(); + super.repackage(); + resolveClasses(); + resolveResourcesDefine(); + String rootDir = getRootDir(); + try { + FileUtils.deleteDirectory(new File(rootDir)); + } catch (IOException e) { + // 忽略 + } + logSuccess(); + } catch (Exception e){ + repackageMojo.getLog().error(e.getMessage(), e); + throw new MojoFailureException(e); + } finally { + if(packageZip != null){ + IOUtils.closeQuietly(packageZip); + } + } + } + + protected void logSuccess(){ + repackageMojo.getLog().info("Success package prod zip file : " + + packageZip.getFile().getPath()); + } + + protected PackageZip getPackageZip() throws Exception { + return new PackageZip(prodConfig.getOutputDirectory(), prodConfig.getFileName()); + } + + @Override + protected String getBasicRootDir(){ + File outputDirectory = repackageMojo.getOutputDirectory(); + return FilesUtils.joiningFilePath(outputDirectory.getPath(), UUID.randomUUID().toString()); + } + + @Override + protected Map getModuleDependencies(DevConfig devConfig) { + // 将项目中模块依赖置为空 + return Collections.emptyMap(); + } + + @Override + protected String getPluginPath() { + return CLASSES_NAME + SEPARATOR; + } + + @Override + protected boolean filterArtifact(Artifact artifact) { + return Constant.scopeFilter(artifact.getScope()); + } + + protected void resolveClasses() throws Exception { + String buildDir = repackageMojo.getProject().getBuild().getOutputDirectory(); + packageZip.copyDirToPackage(new File(buildDir), null); + } + + @Override + protected Manifest getManifest() throws Exception { + Manifest manifest = super.getManifest(); + Attributes attributes = manifest.getMainAttributes(); + attributes.putValue(ManifestKey.PLUGIN_META_PATH, PROD_PLUGIN_META_PATH); + attributes.putValue(ManifestKey.PLUGIN_PACKAGE_TYPE, PackageType.PLUGIN_PACKAGE_TYPE_ZIP); + return manifest; + } + + @Override + protected Properties createPluginMetaInfo() throws Exception { + Properties properties = super.createPluginMetaInfo(); + properties.put(PluginDescriptorKey.PLUGIN_RESOURCES_CONFIG, PROD_RESOURCES_DEFINE_PATH); + properties.put(PluginDescriptorKey.PLUGIN_LIB_DIR, PROD_LIB_PATH); + return properties; + } + + @Override + protected void writeManifest(Manifest manifest) throws Exception { + packageZip.writeManifest(manifest); + } + + @Override + protected String writePluginMetaInfo(Properties properties) throws Exception { + packageZip.write(PROD_PLUGIN_META_PATH, outputStream->{ + properties.store(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8), + Constant.PLUGIN_METE_COMMENTS); + }); + return PROD_PLUGIN_META_PATH; + } + + protected void resolveResourcesDefine() throws Exception{ + Set dependencyIndexNames = resolveDependencies(); + StringBuilder content = new StringBuilder(); + content.append(RESOURCES_DEFINE_DEPENDENCIES).append("\n"); + for (String dependencyIndexName : dependencyIndexNames) { + content.append(dependencyIndexName).append("\n"); + } + String loadMainResources = super.getLoadMainResources(); + if(!ObjectUtils.isEmpty(loadMainResources)){ + content.append(loadMainResources).append("\n"); + } + final byte[] bytes = content.toString().getBytes(StandardCharsets.UTF_8); + try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes)){ + packageZip.putInputStreamEntry(PROD_RESOURCES_DEFINE_PATH, byteArrayInputStream); + } + } + + protected Set resolveDependencies() throws Exception { + Set dependencies = repackageMojo.getFilterDependencies(); + String libDirEntryName = createLibEntry(); + Set dependencyIndexNames = new LinkedHashSet<>(dependencies.size()); + for (Artifact artifact : dependencies) { + if(filterArtifact(artifact)){ + continue; + } + File artifactFile = artifact.getFile(); + packageZip.writeDependency(artifactFile, libDirEntryName); + // fix 解决依赖前缀携带, lib 配置的前缀 + dependencyIndexNames.add(artifactFile.getName()); + } + return dependencyIndexNames; + } + + protected String createLibEntry() throws Exception { + String libDirEntryName = PROD_LIB_PATH; + packageZip.putDirEntry(libDirEntryName); + return libDirEntryName; + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/CommonUtils.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/CommonUtils.java new file mode 100644 index 00000000..f3dfdd6b --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/CommonUtils.java @@ -0,0 +1,100 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.utils; + +import com.gitee.starblues.plugin.pack.filter.Exclude; +import org.apache.commons.io.FileUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Objects; +import java.util.jar.JarFile; + +/** + * Object 工具类 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.1 + */ +public class CommonUtils { + + public final static String PLUGIN_FRAMEWORK_GROUP_ID = "com.gitee.starblues"; + public final static String PLUGIN_FRAMEWORK_ARTIFACT_ID = "spring-brick"; + + public final static String PLUGIN_FRAMEWORK_LOADER_ARTIFACT_ID = "spring-brick-loader"; + + public static final String PATTERN = "yyyy-MM-dd HH:mm:ss"; + public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(PATTERN); + + private CommonUtils(){} + + public static Exclude getPluginFrameworkExclude(){ + return Exclude.get(PLUGIN_FRAMEWORK_GROUP_ID, PLUGIN_FRAMEWORK_ARTIFACT_ID); + } + + public static boolean isPluginFramework(Artifact artifact){ + return Objects.equals(artifact.getGroupId(), PLUGIN_FRAMEWORK_GROUP_ID) + && Objects.equals(artifact.getArtifactId(), PLUGIN_FRAMEWORK_ARTIFACT_ID); + } + + public static boolean isPluginFrameworkLoader(Artifact artifact){ + return Objects.equals(artifact.getGroupId(), PLUGIN_FRAMEWORK_GROUP_ID) + && Objects.equals(artifact.getArtifactId(), PLUGIN_FRAMEWORK_LOADER_ARTIFACT_ID); + } + + public static JarFile getSourceJarFile(MavenProject mavenProject) { + File file = mavenProject.getArtifact().getFile(); + try { + return new JarFile(file); + } catch (Exception e){ + return null; + } + } + + public static String getDateTime() { + return DATE_TIME_FORMATTER.format(LocalDateTime.now()); + } + + public static void deleteFile(File rootFile) throws MojoFailureException { + try { + if(rootFile == null){ + return; + } + if(!rootFile.exists()){ + return; + } + if(rootFile.isFile()){ + FileUtils.delete(rootFile); + } else { + FileUtils.deleteDirectory(rootFile); + } + } catch (Exception e){ + e.printStackTrace(); + throw new MojoFailureException("Delete file '" + rootFile.getPath() + "' failure. " + e.getMessage()); + } + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageJar.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageJar.java new file mode 100644 index 00000000..7fa1c46e --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageJar.java @@ -0,0 +1,58 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.utils; + +import org.apache.commons.compress.archivers.ArchiveOutputStream; +import org.apache.commons.compress.archivers.jar.JarArchiveEntry; +import org.apache.commons.compress.archivers.jar.JarArchiveOutputStream; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; + +import java.io.File; +import java.io.FileOutputStream; +import java.nio.file.Files; + +/** + * jar 打包工具 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public class PackageJar extends PackageZip{ + public PackageJar(File file) throws Exception { + super(file); + } + + public PackageJar(String outputDirectory, String packageName) throws Exception { + super(outputDirectory, packageName); + } + + @Override + protected String getPackageFileSuffix() { + return "jar"; + } + + @Override + protected ArchiveOutputStream getOutputStream(File packFile) throws Exception { + return new JarArchiveOutputStream(Files.newOutputStream(packFile.toPath())); + } + + @Override + protected ZipArchiveEntry getArchiveEntry(String name) { + return new JarArchiveEntry(name); + } +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageZip.java b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageZip.java new file mode 100644 index 00000000..96df2df9 --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/PackageZip.java @@ -0,0 +1,249 @@ +/** + * Copyright [2019-Present] [starBlues] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.starblues.plugin.pack.utils; + +import com.gitee.starblues.common.PackageStructure; +import com.gitee.starblues.utils.FilesUtils; +import com.gitee.starblues.utils.ObjectUtils; +import org.apache.commons.compress.archivers.ArchiveOutputStream; +import org.apache.commons.compress.archivers.zip.UnixStat; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; +import org.apache.commons.compress.archivers.zip.ZipFile; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; + +import java.io.*; +import java.nio.file.Files; +import java.util.Enumeration; +import java.util.jar.Manifest; +import java.util.zip.CRC32; +import java.util.zip.ZipEntry; + +import static com.gitee.starblues.common.PackageStructure.*; + +/** + * zip 打包工具 + * + * @author starBlues + * @since 3.0.0 + * @version 3.0.0 + */ +public class PackageZip implements Closeable{ + + + private static final int UNIX_FILE_MODE = UnixStat.FILE_FLAG | UnixStat.DEFAULT_FILE_PERM; + + private static final int UNIX_DIR_MODE = UnixStat.DIR_FLAG | UnixStat.DEFAULT_DIR_PERM; + + private final File file; + private final ArchiveOutputStream outputStream; + + + public PackageZip(File file) throws Exception { + this.file = file; + this.outputStream = getOutputStream(file); + } + + public PackageZip(String outputDirectory, String packageName) throws Exception{ + String rootPath = FilesUtils.joiningFilePath(outputDirectory, packageName); + this.file = getPackageFile(rootPath); + this.outputStream = getOutputStream(file); + } + + public File getFile(){ + return file; + } + + public String getFileName(){ + return file.getName(); + } + + protected File getPackageFile(String rootPath) throws Exception { + String fileSuffix = getPackageFileSuffix(); + File file = new File(rootPath + "." + fileSuffix); + CommonUtils.deleteFile(file); + if(file.createNewFile()){ + return file; + } + throw new IOException("Create file '" + file.getPath() + "' failure."); + } + + protected String getPackageFileSuffix(){ + return "zip"; + } + + protected ArchiveOutputStream getOutputStream(File packFile) throws Exception { + return new ZipArchiveOutputStream(Files.newOutputStream(packFile.toPath())); + } + + public void copyDirToPackage(File rootDir, String packageDir) throws Exception { + if(packageDir == null){ + packageDir = rootDir.getName(); + } + if (rootDir.isDirectory()) { + File[] childFiles = rootDir.listFiles(); + if(ObjectUtils.isEmpty(packageDir)){ + packageDir = ""; + } else { + packageDir = packageDir + "/"; + putDirEntry(packageDir); + } + if(childFiles == null){ + return; + } + for (File childFile : childFiles) { + copyDirToPackage(childFile, packageDir + childFile.getName()); + } + } else { + putFileEntry(rootDir, packageDir); + } + } + + public void copyZipToPackage(File sourceZipFile) throws Exception { + if(sourceZipFile == null || !sourceZipFile.exists()){ + return; + } + try (ZipFile zipFile = new ZipFile(sourceZipFile)){ + Enumeration entries = zipFile.getEntries(); + while (entries.hasMoreElements()){ + ZipArchiveEntry zipArchiveEntry = entries.nextElement(); + String name = zipArchiveEntry.getName(); + if(name.contains(PackageStructure.META_INF_NAME)){ + // 不拷贝 mate-inf + continue; + } + if(zipArchiveEntry.isDirectory()){ + putDirEntry(name); + } else { + try (InputStream inputStream = zipFile.getInputStream(zipArchiveEntry)){ + putInputStreamEntry(name, inputStream); + } + } + } + } + } + + public String writeDependency(File dependencyFile, String libDirEntryName) throws Exception { + String indexName = libDirEntryName + dependencyFile.getName(); + ZipArchiveEntry entry = getArchiveEntry(indexName); + entry.setTime(System.currentTimeMillis()); + entry.setUnixMode(indexName.endsWith("/") ? UNIX_DIR_MODE : UNIX_FILE_MODE); + entry.getGeneralPurposeBit().useUTF8ForNames(true); + try(FileInputStream inputStream = new FileInputStream(dependencyFile)){ + new CrcAndSize(inputStream).setupStoredEntry(entry); + } + try (FileInputStream inputStream = new FileInputStream(dependencyFile)){ + outputStream.putArchiveEntry(entry); + IOUtils.copy(inputStream, outputStream); + outputStream.closeArchiveEntry(); + } + return indexName; + } + + public void putFileEntry(File destFile, String rootDir) throws Exception { + if(!destFile.exists()){ + throw new FileNotFoundException("Not found file : " + destFile.getPath()); + } + outputStream.putArchiveEntry(getArchiveEntry(rootDir)); + FileUtils.copyFile(destFile, outputStream); + outputStream.closeArchiveEntry(); + } + + public void putInputStreamEntry(String name, InputStream inputStream) throws Exception { + outputStream.putArchiveEntry(getArchiveEntry(name)); + IOUtils.copy(inputStream, outputStream); + outputStream.closeArchiveEntry(); + } + + public void write(String name, String content) throws Exception { + outputStream.putArchiveEntry(getArchiveEntry(name)); + IOUtils.write(content, outputStream, CHARSET_NAME); + outputStream.closeArchiveEntry(); + } + + public void write(String name, Writer writer) throws Exception { + outputStream.putArchiveEntry(getArchiveEntry(name)); + writer.write(outputStream); + outputStream.closeArchiveEntry(); + } + + public void write(String name, File file) throws Exception { + outputStream.putArchiveEntry(getArchiveEntry(name)); + try (FileInputStream fileInputStream = new FileInputStream(file)){ + IOUtils.copy(fileInputStream, outputStream); + outputStream.closeArchiveEntry(); + } + } + + public void writeManifest(Manifest manifest) throws Exception { + putDirEntry(META_INF_NAME + SEPARATOR); + write(PROD_MANIFEST_PATH, manifest::write); + } + + public void putDirEntry(String dir) throws IOException { + outputStream.putArchiveEntry(getArchiveEntry(dir)); + outputStream.closeArchiveEntry(); + } + + protected ZipArchiveEntry getArchiveEntry(String name){ + return new ZipArchiveEntry(name); + } + + + @Override + public void close() throws IOException { + outputStream.finish(); + outputStream.close(); + } + + private static class CrcAndSize { + + private static final int BUFFER_SIZE = 32 * 1024; + + private final CRC32 crc = new CRC32(); + + private long size; + + CrcAndSize(InputStream inputStream) throws IOException { + load(inputStream); + } + + private void load(InputStream inputStream) throws IOException { + byte[] buffer = new byte[BUFFER_SIZE]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + this.crc.update(buffer, 0, bytesRead); + this.size += bytesRead; + } + } + + void setupStoredEntry(ZipArchiveEntry entry) { + entry.setSize(this.size); + entry.setCompressedSize(this.size); + entry.setCrc(this.crc.getValue()); + entry.setMethod(ZipEntry.STORED); + } + + } + + @FunctionalInterface + public interface Writer{ + void write(ArchiveOutputStream outputStream) throws Exception; + } + +} diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/resources/META-INF/maven/com.gitee.starblues.springboot-plugin-maven-packager/plugin-help.xml b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/resources/META-INF/maven/com.gitee.starblues.springboot-plugin-maven-packager/plugin-help.xml new file mode 100644 index 00000000..d4fd840f --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/resources/META-INF/maven/com.gitee.starblues.springboot-plugin-maven-packager/plugin-help.xml @@ -0,0 +1,168 @@ + + + + Spring Boot Plugin Maven Packager + com.gitee.starblues + spring-brick-maven-packager + 3.1.3 + spring-brick-packager + false + true + + + repackage + 重新打包 + compile+runtime + false + true + false + false + false + true + package + com.gitee.starblues.plugin.pack.RepackageMojo + java + per-lookup + once-per-session + 3.0.0 + compile+runtime + true + + + project + org.apache.maven.project.MavenProject + 3.0.0 + true + false + 当前项目 + + + outputDirectory + java.io.File + 3.0.0 + true + true + 打包输出目录地址 + + + includes + java.util.List + 3.0.0 + false + true + 包含依赖定义 + + + excludes + java.util.List + 3.0.0 + false + true + 排除依赖定义 + + + skip + boolean + 3.0.0 + false + true + 跳过执行 + + + mode + string + 3.0.0 + true + true + 打包模式: dev/prod ,默认为dev + + + pluginInfo + com.gitee.starblues.plugin.pack.PluginInfo + 3.0.0 + false + true + 插件信息 + + + loadMainResourcePattern + com.gitee.starblues.plugin.pack.LoadMainResourcePattern + 3.0.0 + false + true + 从主程序加载资源的定义 + + + devConfig + com.gitee.starblues.plugin.pack.dev.DevConfig + 3.0.0 + false + true + dev打包模式配置 + + + prodConfig + com.gitee.starblues.plugin.pack.prod.ProdConfig + 3.0.0 + false + true + prod打包模式配置 + + + mainConfig + com.gitee.starblues.plugin.pack.main.MainConfig + 3.0.0 + false + true + main打包模式配置 + + + loadToMain + com.gitee.starblues.plugin.pack.LoadToMain + 3.0.0 + false + true + 加载到主程序的依赖 + + + encryptConfig + com.gitee.starblues.plugin.pack.encrypt.EncryptConfig + 3.0.1 + false + true + 加密配置 + + + includeSystemScope + boolean + 3.0.2 + false + true + 是否包含scope类型为system的依赖 + + + + + + + + + + ${springboot-plugin.includes} + ${springboot-plugin.excludes} + + + + + + + + + org.apache.maven.project.MavenProjectHelper + projectHelper + + + + + + \ No newline at end of file diff --git a/iot-module/iot-plugin/spring-brick-maven-packager/src/main/resources/META-INF/maven/plugin.xml b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/resources/META-INF/maven/plugin.xml new file mode 100644 index 00000000..d4fd840f --- /dev/null +++ b/iot-module/iot-plugin/spring-brick-maven-packager/src/main/resources/META-INF/maven/plugin.xml @@ -0,0 +1,168 @@ + + + + Spring Boot Plugin Maven Packager + com.gitee.starblues + spring-brick-maven-packager + 3.1.3 + spring-brick-packager + false + true + + + repackage + 重新打包 + compile+runtime + false + true + false + false + false + true + package + com.gitee.starblues.plugin.pack.RepackageMojo + java + per-lookup + once-per-session + 3.0.0 + compile+runtime + true + + + project + org.apache.maven.project.MavenProject + 3.0.0 + true + false + 当前项目 + + + outputDirectory + java.io.File + 3.0.0 + true + true + 打包输出目录地址 + + + includes + java.util.List + 3.0.0 + false + true + 包含依赖定义 + + + excludes + java.util.List + 3.0.0 + false + true + 排除依赖定义 + + + skip + boolean + 3.0.0 + false + true + 跳过执行 + + + mode + string + 3.0.0 + true + true + 打包模式: dev/prod ,默认为dev + + + pluginInfo + com.gitee.starblues.plugin.pack.PluginInfo + 3.0.0 + false + true + 插件信息 + + + loadMainResourcePattern + com.gitee.starblues.plugin.pack.LoadMainResourcePattern + 3.0.0 + false + true + 从主程序加载资源的定义 + + + devConfig + com.gitee.starblues.plugin.pack.dev.DevConfig + 3.0.0 + false + true + dev打包模式配置 + + + prodConfig + com.gitee.starblues.plugin.pack.prod.ProdConfig + 3.0.0 + false + true + prod打包模式配置 + + + mainConfig + com.gitee.starblues.plugin.pack.main.MainConfig + 3.0.0 + false + true + main打包模式配置 + + + loadToMain + com.gitee.starblues.plugin.pack.LoadToMain + 3.0.0 + false + true + 加载到主程序的依赖 + + + encryptConfig + com.gitee.starblues.plugin.pack.encrypt.EncryptConfig + 3.0.1 + false + true + 加密配置 + + + includeSystemScope + boolean + 3.0.2 + false + true + 是否包含scope类型为system的依赖 + + + + + + + + + + ${springboot-plugin.includes} + ${springboot-plugin.excludes} + + + + + + + + + org.apache.maven.project.MavenProjectHelper + projectHelper + + + + + + \ No newline at end of file diff --git a/iot-module/iot-rule-engine/pom.xml b/iot-module/iot-rule-engine/pom.xml index a35105b9..6eecf69e 100644 --- a/iot-module/iot-rule-engine/pom.xml +++ b/iot-module/iot-rule-engine/pom.xml @@ -5,7 +5,7 @@ iot-module cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 diff --git a/iot-module/iot-screen/pom.xml b/iot-module/iot-screen/pom.xml index 70fb8315..19e36cbf 100644 --- a/iot-module/iot-screen/pom.xml +++ b/iot-module/iot-screen/pom.xml @@ -5,7 +5,7 @@ iot-module cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 diff --git a/iot-module/iot-system/pom.xml b/iot-module/iot-system/pom.xml index e9918c9a..bcdacdc5 100644 --- a/iot-module/iot-system/pom.xml +++ b/iot-module/iot-system/pom.xml @@ -5,7 +5,7 @@ iot-module cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 diff --git a/iot-module/pom.xml b/iot-module/pom.xml index b642a676..60f44b1b 100644 --- a/iot-module/pom.xml +++ b/iot-module/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 diff --git a/iot-starter/pom.xml b/iot-starter/pom.xml index d4287ade..0e0261f5 100644 --- a/iot-starter/pom.xml +++ b/iot-starter/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 diff --git a/iot-starter/src/main/resources/application.yml b/iot-starter/src/main/resources/application.yml index 6df068cb..427e3d35 100644 --- a/iot-starter/src/main/resources/application.yml +++ b/iot-starter/src/main/resources/application.yml @@ -93,22 +93,31 @@ spring: # ============mysql配置结束============>> #<<================es时序数据配置开始=============== - elasticsearch: - rest: - #使用内置es的配置 - #uris: http://elasticsearch:9200 - uris: http://127.0.0.1:9200 - username: - password: - connection-timeout: 10s +# 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 +# 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时序数据库配置开始============>> + + + #<<===========iotdb时序数据库配置开始============ + iotdb-datasource: + host: 127.0.0.1 + port: 6667 + username: root + password: root #===========tdengine时序数据库配置开始============>> redis: @@ -195,6 +204,5 @@ weixin: plugin: runMode: prod mainPackage: cc.iotkit - # 如果配置是 windows 下路径, mac、linux 自行修改 pluginPath: - ./data/plugins diff --git a/iot-test-tool/iot-virtual-device/pom.xml b/iot-test-tool/iot-virtual-device/pom.xml index b07f551b..6f5835d2 100644 --- a/iot-test-tool/iot-virtual-device/pom.xml +++ b/iot-test-tool/iot-virtual-device/pom.xml @@ -5,7 +5,7 @@ iot-test-tool cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 diff --git a/iot-test-tool/pom.xml b/iot-test-tool/pom.xml index 0dbf6187..82b9aa03 100755 --- a/iot-test-tool/pom.xml +++ b/iot-test-tool/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT 4.0.0 pom diff --git a/pom.xml b/pom.xml index c9168801..7bb1f39d 100755 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ cc.iotkit iotkit-parent - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT ${project.artifactId} 奇特物联是一个开源的物联网基础开发平台,提供了物联网及相关业务开发的常见基础功能, 能帮助你快速搭建自己的物联网相关业务平台。 @@ -29,7 +29,7 @@ 11 - 1.0.0 + 1.0.1 2.7.11 4.2.2 1.34.0