diff --git a/README_zh.md b/README_zh.md index 0d7e1192a791ded73416e990515ec7234b3238eb..90a58e98f6d2bf0846219f0b1a2659ba3875eeaa 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,4 +1,4 @@ -# springboot插件式开发框架 +# Spring-Boot插件式开发框架 - 全新`3.0.0`版本上线啦,为动态扩展系统而生的框架。 diff --git a/pom.xml b/pom.xml index 4847d111bc7296a71288fe4cc467b8cd5b75f303..6e6cdb651d900511884a6b97dbc72f5af3d71e10 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ com.gitee.starblues spring-brick-parent pom - 3.0.0 + 3.0.1 spring-brick-common @@ -28,6 +28,9 @@ UTF-8 3.8.1 + 1.18.20 + 2.0.9 + 3.1.0 3.1.0 3.1.0 @@ -70,6 +73,30 @@ + + + org.projectlombok + lombok + ${lombok.version} + provided + true + + + + org.powermock + powermock-api-mockito2 + test + ${powermock.version} + + + + org.powermock + powermock-module-junit4 + test + ${powermock.version} + + + @@ -133,7 +160,6 @@ - dev diff --git a/spring-brick-bootstrap/pom.xml b/spring-brick-bootstrap/pom.xml index c5a750570d8a8765a23f58a32700c1297eb4cd84..5e1c5c6a4ce96373b51e0f22ce232fe3f82cddc9 100644 --- a/spring-brick-bootstrap/pom.xml +++ b/spring-brick-bootstrap/pom.xml @@ -7,19 +7,15 @@ spring-brick-parent com.gitee.starblues - 3.0.0 + 3.0.1 spring-brick-bootstrap jar - 插件引导模块 + 插件启动引导模块 - 1.8 - UTF-8 - 3.8.1 - 1.9.6 1.7.7 2.11.3 @@ -36,11 +32,13 @@ aspectjweaver ${aspectj.version} + org.slf4j slf4j-api ${slf4j.version} + com.gitee.starblues spring-brick @@ -48,11 +46,13 @@ provided true + com.fasterxml.jackson.core jackson-databind ${jackson.version} + org.springframework.boot spring-boot @@ -60,6 +60,7 @@ provided true + org.springframework spring-webmvc @@ -67,6 +68,7 @@ provided true + org.springdoc springdoc-openapi-common @@ -74,6 +76,7 @@ provided true + javax.servlet javax.servlet-api diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/EmptyMainApplicationContext.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/EmptyMainApplicationContext.java index 53a55368e9971b990a1ed3c039d4ede5e69f721f..35eb69509929b109232c4e7d8ffe141ba52c343c 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/EmptyMainApplicationContext.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/EmptyMainApplicationContext.java @@ -18,12 +18,6 @@ package com.gitee.starblues.bootstrap; import com.gitee.starblues.spring.MainApplicationContext; import com.gitee.starblues.spring.SpringBeanFactory; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.core.ResolvableType; - -import java.lang.annotation.Annotation; import java.util.Collections; import java.util.Map; import java.util.Set; @@ -31,7 +25,7 @@ import java.util.Set; /** * 空的MainApplicationContext实现 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class EmptyMainApplicationContext implements MainApplicationContext { @@ -51,4 +45,11 @@ public class EmptyMainApplicationContext implements MainApplicationContext { public Map> getConfigurableEnvironment() { return Collections.emptyMap(); } + + @Override + public ClassLoader getClassLoader() { + return EmptyMainApplicationContext.class.getClassLoader(); + } + + } diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginOneselfInteractive.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginOneselfInteractive.java index dfd07faeeb4f2456ea7d0db2b670b93d27474ced..2723562b3900b353b4b1356d7fc15c7dda37774a 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginOneselfInteractive.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/PluginOneselfInteractive.java @@ -20,6 +20,7 @@ import com.gitee.starblues.common.PackageStructure; import com.gitee.starblues.core.descriptor.DevPluginDescriptorLoader; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.core.descriptor.PluginDescriptorLoader; +import com.gitee.starblues.core.descriptor.decrypt.EmptyPluginDescriptorDecrypt; import com.gitee.starblues.core.launcher.plugin.PluginInteractive; import com.gitee.starblues.integration.AutoIntegrationConfiguration; import com.gitee.starblues.integration.IntegrationConfiguration; @@ -80,7 +81,8 @@ public class PluginOneselfInteractive implements PluginInteractive { } private InsidePluginDescriptor createPluginDescriptor(){ - try (PluginDescriptorLoader pluginDescriptorLoader = new DevPluginDescriptorLoader()){ + EmptyPluginDescriptorDecrypt descriptorDecrypt = new EmptyPluginDescriptorDecrypt(); + try (PluginDescriptorLoader pluginDescriptorLoader = new DevPluginDescriptorLoader(descriptorDecrypt)){ Path classesPath = Paths.get(this.getClass().getResource("/").toURI()).getParent(); String metaInf = FilesUtils.joiningFilePath(classesPath.toString(), PackageStructure.META_INF_NAME); InsidePluginDescriptor pluginDescriptor = pluginDescriptorLoader.load(Paths.get(metaInf)); diff --git a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/DefaultMainEnvironmentProvider.java b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/DefaultMainEnvironmentProvider.java index 8487d3664dd6c607272685cccc47dd56471c2aaf..f71a363c300da964609be23baf3ff280501803e7 100644 --- a/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/DefaultMainEnvironmentProvider.java +++ b/spring-brick-bootstrap/src/main/java/com/gitee/starblues/bootstrap/realize/DefaultMainEnvironmentProvider.java @@ -18,7 +18,9 @@ package com.gitee.starblues.bootstrap.realize; import com.gitee.starblues.loader.utils.ObjectUtils; import com.gitee.starblues.spring.MainApplicationContext; +import com.gitee.starblues.utils.MapValueGetter; +import java.util.Collections; import java.util.Map; import java.util.function.Function; @@ -54,57 +56,32 @@ public class DefaultMainEnvironmentProvider implements MainEnvironmentProvider{ @Override public String getString(String name) { - return getValue(name, String::valueOf); + return getMapValueGetter(name).getString(name); } @Override public Integer getInteger(String name) { - return getValue(name, value -> { - if(value instanceof Integer){ - return (Integer) value; - } - return Integer.parseInt(String.valueOf(value)); - }); + return getMapValueGetter(name).getInteger(name); } @Override public Long getLong(String name) { - return getValue(name, value -> { - if(value instanceof Long){ - return (Long) value; - } - return Long.parseLong(String.valueOf(value)); - }); + return getMapValueGetter(name).getLong(name); } @Override public Double getDouble(String name) { - return getValue(name, value -> { - if(value instanceof Double){ - return (Double) value; - } - return Double.parseDouble(String.valueOf(value)); - }); + return getMapValueGetter(name).getDouble(name); } @Override public Float getFloat(String name) { - return getValue(name, value -> { - if(value instanceof Float){ - return (Float) value; - } - return Float.parseFloat(String.valueOf(value)); - }); + return getMapValueGetter(name).getFloat(name); } @Override public Boolean getBoolean(String name) { - return getValue(name, value -> { - if(value instanceof Boolean){ - return (Boolean) value; - } - return Boolean.parseBoolean(String.valueOf(value)); - }); + return getMapValueGetter(name).getBoolean(name); } @Override @@ -112,12 +89,19 @@ public class DefaultMainEnvironmentProvider implements MainEnvironmentProvider{ return mainApplicationContext.getConfigurableEnvironment(); } - private T getValue(String name, Function function){ - Object value = getValue(name); - if(value == null){ - return null; + private MapValueGetter getMapValueGetter(String name) { + Map> configurableEnvironment = mainApplicationContext.getConfigurableEnvironment(); + if(ObjectUtils.isEmpty(configurableEnvironment)){ + return new MapValueGetter(Collections.emptyMap()); + } + for (Map.Entry> entry : configurableEnvironment.entrySet()) { + Map value = entry.getValue(); + if(value.containsKey(name)){ + return new MapValueGetter(value); + } } - return function.apply(value); + return new MapValueGetter(Collections.emptyMap()); } + } diff --git a/spring-brick-common/pom.xml b/spring-brick-common/pom.xml index 90be99fd61909125b5a3fd5b325a14af3153afbb..a0e3e5a5f1b8d3eaec38fda773810fca3ae42043 100644 --- a/spring-brick-common/pom.xml +++ b/spring-brick-common/pom.xml @@ -7,16 +7,11 @@ spring-brick-parent com.gitee.starblues - 3.0.0 + 3.0.1 spring-brick-common + 框架公共模块 jar - - 1.8 - UTF-8 - 3.8.1 - - \ No newline at end of file diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/common/cipher/AbstractPluginCipher.java b/spring-brick-common/src/main/java/com/gitee/starblues/common/cipher/AbstractPluginCipher.java new file mode 100644 index 0000000000000000000000000000000000000000..a2bd2063154f3baa761e45e4b375702643baf98d --- /dev/null +++ b/spring-brick-common/src/main/java/com/gitee/starblues/common/cipher/AbstractPluginCipher.java @@ -0,0 +1,57 @@ +package com.gitee.starblues.common.cipher; + +import com.gitee.starblues.utils.MapValueGetter; +import com.gitee.starblues.utils.ObjectUtils; + +import java.util.Map; + +/** + * 抽象的插件解密 + * + * @author starBlues + * @version 3.0.1 + */ +public abstract class AbstractPluginCipher implements PluginCipher{ + + protected MapValueGetter parameters; + + protected AbstractPluginCipher(){ + } + + public void initParams(Map params){ + parameters = new MapValueGetter(params); + } + + @Override + public String encrypt(String sourceStr) throws Exception { + if(ObjectUtils.isEmpty(sourceStr)){ + return ""; + } + return encryptImpl(sourceStr); + } + + /** + * 加密实现 + * @param sourceStr 原始字符串 + * @return 加密后的字节 + * @throws Exception 加密异常 + */ + protected abstract String encryptImpl(String sourceStr) throws Exception; + + + @Override + public String decrypt(String cryptoStr) throws Exception { + if(ObjectUtils.isEmpty(cryptoStr)){ + return ""; + } + return decryptImpl(cryptoStr); + } + + /** + * 解密实现 + * @param cryptoStr 解密字符串 + * @return 解密后的字符 + * @throws Exception 解密异常 + */ + protected abstract String decryptImpl(String cryptoStr) throws Exception; +} diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/common/cipher/AesPluginCipher.java b/spring-brick-common/src/main/java/com/gitee/starblues/common/cipher/AesPluginCipher.java new file mode 100644 index 0000000000000000000000000000000000000000..3d1548973db88fcd28e66b113810c21ff26991a4 --- /dev/null +++ b/spring-brick-common/src/main/java/com/gitee/starblues/common/cipher/AesPluginCipher.java @@ -0,0 +1,82 @@ +/** + * Copyright [2019-2022] [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.common.cipher; + +import com.gitee.starblues.utils.Assert; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.util.Base64; + +/** + * AES 加密 + * + * @author starBlues + * @version 3.0.1 + */ +public class AesPluginCipher extends AbstractPluginCipher{ + + public final static String SECRET_KEY = "secretKey"; + + private static final String INSTANCE_KEY = "AES/ECB/PKCS5Padding"; + private static final String AES_KEY = "AES"; + + @Override + protected String encryptImpl(String sourceStr) throws Exception { + Key convertSecretKey = getKey(); + Cipher cipher = Cipher.getInstance(INSTANCE_KEY); + cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); + byte[] result = cipher.doFinal(sourceStr.getBytes(StandardCharsets.UTF_8)); + return Base64.getEncoder().encodeToString(result); + } + + @Override + protected String decryptImpl(String cryptoStr) throws Exception { + Key convertSecretKey = getKey(); + Cipher cipher = Cipher.getInstance(INSTANCE_KEY); + cipher.init(Cipher.DECRYPT_MODE, convertSecretKey); + byte[] decode = Base64.getDecoder().decode(cryptoStr); + byte[] result = cipher.doFinal(decode); + return new String(result, StandardCharsets.UTF_8); + } + + + private Key getKey() throws Exception{ + String secretKey = super.parameters.getString(SECRET_KEY); + Assert.isNotEmpty(secretKey, SECRET_KEY + " 不能为空"); + byte[] keyBytes = Base64.getDecoder().decode(secretKey); + return new SecretKeySpec(keyBytes, AES_KEY); + } + + /** + * 获取秘钥 + * @return 秘钥字符串 + * @throws NoSuchAlgorithmException NoSuchAlgorithmException + */ + public static String generateKey() throws Exception { + KeyGenerator keyGenerator = KeyGenerator.getInstance(AES_KEY); + keyGenerator.init(128); + Key secretKey = keyGenerator.generateKey(); + byte[] keyBytes = secretKey.getEncoded(); + return Base64.getEncoder().encodeToString(keyBytes); + } + +} diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/common/cipher/PluginCipher.java b/spring-brick-common/src/main/java/com/gitee/starblues/common/cipher/PluginCipher.java new file mode 100644 index 0000000000000000000000000000000000000000..257d09e58719142b2d2aab6d4591c078176fccc2 --- /dev/null +++ b/spring-brick-common/src/main/java/com/gitee/starblues/common/cipher/PluginCipher.java @@ -0,0 +1,44 @@ +/** + * Copyright [2019-2022] [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.common.cipher; + +/** + * 插件密码接口 + * + * @author starBlues + * @version 3.0.1 + */ +public interface PluginCipher { + + /** + * 加密 + * @param sourceStr 原始字符 + * @return 加密后的字节 + * @throws Exception 加密异常 + */ + String encrypt(String sourceStr) throws Exception; + + /** + * 解密 + * @param cryptoStr 加密的字符 + * @return 解密后的字符 + * @throws Exception 解密异常 + */ + String decrypt(String cryptoStr) throws Exception; + + +} diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/common/cipher/RsaPluginCipher.java b/spring-brick-common/src/main/java/com/gitee/starblues/common/cipher/RsaPluginCipher.java new file mode 100644 index 0000000000000000000000000000000000000000..26dbff2f9745394cc4a471bf10e8ff5ee44c823b --- /dev/null +++ b/spring-brick-common/src/main/java/com/gitee/starblues/common/cipher/RsaPluginCipher.java @@ -0,0 +1,106 @@ +/** + * Copyright [2019-2022] [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.common.cipher; + +import com.gitee.starblues.utils.Assert; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import javax.crypto.Cipher; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +/** + * 非对称插件加解密 + * + * @author starBlues + * @version 3.0.1 + */ +public class RsaPluginCipher extends AbstractPluginCipher{ + + public final static String PUBLIC_KEY = "publicKey"; + public final static String PRIVATE_KEY = "privateKey"; + + public RsaPluginCipher(){ + } + + @Override + protected String encryptImpl(String sourceStr) throws Exception { + String publicKey = super.parameters.getString(PUBLIC_KEY); + Assert.isNotEmpty(publicKey, PUBLIC_KEY + " 不能为空"); + byte[] decoded = Base64.getDecoder().decode(publicKey); + RSAPublicKey pubKey = (RSAPublicKey) KeyFactory + .getInstance("RSA") + .generatePublic(new X509EncodedKeySpec(decoded)); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, pubKey); + return Base64.getEncoder().encodeToString(cipher.doFinal(sourceStr.getBytes(StandardCharsets.UTF_8))); + } + + @Override + protected String decryptImpl(String cryptoStr) throws Exception { + String privateKey = super.parameters.getString(PRIVATE_KEY); + Assert.isNotEmpty(privateKey, PRIVATE_KEY + " 不能为空"); + byte[] inputByte = Base64.getDecoder().decode(cryptoStr.getBytes(StandardCharsets.UTF_8)); + byte[] decoded = Base64.getDecoder().decode(privateKey); + RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded)); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, priKey); + return new String(cipher.doFinal(inputByte)); + } + + /** + * 生成 512大小 密钥对 + * @return 密钥对对象 + * @throws NoSuchAlgorithmException 生成异常 + */ + public static RsaKey generateKey() throws NoSuchAlgorithmException { + return generateKey(512); + } + + /** + * 生成密钥对 + * @param keySize 密钥对大小 + * @return 密钥对对象 + * @throws NoSuchAlgorithmException 生成异常 + */ + public static RsaKey generateKey(Integer keySize) throws NoSuchAlgorithmException { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(keySize); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + + RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); + return new RsaKey( + Base64.getEncoder().encodeToString(rsaPublicKey.getEncoded()), + Base64.getEncoder().encodeToString(rsaPrivateKey.getEncoded()) + ); + } + + @AllArgsConstructor + @Getter + public static class RsaKey{ + private final String publicKey; + private final String privateKey; + } + +} diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/utils/MapValueGetter.java b/spring-brick-common/src/main/java/com/gitee/starblues/utils/MapValueGetter.java new file mode 100644 index 0000000000000000000000000000000000000000..191198e03a3c660833f162307f0c72950b610e26 --- /dev/null +++ b/spring-brick-common/src/main/java/com/gitee/starblues/utils/MapValueGetter.java @@ -0,0 +1,130 @@ +package com.gitee.starblues.utils; + +import java.util.Collections; +import java.util.Map; +import java.util.function.Function; + +/** + * map 值获取者工具类 + * + * @author starBlues + * @version 3.0.1 + */ +public class MapValueGetter { + + private final Map map; + + public MapValueGetter(Map map) { + if(map == null){ + this.map = Collections.emptyMap(); + } else { + this.map = map; + } + } + + /** + * 获取object + * @param key map key + * @return value + */ + public Object getObject(String key) { + return map.get(key); + } + + + /** + * 获取 String 类型值 + * @param key map key + * @return String value + */ + public String getString(String key) { + return getValue(key, String::valueOf); + } + + /** + * 获取 Integer 类型值 + * @param key map key + * @return Integer value + */ + public Integer getInteger(String key) { + return getValue(key, value -> { + if(value instanceof Integer){ + return (Integer) value; + } + return Integer.parseInt(String.valueOf(value)); + }); + } + + /** + * 获取 Long 类型值 + * @param key map key + * @return Long value + */ + public Long getLong(String key) { + return getValue(key, value -> { + if(value instanceof Long){ + return (Long) value; + } + return Long.parseLong(String.valueOf(value)); + }); + } + + /** + * 获取 Double 类型值 + * @param key map key + * @return Double value + */ + public Double getDouble(String key) { + return getValue(key, value -> { + if(value instanceof Double){ + return (Double) value; + } + return Double.parseDouble(String.valueOf(value)); + }); + } + + /** + * 获取 Float 类型值 + * @param key map key + * @return Float value + */ + public Float getFloat(String key) { + return getValue(key, value -> { + if(value instanceof Float){ + return (Float) value; + } + return Float.parseFloat(String.valueOf(value)); + }); + } + + /** + * 获取 Boolean 类型值 + * @param key map key + * @return Boolean value + */ + public Boolean getBoolean(String key) { + return getValue(key, value -> { + if(value instanceof Boolean){ + return (Boolean) value; + } + return Boolean.parseBoolean(String.valueOf(value)); + }); + } + + /** + * 获取值并根据自定义实现转换类型 + * @param key map key + * @param function 自定义类型转换 + * @param 转换后的类型泛型 + * @return 转换后的类型值 + */ + private T getValue(String key, Function function){ + Object value = getObject(key); + if(value == null){ + return null; + } + return function.apply(value); + } + + +} diff --git a/spring-brick-loader/pom.xml b/spring-brick-loader/pom.xml index 8159265ea799e8d748a4d58b16bfab6e58b57a71..8fc2cb2e2f300a787bc32672b253f99c7630e6de 100644 --- a/spring-brick-loader/pom.xml +++ b/spring-brick-loader/pom.xml @@ -5,12 +5,12 @@ spring-brick-parent com.gitee.starblues - 3.0.0 + 3.0.1 4.0.0 spring-brick-loader - + 加载插件模块 \ No newline at end of file diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/AbstractLauncher.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/AbstractLauncher.java index 573ce907e2dfd0a0deb2d1b4c91527c66e8cb91f..e1d1c35208cc2c21be3aeb45fa54f447b3872fb5 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/AbstractLauncher.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/launcher/AbstractLauncher.java @@ -27,17 +27,13 @@ public abstract class AbstractLauncher implements Launcher { public R run(String... args) throws Exception { ClassLoader classLoader = createClassLoader(args); Thread thread = Thread.currentThread(); - ClassLoader oldClassLoader = thread.getContextClassLoader(); - try { - thread.setContextClassLoader(classLoader); - return launch(classLoader, args); - } finally { - thread.setContextClassLoader(oldClassLoader); - } + thread.setContextClassLoader(classLoader); + return launch(classLoader, args); } /** * 创建classloader + * @param args 参数 * @return ClassLoader * @throws Exception 创建异常 */ diff --git a/spring-brick-maven-packager/pom.xml b/spring-brick-maven-packager/pom.xml index 0aebe4dc57a63dfc15963cc40a36572a9faae75c..1037304504d7c5bc91621fed7d3757c7a4eece2f 100644 --- a/spring-brick-maven-packager/pom.xml +++ b/spring-brick-maven-packager/pom.xml @@ -7,13 +7,13 @@ spring-brick-parent com.gitee.starblues - 3.0.0 + 3.0.1 spring-brick-maven-packager jar - 打包插件 + 用于打包主程序/插件模块 8 @@ -36,49 +36,50 @@ + com.gitee.starblues spring-brick-common ${project.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 - ${lombok.version} - provided - true - + junit junit ${junit.version} test + diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/RepackageMojo.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/RepackageMojo.java index 5166f795aba89e0c76abddd61a208bba275a9d68..0e6dbb7abc21448318d68870cf524987756ebfa5 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/RepackageMojo.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/RepackageMojo.java @@ -19,6 +19,7 @@ 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; @@ -33,6 +34,7 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -40,7 +42,7 @@ import java.util.Set; /** * 重新打包 mojo * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ @Mojo(name = "repackage", defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true, threadSafe = true, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, @@ -61,12 +63,20 @@ public class RepackageMojo extends AbstractPackagerMojo { @Parameter(property = "spring-brick-packager.mainLoad") private LoadToMain loadToMain; + @Parameter(property = "spring-brick-packager.encryptConfig") + private EncryptConfig encryptConfig; + private final Set loadToMainSet = new HashSet<>(); @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)){ @@ -102,4 +112,19 @@ public class RepackageMojo extends AbstractPackagerMojo { } } + /** + * 加密 + * @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/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesConfig.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..44cf434931c0a34835b1b78effc45bd74d524367 --- /dev/null +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesConfig.java @@ -0,0 +1,32 @@ +/** + * Copyright [2019-2022] [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 + * @version 3.0.1 + */ +@Data +public class AesConfig { + + private String secretKey; + +} diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesEncryptPlugin.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesEncryptPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..2201d3d492903a74fbd3878e8bda9f913030a203 --- /dev/null +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/AesEncryptPlugin.java @@ -0,0 +1,42 @@ +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 + * @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/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptConfig.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..8aa5b2233ab0b57b0aaeb294dd068eb7e5fa65fb --- /dev/null +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptConfig.java @@ -0,0 +1,33 @@ +/** + * Copyright [2019-2022] [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 + * @version 3.0.1 + */ +@Data +public class EncryptConfig { + + private RsaConfig rsa; + private AesConfig aes; + +} diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPlugin.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..b995f9d73d18cacc6e33e5d337f15dfdd6cc5b6c --- /dev/null +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPlugin.java @@ -0,0 +1,39 @@ +/** + * Copyright [2019-2022] [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 + * @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/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPluginFactory.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPluginFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..f8a2c5b41adf0b9e138024550f89a871f8ae017e --- /dev/null +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/EncryptPluginFactory.java @@ -0,0 +1,49 @@ +/** + * Copyright [2019-2022] [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 + * @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/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaConfig.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..18b7e9a1f943cc301108f2f8d4b91c812cfa785b --- /dev/null +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaConfig.java @@ -0,0 +1,32 @@ +/** + * Copyright [2019-2022] [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 + * @version 3.0.1 + */ +@Data +public class RsaConfig { + + private String publicKey; + +} diff --git a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaEncryptPlugin.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaEncryptPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..b8f4e5d6e04e9091b802db9ef5a911187df1b9e0 --- /dev/null +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/encrypt/RsaEncryptPlugin.java @@ -0,0 +1,56 @@ +/** + * Copyright [2019-2022] [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 + * @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/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/CommonUtils.java b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/CommonUtils.java index f9d722906ba44e311dc1e7600c489cd1782e14c5..87b282e2dbfa8d26b2eebb6c07048ffb41623d39 100644 --- a/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/CommonUtils.java +++ b/spring-brick-maven-packager/src/main/java/com/gitee/starblues/plugin/pack/utils/CommonUtils.java @@ -24,14 +24,14 @@ import java.util.Objects; /** * Object 工具类 * @author starBlues - * @version 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 = "springboot-plugin-framework"; + public final static String PLUGIN_FRAMEWORK_ARTIFACT_ID = "spring-brick"; - public final static String PLUGIN_FRAMEWORK_LOADER_ARTIFACT_ID = "springboot-plugin-framework-loader"; + public final static String PLUGIN_FRAMEWORK_LOADER_ARTIFACT_ID = "spring-brick-loader"; private CommonUtils(){} diff --git a/spring-brick-maven-packager/src/main/resources/META-INF/maven/com.gitee.starblues.springboot-plugin-maven-packager/plugin-help.xml b/spring-brick-maven-packager/src/main/resources/META-INF/maven/com.gitee.starblues.springboot-plugin-maven-packager/plugin-help.xml index b3fd6271d4fe96579d2303ea62cfdea7e0deda74..a0cff0ffe4330182164e4eca3c160e0e74be813e 100644 --- a/spring-brick-maven-packager/src/main/resources/META-INF/maven/com.gitee.starblues.springboot-plugin-maven-packager/plugin-help.xml +++ b/spring-brick-maven-packager/src/main/resources/META-INF/maven/com.gitee.starblues.springboot-plugin-maven-packager/plugin-help.xml @@ -6,7 +6,7 @@ Spring Boot Plugin Maven Packager com.gitee.starblues spring-brick-maven-packager - 3.0.0 + 3.0.1 spring-brick-packager false true @@ -133,6 +133,14 @@ true 加载到主程序的依赖 + + encryptConfig + com.gitee.starblues.plugin.pack.encrypt.EncryptConfig + 3.0.1 + false + true + 加密配置 + diff --git a/spring-brick-maven-packager/src/main/resources/META-INF/maven/plugin.xml b/spring-brick-maven-packager/src/main/resources/META-INF/maven/plugin.xml index b3fd6271d4fe96579d2303ea62cfdea7e0deda74..a0cff0ffe4330182164e4eca3c160e0e74be813e 100644 --- a/spring-brick-maven-packager/src/main/resources/META-INF/maven/plugin.xml +++ b/spring-brick-maven-packager/src/main/resources/META-INF/maven/plugin.xml @@ -6,7 +6,7 @@ Spring Boot Plugin Maven Packager com.gitee.starblues spring-brick-maven-packager - 3.0.0 + 3.0.1 spring-brick-packager false true @@ -133,6 +133,14 @@ true 加载到主程序的依赖 + + encryptConfig + com.gitee.starblues.plugin.pack.encrypt.EncryptConfig + 3.0.1 + false + true + 加密配置 + diff --git a/spring-brick/pom.xml b/spring-brick/pom.xml index e32cc26352fabe264d35cac840b23bc2f085fef3..385671a2241abbe5716da622f92d184f8713ecb2 100644 --- a/spring-brick/pom.xml +++ b/spring-brick/pom.xml @@ -7,13 +7,13 @@ spring-brick-parent com.gitee.starblues - 3.0.0 + 3.0.1 spring-brick jar - spring boot 插件式开发集成包 + 核心集成包, 用于框架集成 2.10.1 @@ -27,7 +27,6 @@ 1.5.2 4.0.1 0.9.0 - 1.18.20 4.11 @@ -37,26 +36,31 @@ spring-brick-common ${project.version} + com.gitee.starblues spring-brick-loader ${project.version} + org.slf4j slf4j-api ${slf4j.version} + commons-io commons-io ${commons-io.version} + com.github.zafarkhaja java-semver ${java-semver.version} + org.springframework.boot spring-boot @@ -64,6 +68,7 @@ provided true + org.springframework spring-webmvc @@ -71,6 +76,7 @@ provided true + org.thymeleaf thymeleaf-spring5 @@ -78,6 +84,7 @@ provided true + javax.servlet javax.servlet-api @@ -85,6 +92,7 @@ provided true + io.springfox springfox-spring-web @@ -92,6 +100,7 @@ provided true + org.springdoc springdoc-openapi-ui @@ -99,19 +108,6 @@ provided true - - org.projectlombok - lombok - ${lombok.version} - provided - true - - - junit - junit - ${junit.version} - test - \ No newline at end of file diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginManager.java b/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginManager.java index 50b3e555289776fdd2ffbb45608fa352a85e0b6e..4914bf62e34a43aa8906d1a966f3af5cc140ff82 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginManager.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginManager.java @@ -49,7 +49,7 @@ import java.util.stream.Collectors; /** * 抽象的插件管理者 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class DefaultPluginManager implements PluginManager{ @@ -117,7 +117,7 @@ public class DefaultPluginManager implements PluginManager{ @Override public synchronized List loadPlugins() { if(loaded.get()){ - throw new RuntimeException("已经加载过了插件, 不能在重复调用: loadPlugins"); + throw new PluginException("不能重复调用: loadPlugins"); } try { if(ObjectUtils.isEmpty(pluginRootDirs)){ @@ -126,18 +126,7 @@ public class DefaultPluginManager implements PluginManager{ } List scanPluginPaths = provider.getPluginScanner().scan(pluginRootDirs); if(ObjectUtils.isEmpty(scanPluginPaths)){ - StringBuilder warn = new StringBuilder("以下路径未发现插件: \n"); - for (int i = 0; i < pluginRootDirs.size(); i++) { - warn.append(i + 1).append(". ").append(pluginRootDirs.get(i)).append("\n"); - } - warn.append("请检查路径是否合适.\n"); - warn.append("请检查配置[plugin.runMode]是否合适.\n"); - if(provider.getRuntimeMode() == RuntimeMode.DEV){ - warn.append("请检查插件包是否编译.\n"); - } else { - warn.append("请检查插件是否合法.\n"); - } - log.warn(warn.toString()); + printOfNotFoundPlugins(); return Collections.emptyList(); } pluginListenerFactory = createPluginListenerFactory(); @@ -156,6 +145,9 @@ public class DefaultPluginManager implements PluginManager{ log.error("加载插件包失败: {}. {}", path, e.getMessage(), e); } } + if(pluginInfoMap.isEmpty()){ + printOfNotFoundPlugins(); + } return getSortPlugin(pluginInfoMap); } finally { loaded.set(true); @@ -228,8 +220,13 @@ public class DefaultPluginManager implements PluginManager{ @Override public synchronized void unLoad(String pluginId) { Assert.isNotNull(pluginId, "参数pluginId不能为空"); - PluginInsideInfo pluginInsideInfo = resolvedPlugins.remove(pluginId); + PluginInsideInfo pluginInsideInfo = resolvedPlugins.get(pluginId); + if(!resolvedPlugins.containsKey(pluginId)){ + throw new PluginException("没有发现插件: " + pluginId); + } + resolvedPlugins.remove(pluginId); pluginListenerFactory.unLoadSuccess(pluginInsideInfo.toPluginInfo()); + LogUtils.info(log, pluginInsideInfo.getPluginDescriptor(), "卸载成功"); } @Override @@ -302,7 +299,7 @@ public class DefaultPluginManager implements PluginManager{ } // 检查插件版本 PluginDescriptor upgradePluginDescriptor = upgradePlugin.getPluginDescriptor(); - checkVersion(oldPlugin.getPluginDescriptor().getPluginVersion(), upgradePluginDescriptor.getPluginVersion()); + checkVersion(oldPlugin.getPluginDescriptor(), upgradePluginDescriptor); if(oldPlugin.getPluginState() == PluginState.STARTED){ // 如果插件被启动, 则卸载旧的插件 uninstall(pluginId); @@ -316,7 +313,8 @@ public class DefaultPluginManager implements PluginManager{ log.info("更新插件[{}]成功", MsgUtils.getPluginUnique(upgradePluginDescriptor)); return upgradePlugin; } catch (Exception e){ - throw PluginException.getPluginException(e, ()-> new PluginException(upgradePluginDescriptor, "更新失败", e)); + throw PluginException.getPluginException(e, ()-> + new PluginException(upgradePluginDescriptor, "更新失败", e)); } } @@ -411,6 +409,8 @@ public class DefaultPluginManager implements PluginManager{ if(resolvedPlugins.containsKey(pluginId)){ throw new PluginException(pluginInsideInfo.getPluginDescriptor(), "已经被加载"); } + // 检查当前插件版本号是否合法 + provider.getVersionInspector().check(pluginInsideInfo.getPluginDescriptor().getPluginVersion()); resolvedPlugins.put(pluginId, pluginInsideInfo); LogUtils.info(log, pluginInsideInfo.getPluginDescriptor(), "加载成功"); return pluginInsideInfo; @@ -515,13 +515,22 @@ public class DefaultPluginManager implements PluginManager{ */ protected void start(PluginInsideInfo pluginInsideInfo) throws Exception{ Assert.isNotNull(pluginInsideInfo, "pluginInsideInfo 参数不能为空"); - String pluginId = pluginInsideInfo.getPluginId(); launcherChecker.checkCanStart(pluginInsideInfo); pluginInsideInfo.setPluginState(PluginState.STARTED); + startFinish(pluginInsideInfo); + } + + /** + * 启动完成后的操作 + * @param pluginInsideInfo pluginInsideInfo + */ + protected void startFinish(PluginInsideInfo pluginInsideInfo){ + String pluginId = pluginInsideInfo.getPluginId(); startedPlugins.put(pluginId, pluginInsideInfo); resolvedPlugins.remove(pluginId); } + /** * 统一停止插件操作 * @param pluginInsideInfo PluginInsideInfo @@ -529,8 +538,16 @@ public class DefaultPluginManager implements PluginManager{ */ protected void stop(PluginInsideInfo pluginInsideInfo) throws Exception{ launcherChecker.checkCanStop(pluginInsideInfo); - String pluginId = pluginInsideInfo.getPluginId(); pluginInsideInfo.setPluginState(PluginState.STOPPED); + stopFinish(pluginInsideInfo); + } + + /** + * 停止完成操作 + * @param pluginInsideInfo pluginInsideInfo + */ + protected void stopFinish(PluginInsideInfo pluginInsideInfo){ + String pluginId = pluginInsideInfo.getPluginId(); resolvedPlugins.put(pluginId, pluginInsideInfo); startedPlugins.remove(pluginId); } @@ -541,6 +558,9 @@ public class DefaultPluginManager implements PluginManager{ * @return 排序的插件信息 */ protected List getSortPlugin(Map pluginInfos){ + if(ObjectUtils.isEmpty(pluginInfos)){ + return Collections.emptyList(); + } if (ObjectUtils.isEmpty(sortedPluginIds)) { return new ArrayList<>(pluginInfos.values()); } @@ -583,14 +603,15 @@ public class DefaultPluginManager implements PluginManager{ /** * 检查比较插件版本 - * @param oldPluginVersion 旧插件版本 - * @param newPluginVersion 新插件版本 + * @param oldPlugin 旧插件信息 + * @param newPlugin 新插件信息 */ - protected void checkVersion(String oldPluginVersion, String newPluginVersion){ - int compareVersion = provider.getVersionInspector().compareTo(oldPluginVersion, newPluginVersion); - if(compareVersion <= 0){ - throw new PluginException("插件包版本[" + newPluginVersion + "]必须大于:" - + oldPluginVersion); + protected void checkVersion(PluginDescriptor oldPlugin, PluginDescriptor newPlugin){ + int compareVersion = provider.getVersionInspector().compareTo(oldPlugin.getPluginVersion(), + newPlugin.getPluginVersion()); + if(compareVersion >= 0){ + throw new PluginException("新插件包版本[" + MsgUtils.getPluginUnique(newPlugin) + "]必须大于" + + "旧插件版本[" + MsgUtils.getPluginUnique(oldPlugin) + "]"); } } @@ -607,5 +628,28 @@ public class DefaultPluginManager implements PluginManager{ } } + /** + * 没有扫描到插件时的日志打印 + */ + private void printOfNotFoundPlugins(){ + StringBuilder warn = new StringBuilder(); + warn.append("以下路径未发现插件: \n"); + if(pluginRootDirs.size() == 1){ + warn.append(pluginRootDirs.get(0)).append("\n"); + } else { + for (int i = 0; i < pluginRootDirs.size(); i++) { + warn.append(i + 1).append(". ").append(pluginRootDirs.get(i)).append("\n"); + } + } + warn.append("请检查路径是否合适.\n"); + warn.append("请检查配置[plugin.runMode]是否合适.\n"); + if(provider.getRuntimeMode() == RuntimeMode.DEV){ + warn.append("请检查插件包是否编译.\n"); + } else { + warn.append("请检查插件是否合法.\n"); + } + log.warn(warn.toString()); + } + } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/DefaultRealizeProvider.java b/spring-brick/src/main/java/com/gitee/starblues/core/DefaultRealizeProvider.java index 758d531012a2f564b8822e4cede173f99ca02c2a..d06e538fae4dd14b4277d78f2e2554bce57c3ef9 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/DefaultRealizeProvider.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/DefaultRealizeProvider.java @@ -34,8 +34,10 @@ import com.gitee.starblues.utils.Assert; import org.springframework.context.ApplicationContext; /** + * 默认的RealizeProvider实现 + * * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class DefaultRealizeProvider implements RealizeProvider { @@ -63,7 +65,7 @@ public class DefaultRealizeProvider implements RealizeProvider { } setPluginScanner(basePluginScanner); setPluginBasicChecker(new ComposePluginBasicChecker(applicationContext)); - setPluginDescriptorLoader(new ComposeDescriptorLoader(pluginBasicChecker)); + setPluginDescriptorLoader(new ComposeDescriptorLoader(applicationContext, pluginBasicChecker)); setVersionInspector(new SemverVersionInspector()); } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java b/spring-brick/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java index 432fcf62d4c2491517c7f42f5ffe67eea0441b3d..d9b9b907fd185d58c7784b2a7bc0e3db50ead2e8 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java @@ -43,7 +43,7 @@ import java.util.concurrent.ConcurrentHashMap; /** * 可引导启动的插件管理者 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class PluginLauncherManager extends DefaultPluginManager{ @@ -89,7 +89,7 @@ public class PluginLauncherManager extends DefaultPluginManager{ @Override protected void start(PluginInsideInfo pluginInsideInfo) throws Exception { - super.start(pluginInsideInfo); + launcherChecker.checkCanStart(pluginInsideInfo); try { InsidePluginDescriptor pluginDescriptor = pluginInsideInfo.getPluginDescriptor(); PluginInteractive pluginInteractive = new DefaultPluginInteractive(pluginDescriptor, @@ -98,6 +98,8 @@ public class PluginLauncherManager extends DefaultPluginManager{ SpringPluginHook springPluginHook = pluginLauncher.run(); RegistryPluginInfo registryPluginInfo = new RegistryPluginInfo(pluginDescriptor, springPluginHook); registryInfo.put(pluginDescriptor.getPluginId(), registryPluginInfo); + pluginInsideInfo.setPluginState(PluginState.STARTED); + super.startFinish(pluginInsideInfo); } catch (Exception e){ // 启动失败, 进行停止 pluginInsideInfo.setPluginState(PluginState.STARTED_FAILURE); @@ -126,6 +128,7 @@ public class PluginLauncherManager extends DefaultPluginManager{ } } + static class RegistryPluginInfo{ private final PluginDescriptor descriptor; private final SpringPluginHook springPluginHook; diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/checker/DefaultPluginLauncherChecker.java b/spring-brick/src/main/java/com/gitee/starblues/core/checker/DefaultPluginLauncherChecker.java index d93de10c0a3a245f3d1fd50419b2cfebc16441b6..052b74a898356e5a611e61442d2093d435a27ac4 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/checker/DefaultPluginLauncherChecker.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/checker/DefaultPluginLauncherChecker.java @@ -20,14 +20,18 @@ import com.gitee.starblues.common.Constants; import com.gitee.starblues.core.PluginInfo; import com.gitee.starblues.core.PluginState; import com.gitee.starblues.core.RealizeProvider; +import com.gitee.starblues.core.descriptor.PluginDescriptor; import com.gitee.starblues.core.exception.PluginDisabledException; import com.gitee.starblues.core.exception.PluginException; import com.gitee.starblues.integration.IntegrationConfiguration; +import com.gitee.starblues.utils.MsgUtils; import com.gitee.starblues.utils.ObjectUtils; /** + * 默认插件启动检查者 + * * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class DefaultPluginLauncherChecker implements PluginLauncherChecker { @@ -75,12 +79,15 @@ public class DefaultPluginLauncherChecker implements PluginLauncherChecker { String requires = pluginInfo.getPluginDescriptor().getRequires(); boolean exactVersion = configuration.exactVersion(); int compareVersion = realizeProvider.getVersionInspector().compareTo(requires, version); + PluginDescriptor descriptor = pluginInfo.getPluginDescriptor(); if(exactVersion && compareVersion != 0){ - String error = "需要安装到[" + requires + "]版本的主程序, 但当前主程序版本为[" + version + "]"; + String error = "插件[" + MsgUtils.getPluginUnique(descriptor) + "]" + + "只能安装到[" + requires + "]版本的主程序, 但当前主程序版本为[" + version + "]"; throw new PluginException(pluginInfo.getPluginDescriptor(), error); } if(compareVersion > 0){ - String error = "需要安装到小于等于[" + requires + "]版本的主程序, 但当前主程序版本为[" + version + "]"; + String error = "插件[" + MsgUtils.getPluginUnique(descriptor) + "]" + + "只能安装到小于等于[" + requires + "]版本的主程序, 但当前主程序版本为[" + version + "]"; throw new PluginException(pluginInfo.getPluginDescriptor(), error); } } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/AbstractPluginDescriptorLoader.java b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/AbstractPluginDescriptorLoader.java index 14b11d814e552c2e2672e35bf0be60a04bc5fd39..40f62dc8c2ee39a946434a00689f46d73f2c9767 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/AbstractPluginDescriptorLoader.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/AbstractPluginDescriptorLoader.java @@ -17,13 +17,17 @@ package com.gitee.starblues.core.descriptor; -import com.gitee.starblues.common.*; +import com.gitee.starblues.common.AbstractDependencyPlugin; +import com.gitee.starblues.common.Constants; +import com.gitee.starblues.common.DependencyPlugin; +import com.gitee.starblues.core.descriptor.decrypt.PluginDescriptorDecrypt; +import com.gitee.starblues.core.exception.PluginDecryptException; import com.gitee.starblues.core.exception.PluginException; import com.gitee.starblues.utils.FilesUtils; -import com.gitee.starblues.utils.PropertiesUtils; import com.gitee.starblues.utils.ObjectUtils; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,34 +39,42 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; -import java.util.jar.Attributes; -import java.util.jar.Manifest; -import static com.gitee.starblues.common.PackageStructure.MANIFEST; import static com.gitee.starblues.common.PluginDescriptorKey.*; import static com.gitee.starblues.utils.PropertiesUtils.getValue; /** * 抽象的 PluginDescriptorLoader * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ +@Slf4j public abstract class AbstractPluginDescriptorLoader implements PluginDescriptorLoader{ private final Logger logger = LoggerFactory.getLogger(this.getClass()); + protected final PluginDescriptorDecrypt pluginDescriptorDecrypt; + + protected AbstractPluginDescriptorLoader(PluginDescriptorDecrypt pluginDescriptorDecrypt) { + this.pluginDescriptorDecrypt = pluginDescriptorDecrypt; + } @Override public InsidePluginDescriptor load(Path location) throws PluginException { PluginMeta pluginMeta = null; try { pluginMeta = getPluginMetaInfo(location); - if(pluginMeta == null || pluginMeta.getPluginMetaInfo() == null){ + if(pluginMeta == null || pluginMeta.getProperties() == null){ logger.debug("路径[{}]没有发现插件配置信息", location); return null; } return create(pluginMeta, location); } catch (Exception e) { + if(e instanceof PluginDecryptException){ + logger.error(e.getMessage(), e); + } else { + logger.debug(e.getMessage(), e); + } return null; } } @@ -81,7 +93,7 @@ public abstract class AbstractPluginDescriptorLoader implements PluginDescriptor protected abstract PluginMeta getPluginMetaInfo(Path location) throws Exception; protected DefaultInsidePluginDescriptor create(PluginMeta pluginMeta, Path path) throws Exception{ - Properties properties = pluginMeta.getPluginMetaInfo(); + Properties properties = pluginMeta.getProperties(); DefaultInsidePluginDescriptor descriptor = new DefaultInsidePluginDescriptor( getValue(properties, PLUGIN_ID), getValue(properties, PLUGIN_VERSION), @@ -161,29 +173,20 @@ public abstract class AbstractPluginDescriptorLoader implements PluginDescriptor return pluginLibInfos; } - protected Manifest getManifest(InputStream inputStream) throws Exception{ - Manifest manifest = new Manifest(); - try { - manifest.read(inputStream); - return manifest; - } finally { - inputStream.close(); - } - } - - protected Properties getProperties(InputStream inputStream) throws Exception{ + protected Properties getDecryptProperties(InputStream inputStream) throws Exception{ Properties properties = new Properties(); try (InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);){ properties.load(reader); - return properties; } + String pluginId = getValue(properties, PLUGIN_ID); + return pluginDescriptorDecrypt.decrypt(pluginId, properties); } @AllArgsConstructor @Getter public static class PluginMeta{ private final String packageType; - private final Properties pluginMetaInfo; + private final Properties properties; } } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ComposeDescriptorLoader.java b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ComposeDescriptorLoader.java index 475815e0df8d3615ab9ffcca814e6bd0c49ee9a6..669b4f3d1c67b18761728707b34008e78a22572b 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ComposeDescriptorLoader.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ComposeDescriptorLoader.java @@ -17,7 +17,11 @@ package com.gitee.starblues.core.descriptor; import com.gitee.starblues.core.checker.PluginBasicChecker; +import com.gitee.starblues.core.descriptor.decrypt.EmptyPluginDescriptorDecrypt; +import com.gitee.starblues.core.descriptor.decrypt.PluginDescriptorDecrypt; import com.gitee.starblues.core.exception.PluginException; +import com.gitee.starblues.utils.SpringBeanUtils; +import org.springframework.context.ApplicationContext; import java.nio.file.Path; import java.util.ArrayList; @@ -26,24 +30,37 @@ import java.util.List; /** * 组合插件描述加载者 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class ComposeDescriptorLoader implements PluginDescriptorLoader{ private final List pluginDescriptorLoaders = new ArrayList<>(); - + + private final ApplicationContext applicationContext; private final PluginBasicChecker pluginChecker; - public ComposeDescriptorLoader(PluginBasicChecker pluginChecker) { + + public ComposeDescriptorLoader(ApplicationContext applicationContext, PluginBasicChecker pluginChecker) { + this.applicationContext = applicationContext; this.pluginChecker = pluginChecker; addDefaultLoader(); } protected void addDefaultLoader(){ - addLoader(new DevPluginDescriptorLoader()); - addLoader(new ProdPluginDescriptorLoader()); + PluginDescriptorDecrypt pluginDescriptorDecrypt = getPluginDescriptorDecrypt(applicationContext); + addLoader(new DevPluginDescriptorLoader(pluginDescriptorDecrypt)); + addLoader(new ProdPluginDescriptorLoader(pluginDescriptorDecrypt)); } + protected PluginDescriptorDecrypt getPluginDescriptorDecrypt(ApplicationContext applicationContext){ + PluginDescriptorDecrypt pluginDescriptorDecrypt = + SpringBeanUtils.getExistBean(applicationContext, PluginDescriptorDecrypt.class); + if(pluginDescriptorDecrypt != null){ + return pluginDescriptorDecrypt; + } else { + return new EmptyPluginDescriptorDecrypt(); + } + } public void addLoader(PluginDescriptorLoader descriptorLoader){ if(descriptorLoader != null){ diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/DevPluginDescriptorLoader.java b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/DevPluginDescriptorLoader.java index 3b94a9fbab69ab0814e09b8fb4d3b668d61b9fef..2d16ba9351fe9ff44c68c7d75fd4140312d7036c 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/DevPluginDescriptorLoader.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/DevPluginDescriptorLoader.java @@ -18,31 +18,40 @@ package com.gitee.starblues.core.descriptor; import com.gitee.starblues.common.PackageStructure; import com.gitee.starblues.common.PackageType; +import com.gitee.starblues.core.descriptor.decrypt.PluginDescriptorDecrypt; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Properties; -import java.util.jar.Manifest; /** * 开发环境 PluginDescriptorLoader 加载者 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ +@Slf4j public class DevPluginDescriptorLoader extends AbstractPluginDescriptorLoader{ + public DevPluginDescriptorLoader(PluginDescriptorDecrypt pluginDescriptorDecrypt) { + super(pluginDescriptorDecrypt); + } + @Override protected PluginMeta getPluginMetaInfo(Path location) throws Exception { String pluginMetaPath = location.toString() + File.separator + PackageStructure.PLUGIN_META_NAME; File file = new File(pluginMetaPath); if(!file.exists()){ + log.debug("Path: [{}] not exist.", location); return null; } Path path = Paths.get(pluginMetaPath); - Properties properties = super.getProperties(Files.newInputStream(path)); - if(properties.isEmpty()){ + Properties properties = super.getDecryptProperties(Files.newInputStream(path)); + if(properties == null || properties.isEmpty()){ + log.debug("Load plugin properties is empty from '{}'", path); return null; } return new PluginMeta(PackageType.PLUGIN_PACKAGE_TYPE_DEV, properties); diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdDirPluginDescriptorLoader.java b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdDirPluginDescriptorLoader.java index f4547abf777f270089e318813fdbb58229231cfd..8edea7c3893360d8e02ed3f37aaf0d334aae9f97 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdDirPluginDescriptorLoader.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdDirPluginDescriptorLoader.java @@ -17,12 +17,13 @@ package com.gitee.starblues.core.descriptor; import com.gitee.starblues.common.ManifestKey; -import com.gitee.starblues.common.PackageType; import com.gitee.starblues.common.PluginDescriptorKey; +import com.gitee.starblues.core.descriptor.decrypt.PluginDescriptorDecrypt; import com.gitee.starblues.utils.PropertiesUtils; import com.gitee.starblues.utils.FilesUtils; import com.gitee.starblues.utils.ObjectUtils; import org.apache.commons.io.FileUtils; +import org.springframework.context.ApplicationContext; import java.io.File; import java.io.FileInputStream; @@ -43,10 +44,14 @@ import static com.gitee.starblues.common.PackageStructure.*; * 生产环境目录式插件 PluginDescriptorLoader 加载者 * 解析生产的dir * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class ProdDirPluginDescriptorLoader extends AbstractPluginDescriptorLoader{ + public ProdDirPluginDescriptorLoader(PluginDescriptorDecrypt pluginDescriptorDecrypt) { + super(pluginDescriptorDecrypt); + } + @Override protected PluginMeta getPluginMetaInfo(Path location) throws Exception { File file = new File(FilesUtils.joiningFilePath(location.toString(), resolvePath(PROD_MANIFEST_PATH))); @@ -70,7 +75,7 @@ public class ProdDirPluginDescriptorLoader extends AbstractPluginDescriptorLoade if(!pluginMetaFile.exists()){ return null; } - Properties properties = super.getProperties(new FileInputStream(pluginMetaFile)); + Properties properties = super.getDecryptProperties(new FileInputStream(pluginMetaFile)); if(properties.isEmpty()){ return null; } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdPackagePluginDescriptorLoader.java b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdPackagePluginDescriptorLoader.java index 15896fcc53ecf285036d9df826ff166a06cf5a19..2226d50d054400bd9d339b26914ecb9566c4de41 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdPackagePluginDescriptorLoader.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdPackagePluginDescriptorLoader.java @@ -19,9 +19,11 @@ package com.gitee.starblues.core.descriptor; import com.gitee.starblues.common.ManifestKey; import com.gitee.starblues.common.PackageStructure; +import com.gitee.starblues.core.descriptor.decrypt.PluginDescriptorDecrypt; import com.gitee.starblues.utils.PropertiesUtils; import com.gitee.starblues.utils.ObjectUtils; import org.apache.commons.io.IOUtils; +import org.springframework.context.ApplicationContext; import java.io.InputStream; import java.nio.file.Path; @@ -39,13 +41,14 @@ import static com.gitee.starblues.common.PluginDescriptorKey.PLUGIN_RESOURCES_CO * 生产环境打包好的插件 PluginDescriptorLoader 加载者 * 解析 jar、zip * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class ProdPackagePluginDescriptorLoader extends AbstractPluginDescriptorLoader{ private PluginResourcesConfig pluginResourcesConfig; - public ProdPackagePluginDescriptorLoader() { + public ProdPackagePluginDescriptorLoader(PluginDescriptorDecrypt pluginDescriptorDecrypt) { + super(pluginDescriptorDecrypt); } @Override @@ -62,7 +65,7 @@ public class ProdPackagePluginDescriptorLoader extends AbstractPluginDescriptorL if(jarEntry == null){ return null; } - Properties properties = super.getProperties(jarFile.getInputStream(jarEntry)); + Properties properties = super.getDecryptProperties(jarFile.getInputStream(jarEntry)); if(properties.isEmpty()){ return null; } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdPluginDescriptorLoader.java b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdPluginDescriptorLoader.java index 41a0583e5f18a223402c212d794450e24f2529d7..17ba28f22c14792f59debdd7aa8cec2cc29f159f 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdPluginDescriptorLoader.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ProdPluginDescriptorLoader.java @@ -16,6 +16,7 @@ package com.gitee.starblues.core.descriptor; +import com.gitee.starblues.core.descriptor.decrypt.PluginDescriptorDecrypt; import com.gitee.starblues.core.exception.PluginException; import com.gitee.starblues.utils.ResourceUtils; import org.slf4j.Logger; @@ -26,7 +27,7 @@ import java.nio.file.Path; /** * 生产环境插件描述加载者 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class ProdPluginDescriptorLoader implements PluginDescriptorLoader{ @@ -34,14 +35,20 @@ public class ProdPluginDescriptorLoader implements PluginDescriptorLoader{ private PluginDescriptorLoader target; + private final PluginDescriptorDecrypt pluginDescriptorDecrypt; + + public ProdPluginDescriptorLoader(PluginDescriptorDecrypt pluginDescriptorDecrypt) { + this.pluginDescriptorDecrypt = pluginDescriptorDecrypt; + } + @Override public InsidePluginDescriptor load(Path location) throws PluginException { if(ResourceUtils.isJarFile(location)){ - target = new ProdPackagePluginDescriptorLoader(); + target = new ProdPackagePluginDescriptorLoader(pluginDescriptorDecrypt); } else if(ResourceUtils.isZipFile(location)){ - target = new ProdPackagePluginDescriptorLoader(); + target = new ProdPackagePluginDescriptorLoader(pluginDescriptorDecrypt); } else if(ResourceUtils.isDirFile(location)){ - target = new ProdDirPluginDescriptorLoader(); + target = new ProdDirPluginDescriptorLoader(pluginDescriptorDecrypt); } else { logger.warn("不能解析文件: {}", location); return null; diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/decrypt/DefaultPluginDescriptorDecrypt.java b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/decrypt/DefaultPluginDescriptorDecrypt.java new file mode 100644 index 0000000000000000000000000000000000000000..e273f583e3b4698a44059f33998913552de7c359 --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/decrypt/DefaultPluginDescriptorDecrypt.java @@ -0,0 +1,133 @@ +package com.gitee.starblues.core.descriptor.decrypt; + +import com.gitee.starblues.common.PluginDescriptorKey; +import com.gitee.starblues.common.cipher.AbstractPluginCipher; +import com.gitee.starblues.common.cipher.PluginCipher; +import com.gitee.starblues.core.exception.PluginDecryptException; +import com.gitee.starblues.core.exception.PluginException; +import com.gitee.starblues.integration.IntegrationConfiguration; +import com.gitee.starblues.integration.decrypt.DecryptConfiguration; +import com.gitee.starblues.integration.decrypt.DecryptPluginConfiguration; +import com.gitee.starblues.utils.ObjectUtils; +import com.gitee.starblues.utils.PropertiesUtils; +import org.springframework.context.ApplicationContext; +import org.springframework.util.ClassUtils; + +import java.util.*; + +/** + * 默认的 PluginDescriptorDecrypt + * + * @author starBlues + * @version 3.0.1 + */ +public class DefaultPluginDescriptorDecrypt implements PluginDescriptorDecrypt{ + + private final ApplicationContext applicationContext; + + private final DecryptConfiguration decryptConfig; + private final Map pluginDecryptConfig; + + public DefaultPluginDescriptorDecrypt(ApplicationContext applicationContext, + IntegrationConfiguration configuration) { + this.applicationContext = applicationContext; + + this.decryptConfig = configuration.decrypt(); + List plugins = decryptConfig.getPlugins(); + if(ObjectUtils.isEmpty(plugins)){ + this.pluginDecryptConfig = Collections.emptyMap(); + } else { + this.pluginDecryptConfig = new HashMap<>(plugins.size()); + for (DecryptPluginConfiguration plugin : plugins) { + pluginDecryptConfig.put(plugin.getPluginId(), plugin); + } + } + } + + @Override + public Properties decrypt(String pluginId, Properties properties) { + PluginCipher pluginCipher = getPluginCipher(pluginId); + if(pluginCipher == null){ + return properties; + } + try { + String bootstrapClass = PropertiesUtils.getValue(properties, PluginDescriptorKey.PLUGIN_BOOTSTRAP_CLASS); + String decrypt = pluginCipher.decrypt(bootstrapClass); + properties.setProperty(PluginDescriptorKey.PLUGIN_BOOTSTRAP_CLASS, decrypt); + return properties; + } catch (Exception e) { + throw new PluginDecryptException("插件[" + pluginId + "]解密失败. " + e.getMessage()); + } + } + + protected PluginCipher getPluginCipher(String pluginId){ + if(decryptConfig == null){ + return null; + } + Boolean enable = decryptConfig.getEnable(); + if(enable == null || !enable){ + // 没有启用 + return null; + } + Map props = decryptConfig.getProps(); + if(props == null){ + props = new HashMap<>(); + decryptConfig.setProps(props); + } + String className = decryptConfig.getClassName(); + if(ObjectUtils.isEmpty(pluginDecryptConfig)){ + // 没有配置具体插件的解密配置 + return getPluginCipherBean(className, props); + } + DecryptPluginConfiguration decryptPluginConfiguration = pluginDecryptConfig.get(pluginId); + if(decryptPluginConfiguration == null){ + // 当前插件没有配置解密配置, 说明不启用解密 + return null; + } + Map pluginParam = decryptPluginConfiguration.getProps(); + if(!ObjectUtils.isEmpty(pluginParam)){ + props.putAll(pluginParam); + } + return getPluginCipherBean(className, props); + } + + + protected PluginCipher getPluginCipherBean(String className, Map params){ + ClassLoader defaultClassLoader = ClassUtils.getDefaultClassLoader(); + try { + if(defaultClassLoader == null){ + defaultClassLoader = this.getClass().getClassLoader(); + } + Class aClass = defaultClassLoader.loadClass(className); + + String error = "解密实现者[" + className + "]没有继承 [" + AbstractPluginCipher.class.getName() + "]"; + + if(aClass.isAssignableFrom(AbstractPluginCipher.class)){ + throw new PluginDecryptException(error); + } + Object bean = getBean(aClass); + if(bean instanceof AbstractPluginCipher){ + AbstractPluginCipher pluginCipher = (AbstractPluginCipher) bean; + pluginCipher.initParams(params); + return pluginCipher; + } else { + throw new PluginDecryptException(error); + } + } catch (ClassNotFoundException e) { + throw new PluginDecryptException("没有发现解密实现者: " + className); + } + } + + protected Object getBean(Class aClass){ + try { + return applicationContext.getBean(aClass); + } catch (Exception e1){ + try { + return aClass.getConstructor().newInstance(); + } catch (Exception e2){ + throw new PluginDecryptException(e2); + } + } + } + +} diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/decrypt/EmptyPluginDescriptorDecrypt.java b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/decrypt/EmptyPluginDescriptorDecrypt.java new file mode 100644 index 0000000000000000000000000000000000000000..bdf89c13dcdd48bb23f127c79fa8dc9f8c045dac --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/decrypt/EmptyPluginDescriptorDecrypt.java @@ -0,0 +1,32 @@ +/** + * Copyright [2019-2022] [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.core.descriptor.decrypt; + +import java.util.Properties; + +/** + * 空的插件解密 + * + * @author starBlues + * @version 3.0.1 + */ +public class EmptyPluginDescriptorDecrypt implements PluginDescriptorDecrypt{ + @Override + public Properties decrypt(String pluginId, Properties properties) { + return properties; + } +} diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/decrypt/PluginDescriptorDecrypt.java b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/decrypt/PluginDescriptorDecrypt.java new file mode 100644 index 0000000000000000000000000000000000000000..df444de8e3ce659e79de46ab58b47c51910040b6 --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/decrypt/PluginDescriptorDecrypt.java @@ -0,0 +1,41 @@ +/** + * Copyright [2019-2022] [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.core.descriptor.decrypt; + +import com.gitee.starblues.core.exception.PluginDecryptException; + +import java.util.Properties; + +/** + * 插件描述文件解密器 + * + * @author starBlues + * @version 3.0.1 + */ +public interface PluginDescriptorDecrypt { + + /** + * 解密 properties + * + * @param pluginId 插件id + * @param properties properties + * @return 解密后的 Properties + * @throws PluginDecryptException 插件解密异常 + */ + Properties decrypt(String pluginId, Properties properties) throws PluginDecryptException; + +} diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/exception/PluginDecryptException.java b/spring-brick/src/main/java/com/gitee/starblues/core/exception/PluginDecryptException.java new file mode 100644 index 0000000000000000000000000000000000000000..8b5def0785b7012470b11f43c574b3f481fd8ada --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/core/exception/PluginDecryptException.java @@ -0,0 +1,60 @@ +/** + * Copyright [2019-2022] [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.core.exception; + +import com.gitee.starblues.core.descriptor.PluginDescriptor; + +/** + * 插件解密异常 + * + * @author starBlues + * @version 3.0.1 + */ +public class PluginDecryptException extends PluginException{ + + public PluginDecryptException() { + super(); + } + + public PluginDecryptException(String message) { + super(message); + } + + public PluginDecryptException(Throwable cause) { + super(cause); + } + + public PluginDecryptException(String message, Throwable cause) { + super(message, cause); + } + + public PluginDecryptException(PluginDescriptor pluginDescriptor, String opType, Throwable cause) { + super(pluginDescriptor, opType, cause); + } + + public PluginDecryptException(PluginDescriptor pluginDescriptor, String message) { + super(pluginDescriptor, message); + } + + public PluginDecryptException(String pluginId, String opType, Throwable cause) { + super(pluginId, opType, cause); + } + + public PluginDecryptException(String pluginId, String message) { + super(pluginId, message); + } +} diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginLauncher.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginLauncher.java index 4c5ba7882c61a19393266e00b1a4770cf7db5724..65fad6583845a13975c97669e6eb768ee45bb6c9 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginLauncher.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/PluginLauncher.java @@ -23,8 +23,8 @@ import com.gitee.starblues.loader.classloader.GenericClassLoader; import com.gitee.starblues.loader.classloader.resource.loader.DefaultResourceLoaderFactory; import com.gitee.starblues.loader.classloader.resource.loader.ResourceLoaderFactory; import com.gitee.starblues.loader.launcher.AbstractLauncher; -import com.gitee.starblues.loader.launcher.ResourceLoaderFactoryGetter; import com.gitee.starblues.spring.SpringPluginHook; +import com.gitee.starblues.utils.MsgUtils; import java.util.Map; import java.util.WeakHashMap; @@ -32,7 +32,7 @@ import java.util.WeakHashMap; /** * 插件启动引导类 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class PluginLauncher extends AbstractLauncher { @@ -61,7 +61,8 @@ public class PluginLauncher extends AbstractLauncher { protected synchronized PluginClassLoader getPluginClassLoader() throws Exception { String pluginId = pluginDescriptor.getPluginId(); - PluginClassLoader classLoader = CLASS_LOADER_CACHE.get(pluginId); + String key = MsgUtils.getPluginUnique(pluginDescriptor); + PluginClassLoader classLoader = CLASS_LOADER_CACHE.get(key); if(classLoader != null){ return classLoader; } @@ -69,7 +70,7 @@ public class PluginLauncher extends AbstractLauncher { pluginId, getParentClassLoader(), mainResourcePatternDefiner, getResourceLoaderFactory() ); - CLASS_LOADER_CACHE.put(pluginId, pluginClassLoader); + CLASS_LOADER_CACHE.put(key, pluginClassLoader); return pluginClassLoader; } @@ -78,7 +79,7 @@ public class PluginLauncher extends AbstractLauncher { } protected GenericClassLoader getParentClassLoader() throws Exception { - ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + ClassLoader contextClassLoader = pluginInteractive.getMainApplicationContext().getClassLoader(); if(contextClassLoader instanceof GenericClassLoader){ return (GenericClassLoader) contextClassLoader; } else { diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/version/SemverVersionInspector.java b/spring-brick/src/main/java/com/gitee/starblues/core/version/SemverVersionInspector.java index 22c1e5c663903b2c26426a76e896b12a2215f865..70dfde34696f175790e7ce88a725001c014dd0bb 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/version/SemverVersionInspector.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/version/SemverVersionInspector.java @@ -16,17 +16,38 @@ package com.gitee.starblues.core.version; +import com.gitee.starblues.core.exception.PluginException; +import com.gitee.starblues.utils.ObjectUtils; +import com.github.zafarkhaja.semver.UnexpectedCharacterException; import com.github.zafarkhaja.semver.Version; /** * Semver标准版本检查 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class SemverVersionInspector implements VersionInspector{ + @Override + public void check(String version) throws PluginException { + try { + Version.valueOf(version); + } catch (Throwable e){ + String message = e.toString(); + if(ObjectUtils.isEmpty(message)){ + message = ""; + } else { + message = ": " + message; + } + throw new PluginException("版本号[" + version + "]非法" + message); + } + } + @Override public int compareTo(String version1, String version2) { + check(version1); + check(version2); + Version v1 = Version.valueOf(version1); Version v2 = Version.valueOf(version2); return v1.compareTo(v2); diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/version/VersionInspector.java b/spring-brick/src/main/java/com/gitee/starblues/core/version/VersionInspector.java index be6a573a5394c19c9080a297112a0330e5289133..b1e1dd8aa60ed85a8049529ef79bac55c763460f 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/version/VersionInspector.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/version/VersionInspector.java @@ -16,20 +16,29 @@ package com.gitee.starblues.core.version; +import com.gitee.starblues.core.exception.PluginException; + /** * 版本检查 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public interface VersionInspector { + /** + * 检查插件版本号是否合法 + * @param version 版本号 + * @throws PluginException 版本号不合法则抛出异常 + */ + void check(String version) throws PluginException; /** * 比较 v1 和 v2版本. * @param v1 版本号码1 * @param v2 版本号码2 * @return 如果 v1大于等于v2, 则返回大于等于0的数字, 否则返回小于0的数字 + * @throws PluginException 版本号不合法则抛出异常 */ - int compareTo(String v1, String v2); + int compareTo(String v1, String v2) throws PluginException;; } diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/AutoIntegrationConfiguration.java b/spring-brick/src/main/java/com/gitee/starblues/integration/AutoIntegrationConfiguration.java index 2b5f0ea3c7c1f2de866e34a28fac796d5b01478d..5134ad9517a376a4639b877a1a99a3c9d0819ddc 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/AutoIntegrationConfiguration.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/AutoIntegrationConfiguration.java @@ -17,6 +17,7 @@ package com.gitee.starblues.integration; import com.gitee.starblues.core.RuntimeMode; +import com.gitee.starblues.integration.decrypt.DecryptConfiguration; import com.gitee.starblues.utils.ResourceUtils; import lombok.Data; import lombok.EqualsAndHashCode; @@ -31,7 +32,7 @@ import java.util.Set; /** * 自动集成的配置 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ @EqualsAndHashCode(callSuper = true) @Component @@ -126,6 +127,11 @@ public class AutoIntegrationConfiguration extends DefaultIntegrationConfiguratio @Value("${exactVersion:false}") private Boolean exactVersion; + /** + * 对插件启动时进行解密校验配置。默认为不启用 + */ + private DecryptConfiguration decrypt; + @Override public boolean enable() { if(enable == null){ @@ -183,4 +189,36 @@ public class AutoIntegrationConfiguration extends DefaultIntegrationConfiguratio } } + @Override + public Set enablePluginIds() { + return enablePluginIds; + } + + @Override + public Set disablePluginIds() { + return disablePluginIds; + } + + @Override + public List sortInitPluginIds() { + return sortInitPluginIds; + } + + @Override + public String version() { + return version; + } + + @Override + public boolean exactVersion() { + return exactVersion; + } + + @Override + public DecryptConfiguration decrypt() { + if(decrypt == null){ + return super.decrypt(); + } + return decrypt; + } } diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/DefaultIntegrationConfiguration.java b/spring-brick/src/main/java/com/gitee/starblues/integration/DefaultIntegrationConfiguration.java index c80f1bfc68eed38423cf9690557b9f8ef2c1c155..451103bc0d036508f437ce1ea26642a0369a504f 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/DefaultIntegrationConfiguration.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/DefaultIntegrationConfiguration.java @@ -16,6 +16,7 @@ package com.gitee.starblues.integration; +import com.gitee.starblues.integration.decrypt.DecryptConfiguration; import com.gitee.starblues.utils.Assert; import java.util.ArrayList; @@ -26,7 +27,7 @@ import java.util.Set; * 默认的插件集成配置。给非必须配置设置了默认值 * * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public abstract class DefaultIntegrationConfiguration implements IntegrationConfiguration{ @@ -90,6 +91,13 @@ public abstract class DefaultIntegrationConfiguration implements IntegrationConf return false; } + @Override + public DecryptConfiguration decrypt() { + DecryptConfiguration decryptConfiguration = new DecryptConfiguration(); + decryptConfiguration.setEnable(false); + return decryptConfiguration; + } + /** * 检查配置 */ diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/ExtendPointConfiguration.java b/spring-brick/src/main/java/com/gitee/starblues/integration/ExtendPointConfiguration.java index 46bb11a84f46c70aa12efdbd01e8057f103b861f..cd7944e6adcc59835e530ff73441088b3a669978 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/ExtendPointConfiguration.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/ExtendPointConfiguration.java @@ -18,6 +18,8 @@ package com.gitee.starblues.integration; import com.gitee.starblues.core.DefaultRealizeProvider; import com.gitee.starblues.core.RealizeProvider;; +import com.gitee.starblues.core.descriptor.decrypt.DefaultPluginDescriptorDecrypt; +import com.gitee.starblues.core.descriptor.decrypt.PluginDescriptorDecrypt; import com.gitee.starblues.core.launcher.plugin.BasicMainResourcePatternDefiner; import com.gitee.starblues.integration.operator.DefaultPluginOperator; import com.gitee.starblues.integration.operator.PluginOperator; @@ -32,7 +34,7 @@ import org.springframework.context.support.GenericApplicationContext; /** * 系统Bean配置 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class ExtendPointConfiguration { @@ -81,4 +83,10 @@ public class ExtendPointConfiguration { return new BasicMainResourcePatternDefiner(configuration.mainPackage()); } + @Bean + @ConditionalOnMissingBean + public PluginDescriptorDecrypt pluginDescriptorDecrypt(){ + return new DefaultPluginDescriptorDecrypt(applicationContext, configuration); + } + } diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/IntegrationConfiguration.java b/spring-brick/src/main/java/com/gitee/starblues/integration/IntegrationConfiguration.java index ace90166a30961c2ccff00468b72c83d6c49163c..a866e79bf057d036cdc681dd45f867371a6fde5b 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/IntegrationConfiguration.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/IntegrationConfiguration.java @@ -19,8 +19,8 @@ package com.gitee.starblues.integration; import com.gitee.starblues.common.Constants; import com.gitee.starblues.core.RuntimeMode; +import com.gitee.starblues.integration.decrypt.DecryptConfiguration; import com.gitee.starblues.utils.ObjectUtils; -import org.springframework.http.CacheControl; import java.util.List; import java.util.Set; @@ -29,7 +29,7 @@ import java.util.Set; /** * 插件集成时的配置接口。插件集成的配置接口 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public interface IntegrationConfiguration { @@ -118,6 +118,12 @@ public interface IntegrationConfiguration { */ boolean exactVersion(); + /** + * 解密配置 + * @return DecryptConfiguration + */ + DecryptConfiguration decrypt(); + /** * 检查配置 diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/decrypt/DecryptConfiguration.java b/spring-brick/src/main/java/com/gitee/starblues/integration/decrypt/DecryptConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..111210212c5e126773d76821832427e5d3e65687 --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/decrypt/DecryptConfiguration.java @@ -0,0 +1,61 @@ +/** + * Copyright [2019-2022] [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.integration.decrypt; + +import com.gitee.starblues.common.cipher.AesPluginCipher; +import com.gitee.starblues.common.cipher.RsaPluginCipher; +import lombok.Data; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 对插件启动时进行解密校验配置。默认为不启用 + * + * @author starBlues + * @version 3.0.1 + */ +@Data +public class DecryptConfiguration { + + /** + * 是否启动. 默认启用 + */ + private Boolean enable = true; + + /** + * 加解密实现类名称. + * 通过类加载器加载, 然后从Spring容器中获取, 获取不到, 对其直接实例化 + * 默认: {@link AesPluginCipher} + * 可选: + * @see com.gitee.starblues.common.cipher.AesPluginCipher + * @see com.gitee.starblues.common.cipher.RsaPluginCipher + */ + private String className = AesPluginCipher.class.getName(); + + /** + * 总配置 + */ + private Map props = new HashMap<>(); + + /** + * 指定可生效的插件. 如果不配置, 则默认对全部插件生效 + */ + private List plugins; + +} diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/decrypt/DecryptPluginConfiguration.java b/spring-brick/src/main/java/com/gitee/starblues/integration/decrypt/DecryptPluginConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..5b769f89d1673f548a179c7fef4c0c394feca621 --- /dev/null +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/decrypt/DecryptPluginConfiguration.java @@ -0,0 +1,43 @@ +/** + * Copyright [2019-2022] [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.integration.decrypt; + +import lombok.Data; + +import java.util.Map; + +/** + * 解密插件配置 + * + * @author starBlues + * @version 3.0.1 + */ +@Data +public class DecryptPluginConfiguration { + + /** + * 插件id + */ + private String pluginId; + + /** + * 对当前插件特定的配置, 可以覆盖 {@link DecryptConfiguration#getProps()} 配置 + */ + private Map props; + + +} diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java b/spring-brick/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java index 0a8c6b12c2e1223c89797a6c29f1e570129f4952..ea44db3699b110f54dcc8140eb0d717afe319726 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java @@ -53,7 +53,7 @@ import java.util.concurrent.atomic.AtomicBoolean; /** * 默认的插件操作者 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class DefaultPluginOperator implements PluginOperator { protected final Logger log = LoggerFactory.getLogger(this.getClass()); @@ -90,12 +90,8 @@ public class DefaultPluginOperator implements PluginOperator { return true; } initBeforeLogPrint(); - // 触发插件初始化监听器 - pluginInitializerListenerFactory.before(); if(!configuration.enable()){ log.info("插件功能已被禁用!"); - // 如果禁用的话, 直接返回 - pluginInitializerListenerFactory.complete(); return false; } // 开始加载插件 @@ -103,6 +99,8 @@ public class DefaultPluginOperator implements PluginOperator { if(ObjectUtils.isEmpty(pluginInfos)){ return false; } + // 触发插件初始化监听器 + pluginInitializerListenerFactory.before(); boolean isFoundException = false; for (PluginInfo pluginInfo : pluginInfos) { try { @@ -304,6 +302,8 @@ public class DefaultPluginOperator implements PluginOperator { } // 然后进入更新模式 pluginInfo = pluginManager.upgrade(tempFilePath, isUnpackPluginFile); + // 删除旧插件包 + FileUtils.delete(oldPluginPath.toFile()); } else { // 不存在则进入安装插件模式 pluginInfo = pluginManager.install(tempFilePath, isUnpackPluginFile); diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContext.java b/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContext.java index 070e04a6b4f0d567069f32925f772b48cad0eb1e..e1cdb4d8d33c8aa6a379d75427130114c6497b6b 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContext.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContext.java @@ -21,7 +21,7 @@ import java.util.Map; /** * 主程序 ApplicationContext 接口 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public interface MainApplicationContext extends ApplicationContext { @@ -32,4 +32,10 @@ public interface MainApplicationContext extends ApplicationContext { */ Map> getConfigurableEnvironment(); + /** + * 得到主程序的 ClassLoader + * @return ClassLoader + */ + ClassLoader getClassLoader(); + } diff --git a/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContextProxy.java b/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContextProxy.java index a430ae8a831491cd595ffc4b39d603bfee909f97..b2779e407785ab78ce193dd2ed4b276d30e88f8e 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContextProxy.java +++ b/spring-brick/src/main/java/com/gitee/starblues/spring/MainApplicationContextProxy.java @@ -23,27 +23,29 @@ import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertySource; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; /** * 主程序 ApplicationContext 的实现 * @author starBlues - * @version 3.0.0 + * @version 3.0.1 */ public class MainApplicationContextProxy extends ApplicationContextProxy implements MainApplicationContext{ private final GenericApplicationContext applicationContext; + private final ClassLoader classLoader; public MainApplicationContextProxy(GenericApplicationContext applicationContext) { super(applicationContext.getBeanFactory()); this.applicationContext = applicationContext; + this.classLoader = Thread.currentThread().getContextClassLoader(); } public MainApplicationContextProxy(GenericApplicationContext applicationContext, AutoCloseable autoCloseable) { super(applicationContext.getBeanFactory(), autoCloseable); this.applicationContext = applicationContext; + this.classLoader = Thread.currentThread().getContextClassLoader(); } @Override @@ -67,4 +69,9 @@ public class MainApplicationContextProxy extends ApplicationContextProxy impleme } return environmentMap; } + + @Override + public ClassLoader getClassLoader() { + return classLoader; + } } diff --git a/spring-brick/src/main/resources/META-INF/spring-configuration-metadata.json b/spring-brick/src/main/resources/META-INF/spring-configuration-metadata.json index 4eec8b41335758607b41fd0d35692123bbfe07dd..67610e7b0fe6bd0ae08c1d01226751432b1b08de 100644 --- a/spring-brick/src/main/resources/META-INF/spring-configuration-metadata.json +++ b/spring-brick/src/main/resources/META-INF/spring-configuration-metadata.json @@ -99,6 +99,38 @@ "sourceType": "com.gitee.starblues.integration.AutoIntegrationConfiguration", "description": "是否完全匹配版本。设置为true表示插件设置的requires的版本号完全匹配version版本号才可允许插件安装, 即: requires=x.y.z; 设置为false表示插件设置的requires的版本号小于等于version值, 插件就可安装, 即requires<=x.y.z", "defaultValue": false + }, + { + "name": "plugin.decrypt", + "type": "com.gitee.starblues.integration.decrypt.DecryptConfiguration", + "sourceType": "com.gitee.starblues.integration.AutoIntegrationConfiguration", + "description": "对插件启动时进行解密校验配置。默认为不启用" + }, + { + "name": "plugin.decrypt.enable", + "type": "java.lang.Boolean", + "sourceType": "com.gitee.starblues.integration.decrypt.DecryptConfiguration", + "description": "解密校验配置是否启用。默认为启用", + "defaultValue": true + }, + { + "name": "plugin.decrypt.className", + "type": "java.lang.String", + "sourceType": "com.gitee.starblues.integration.decrypt.DecryptConfiguration", + "description": "解密实现类名称。默认: com.gitee.starblues.common.cipher.RsaPluginCipher", + "defaultValue": "com.gitee.starblues.common.cipher.RsaPluginCipher" + }, + { + "name": "plugin.decrypt.props", + "type": "java.lang.Map", + "sourceType": "com.gitee.starblues.integration.decrypt.DecryptConfiguration", + "description": "总配置" + }, + { + "name": "plugin.decrypt.plugins", + "type": "java.lang.List", + "sourceType": "com.gitee.starblues.integration.decrypt.DecryptConfiguration", + "description": "指定可生效的插件. 如果不配置, 则默认对全部插件生效" } ] } \ No newline at end of file diff --git a/spring-brick/src/test/java/com/gitee/starblues/core/checker/DefaultPluginLauncherCheckerTest.java b/spring-brick/src/test/java/com/gitee/starblues/core/checker/DefaultPluginLauncherCheckerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..09d895d26c40e1b33acffbee44cf4c33ec620244 --- /dev/null +++ b/spring-brick/src/test/java/com/gitee/starblues/core/checker/DefaultPluginLauncherCheckerTest.java @@ -0,0 +1,94 @@ +/** + * Copyright [2019-2022] [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.core.checker; + +import com.gitee.starblues.core.DefaultPluginInsideInfo; +import com.gitee.starblues.core.PluginInfo; +import com.gitee.starblues.core.PluginState; +import com.gitee.starblues.core.RealizeProvider; +import com.gitee.starblues.core.descriptor.DefaultInsidePluginDescriptor; +import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; +import com.gitee.starblues.core.exception.PluginException; +import com.gitee.starblues.core.version.SemverVersionInspector; +import com.gitee.starblues.integration.IntegrationConfiguration; +import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.io.File; +import java.nio.file.Path; + +import static org.powermock.api.mockito.PowerMockito.*; +/** + * 测试 DefaultPluginLauncherChecker + * + * @author starBlues + * @version 3.0.0 + */ +@RunWith(PowerMockRunner.class) +public class DefaultPluginLauncherCheckerTest extends TestCase { + + private DefaultPluginLauncherChecker launcherChecker; + + @Mock + private RealizeProvider realizeProvider; + @Mock + private IntegrationConfiguration configuration; + + @Before + public void setUp(){ + launcherChecker = spy(new DefaultPluginLauncherChecker(realizeProvider, configuration)); + } + + @Test + public void test_checkCanStart_start(){ + DefaultPluginInsideInfo pluginInfo = getPluginInfo(); + pluginInfo.setPluginState(PluginState.STARTED); + + when(configuration.isDisabled(Mockito.anyString())).thenReturn(false); + when(configuration.isEnable(Mockito.anyString())).thenReturn(true); + + try { + launcherChecker.checkCanStart(pluginInfo); + } catch (Exception e){ + assertTrue(e instanceof PluginException); + } + } + + + private DefaultPluginInsideInfo getPluginInfo(){ + String pluginId = "pluginId"; + String version = "1.0.0"; + String pluginClass = "pluginClass"; + Path pluginPath = mock(Path.class); + Path pluginPath2 = mock(Path.class); + when(pluginPath.toAbsolutePath()).thenReturn(pluginPath2); + when(pluginPath2.toString()).thenReturn("path"); + + File file = mock(File.class); + when(pluginPath.toFile()).thenReturn(file); + when(file.getName()).thenReturn("file.jar"); + InsidePluginDescriptor descriptor = new DefaultInsidePluginDescriptor(pluginId, version, pluginClass, pluginPath); + + return new DefaultPluginInsideInfo(descriptor); + } + +} \ No newline at end of file diff --git a/spring-brick/src/test/java/com/gitee/starblues/core/version/SemverVersionInspectorTest.java b/spring-brick/src/test/java/com/gitee/starblues/core/version/SemverVersionInspectorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c8e87d72da807b603b99eb27f66c601116ca0534 --- /dev/null +++ b/spring-brick/src/test/java/com/gitee/starblues/core/version/SemverVersionInspectorTest.java @@ -0,0 +1,65 @@ +/** + * Copyright [2019-2022] [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.core.version; + +import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.modules.junit4.PowerMockRunner; + +import static org.powermock.api.mockito.PowerMockito.*; + +/** + * SemverVersionInspectorTest 单元测试 + * + * @author starBlues + * @version 3.0.0 + */ +@RunWith(PowerMockRunner.class) +public class SemverVersionInspectorTest extends TestCase { + + private SemverVersionInspector versionInspector; + + + @Before + public void setUp(){ + versionInspector = spy(new SemverVersionInspector()); + } + + @Test + public void test_equal(){ + assertEquals(0, versionInspector.compareTo("1.0.0", "1.0.0")); + assertEquals(0, versionInspector.compareTo("1.0.0-SNAPSHOT", "1.0.0-SNAPSHOT")); + } + + @Test + public void test_greater(){ + assertTrue(versionInspector.compareTo("2.0.0", "1.0.0") > 0); + assertTrue(versionInspector.compareTo("2.0.0-SNAPSHOT", "1.0.0-SNAPSHOT") > 0); + assertTrue(versionInspector.compareTo("2.0.2", "1.2.0") > 0); + assertTrue(versionInspector.compareTo("1.2.2", "1.2.0") > 0); + } + + @Test + public void test_less(){ + assertTrue(versionInspector.compareTo("1.0.0", "2.0.0") <= 0); + assertTrue(versionInspector.compareTo("1.0.0-SNAPSHOT", "2.0.0-SNAPSHOT") <= 0); + } + + +} \ No newline at end of file diff --git a/update.md b/update.md new file mode 100644 index 0000000000000000000000000000000000000000..717eff72034983b6eb6daf00cf6507490f21d5d8 --- /dev/null +++ b/update.md @@ -0,0 +1,6 @@ +1. 新增插件包启动时可进行密码校验功能。 +2. 修复插件动态安装的问题。 +3. 修复主程序打包为生产环境jar包后,启动问题。 +4. 修复插件更新时, 版本校验问题。 +5. 修复插件排序、启用、禁用配置无效的问题。 +6. 修复插件更新时, 新代码不无法变更的问题。 \ No newline at end of file