Commit 290fcd94d56334e4706935a5b250c1d925a5eaee
1 parent
92c2717d
【功能新增】IoT:增加插件支持,包含插件API和示例控制器
Showing
18 changed files
with
637 additions
and
92 deletions
yudao-module-iot/pom.xml
| @@ -11,6 +11,7 @@ | @@ -11,6 +11,7 @@ | ||
| 11 | <module>yudao-module-iot-api</module> | 11 | <module>yudao-module-iot-api</module> |
| 12 | <module>yudao-module-iot-biz</module> | 12 | <module>yudao-module-iot-biz</module> |
| 13 | <module>yudao-module-iot-plugin</module> | 13 | <module>yudao-module-iot-plugin</module> |
| 14 | + <module>yudao-module-iot-plugin-api</module> | ||
| 14 | </modules> | 15 | </modules> |
| 15 | <modelVersion>4.0.0</modelVersion> | 16 | <modelVersion>4.0.0</modelVersion> |
| 16 | 17 |
yudao-module-iot/yudao-module-iot-biz/pom.xml
| @@ -27,6 +27,13 @@ | @@ -27,6 +27,13 @@ | ||
| 27 | 27 | ||
| 28 | <dependency> | 28 | <dependency> |
| 29 | <groupId>cn.iocoder.boot</groupId> | 29 | <groupId>cn.iocoder.boot</groupId> |
| 30 | + <artifactId>yudao-module-iot-plugin-api</artifactId> | ||
| 31 | + <version>0.0.1</version> | ||
| 32 | + <scope>compile</scope> | ||
| 33 | + </dependency> | ||
| 34 | + | ||
| 35 | + <dependency> | ||
| 36 | + <groupId>cn.iocoder.boot</groupId> | ||
| 30 | <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> | 37 | <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> |
| 31 | </dependency> | 38 | </dependency> |
| 32 | 39 | ||
| @@ -75,6 +82,7 @@ | @@ -75,6 +82,7 @@ | ||
| 75 | <groupId>org.pf4j</groupId> | 82 | <groupId>org.pf4j</groupId> |
| 76 | <artifactId>pf4j-spring</artifactId> | 83 | <artifactId>pf4j-spring</artifactId> |
| 77 | </dependency> | 84 | </dependency> |
| 85 | + | ||
| 78 | </dependencies> | 86 | </dependencies> |
| 79 | 87 | ||
| 80 | </project> | 88 | </project> |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugininfo/Greetings.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright (C) 2012-present the original author or authors. | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package cn.iocoder.yudao.module.iot.controller.admin.plugininfo; | ||
| 17 | + | ||
| 18 | +import cn.iocoder.yudao.module.iot.api.Greeting; | ||
| 19 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 20 | +import org.springframework.stereotype.Component; | ||
| 21 | + | ||
| 22 | +import java.util.List; | ||
| 23 | + | ||
| 24 | +/** | ||
| 25 | + * 打招呼 测试用例 | ||
| 26 | + */ | ||
| 27 | +@Component | ||
| 28 | +public class Greetings { | ||
| 29 | + | ||
| 30 | + @Autowired | ||
| 31 | + private List<Greeting> greetings; | ||
| 32 | + | ||
| 33 | + public void printGreetings() { | ||
| 34 | + System.out.printf("找到扩展点的 %d 个扩展 '%s'%n", greetings.size(), Greeting.class.getName()); | ||
| 35 | + for (Greeting greeting : greetings) { | ||
| 36 | + System.out.println(">>> " + greeting.getGreeting()); | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | +} |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugininfo/PluginController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.plugininfo; | ||
| 2 | + | ||
| 3 | +import jakarta.annotation.Resource; | ||
| 4 | +import org.pf4j.spring.SpringPluginManager; | ||
| 5 | +import org.springframework.beans.factory.annotation.Value; | ||
| 6 | +import org.springframework.context.ApplicationContext; | ||
| 7 | +import org.springframework.http.HttpStatus; | ||
| 8 | +import org.springframework.http.ResponseEntity; | ||
| 9 | +import org.springframework.web.bind.annotation.*; | ||
| 10 | +import org.springframework.web.multipart.MultipartFile; | ||
| 11 | + | ||
| 12 | +import javax.annotation.security.PermitAll; | ||
| 13 | +import java.io.IOException; | ||
| 14 | +import java.nio.file.Files; | ||
| 15 | +import java.nio.file.Path; | ||
| 16 | +import java.nio.file.Paths; | ||
| 17 | +import java.nio.file.StandardCopyOption; | ||
| 18 | +import java.util.List; | ||
| 19 | +import java.util.stream.Collectors; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * 插件 Controller 测试用例 | ||
| 23 | + */ | ||
| 24 | +@RestController | ||
| 25 | +@RequestMapping("/iot/plugins") | ||
| 26 | +public class PluginController { | ||
| 27 | + | ||
| 28 | + @Resource | ||
| 29 | + private ApplicationContext applicationContext; | ||
| 30 | + @Resource | ||
| 31 | + private SpringPluginManager springPluginManager; | ||
| 32 | + @Resource | ||
| 33 | + private Greetings greetings; | ||
| 34 | + | ||
| 35 | + @Value("${pf4j.pluginsDir}") | ||
| 36 | + private String pluginsDir; | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 上传插件 JAR 文件并加载插件 | ||
| 40 | + * | ||
| 41 | + * @param file 上传的 JAR 文件 | ||
| 42 | + * @return 上传结果 | ||
| 43 | + */ | ||
| 44 | + @PermitAll | ||
| 45 | + @PostMapping("/upload") | ||
| 46 | + public ResponseEntity<String> uploadPlugin(@RequestParam("file") MultipartFile file) { | ||
| 47 | + if (file.isEmpty()) { | ||
| 48 | + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("上传的文件为空"); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + // 确保插件目录存在 | ||
| 52 | + Path pluginsPath = Paths.get(pluginsDir); | ||
| 53 | + try { | ||
| 54 | + if (!Files.exists(pluginsPath)) { | ||
| 55 | + Files.createDirectories(pluginsPath); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + // 保存上传的 JAR 文件到插件目录 | ||
| 59 | + String filename = file.getOriginalFilename(); | ||
| 60 | + if (filename == null || (!filename.endsWith(".jar") && !filename.endsWith(".zip"))) { | ||
| 61 | + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("上传的文件不是 JAR 或 ZIP 文件"); | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + Path jarPath = pluginsPath.resolve(filename); | ||
| 65 | + | ||
| 66 | + Files.copy(file.getInputStream(), jarPath, StandardCopyOption.REPLACE_EXISTING); | ||
| 67 | + | ||
| 68 | + // 加载插件 | ||
| 69 | + String pluginId = springPluginManager.loadPlugin(jarPath.toAbsolutePath()); | ||
| 70 | + | ||
| 71 | + // 启动插件 | ||
| 72 | + springPluginManager.startPlugin(pluginId); | ||
| 73 | + | ||
| 74 | + return ResponseEntity.ok("插件上传并加载成功"); | ||
| 75 | + } catch (IOException e) { | ||
| 76 | + e.printStackTrace(); | ||
| 77 | + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("上传插件时发生错误: " + e.getMessage()); | ||
| 78 | + } catch (Exception e) { | ||
| 79 | + e.printStackTrace(); | ||
| 80 | + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("加载插件时发生错误: " + e.getMessage()); | ||
| 81 | + } | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + /** | ||
| 85 | + * 卸载指定插件 | ||
| 86 | + * | ||
| 87 | + * @param pluginId 插件 ID | ||
| 88 | + * @return 卸载结果 | ||
| 89 | + */ | ||
| 90 | + @PermitAll | ||
| 91 | + @DeleteMapping("/unload/{pluginId}") | ||
| 92 | + public ResponseEntity<String> unloadPlugin(@PathVariable String pluginId) { | ||
| 93 | + if (springPluginManager.getPlugins().stream().noneMatch(plugin -> plugin.getDescriptor().getPluginId().equals(pluginId))) { | ||
| 94 | + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("插件未加载: " + pluginId); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + springPluginManager.stopPlugin(pluginId); | ||
| 98 | + springPluginManager.unloadPlugin(pluginId); | ||
| 99 | + | ||
| 100 | + // 删除插件 JAR 文件(可选) | ||
| 101 | +// PluginWrapper plugin = pluginManager.getPlugin(pluginId); | ||
| 102 | +// PluginDescriptor descriptor = plugin.getDescriptor(); | ||
| 103 | +// Path jarPath = Paths.get(pluginsDir).resolve(descriptor.getPluginId() + ".jar"); | ||
| 104 | +// Files.deleteIfExists(jarPath); | ||
| 105 | + | ||
| 106 | + return ResponseEntity.ok("插件卸载成功: " + pluginId); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + /** | ||
| 110 | + * 列出所有已加载的插件 | ||
| 111 | + * | ||
| 112 | + * @return 插件列表 | ||
| 113 | + */ | ||
| 114 | + @PermitAll | ||
| 115 | + @GetMapping("/list") | ||
| 116 | + public ResponseEntity<List<String>> listPlugins() { | ||
| 117 | + List<String> plugins = springPluginManager.getPlugins().stream() | ||
| 118 | + .map(plugin -> plugin.getDescriptor().getPluginId()) | ||
| 119 | + .collect(Collectors.toList()); | ||
| 120 | + return ResponseEntity.ok(plugins); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + /** | ||
| 124 | + * 打印问候语 | ||
| 125 | + * | ||
| 126 | + * @return 1 | ||
| 127 | + */ | ||
| 128 | + @PermitAll | ||
| 129 | + @GetMapping("/printGreetings") | ||
| 130 | + public ResponseEntity<Integer> printGreetings() { | ||
| 131 | + greetings.printGreetings(); | ||
| 132 | + return ResponseEntity.ok(1); | ||
| 133 | + } | ||
| 134 | +} |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugininfo/WhazzupGreeting.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright (C) 2012-present the original author or authors. | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package cn.iocoder.yudao.module.iot.controller.admin.plugininfo; | ||
| 17 | + | ||
| 18 | +import cn.iocoder.yudao.module.iot.api.Greeting; | ||
| 19 | +import org.pf4j.Extension; | ||
| 20 | +import org.springframework.stereotype.Component; | ||
| 21 | + | ||
| 22 | +/** | ||
| 23 | + * 打招呼 测试用例 | ||
| 24 | + */ | ||
| 25 | +@Extension | ||
| 26 | +@Component | ||
| 27 | +public class WhazzupGreeting implements Greeting { | ||
| 28 | + | ||
| 29 | + @Override | ||
| 30 | + public String getGreeting() { | ||
| 31 | + return "Whazzup"; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | +} |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/SpringConfiguration.java
| 1 | package cn.iocoder.yudao.module.iot.framework.plugin; | 1 | package cn.iocoder.yudao.module.iot.framework.plugin; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.module.iot.controller.admin.plugininfo.Greetings; | ||
| 3 | import org.pf4j.spring.SpringPluginManager; | 4 | import org.pf4j.spring.SpringPluginManager; |
| 4 | import org.springframework.context.annotation.Bean; | 5 | import org.springframework.context.annotation.Bean; |
| 5 | import org.springframework.context.annotation.Configuration; | 6 | import org.springframework.context.annotation.Configuration; |
| 7 | +import org.springframework.context.annotation.DependsOn; | ||
| 6 | 8 | ||
| 7 | @Configuration | 9 | @Configuration |
| 8 | public class SpringConfiguration { | 10 | public class SpringConfiguration { |
| @@ -12,4 +14,10 @@ public class SpringConfiguration { | @@ -12,4 +14,10 @@ public class SpringConfiguration { | ||
| 12 | return new SpringPluginManager(); | 14 | return new SpringPluginManager(); |
| 13 | } | 15 | } |
| 14 | 16 | ||
| 17 | + @Bean | ||
| 18 | + @DependsOn("pluginManager") | ||
| 19 | + public Greetings greetings() { | ||
| 20 | + return new Greetings(); | ||
| 21 | + } | ||
| 22 | + | ||
| 15 | } | 23 | } |
| 16 | \ No newline at end of file | 24 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugininfo/PluginInfoService.java
| @@ -7,8 +7,6 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo.PluginInfoDO; | @@ -7,8 +7,6 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo.PluginInfoDO; | ||
| 7 | import jakarta.validation.Valid; | 7 | import jakarta.validation.Valid; |
| 8 | import org.springframework.web.multipart.MultipartFile; | 8 | import org.springframework.web.multipart.MultipartFile; |
| 9 | 9 | ||
| 10 | -import java.io.InputStream; | ||
| 11 | - | ||
| 12 | /** | 10 | /** |
| 13 | * IoT 插件信息 Service 接口 | 11 | * IoT 插件信息 Service 接口 |
| 14 | * | 12 | * |
| @@ -57,7 +55,7 @@ public interface PluginInfoService { | @@ -57,7 +55,7 @@ public interface PluginInfoService { | ||
| 57 | /** | 55 | /** |
| 58 | * 上传插件的 JAR 包 | 56 | * 上传插件的 JAR 包 |
| 59 | * | 57 | * |
| 60 | - * @param id 插件id | 58 | + * @param id 插件id |
| 61 | * @param file 文件 | 59 | * @param file 文件 |
| 62 | */ | 60 | */ |
| 63 | void uploadJar(Long id, MultipartFile file); | 61 | void uploadJar(Long id, MultipartFile file); |
| @@ -65,7 +63,7 @@ public interface PluginInfoService { | @@ -65,7 +63,7 @@ public interface PluginInfoService { | ||
| 65 | /** | 63 | /** |
| 66 | * 更新插件的状态 | 64 | * 更新插件的状态 |
| 67 | * | 65 | * |
| 68 | - * @param id 插件id | 66 | + * @param id 插件id |
| 69 | * @param status 状态 | 67 | * @param status 状态 |
| 70 | */ | 68 | */ |
| 71 | void updatePluginStatus(Long id, Integer status); | 69 | void updatePluginStatus(Long id, Integer status); |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugininfo/PluginInfoServiceImpl.java
| @@ -17,13 +17,18 @@ import org.pf4j.PluginDescriptor; | @@ -17,13 +17,18 @@ import org.pf4j.PluginDescriptor; | ||
| 17 | import org.pf4j.PluginState; | 17 | import org.pf4j.PluginState; |
| 18 | import org.pf4j.PluginWrapper; | 18 | import org.pf4j.PluginWrapper; |
| 19 | import org.pf4j.spring.SpringPluginManager; | 19 | import org.pf4j.spring.SpringPluginManager; |
| 20 | +import org.springframework.beans.factory.annotation.Value; | ||
| 20 | import org.springframework.stereotype.Service; | 21 | import org.springframework.stereotype.Service; |
| 21 | import org.springframework.validation.annotation.Validated; | 22 | import org.springframework.validation.annotation.Validated; |
| 22 | import org.springframework.web.multipart.MultipartFile; | 23 | import org.springframework.web.multipart.MultipartFile; |
| 23 | 24 | ||
| 25 | +import java.nio.file.Files; | ||
| 24 | import java.nio.file.Path; | 26 | import java.nio.file.Path; |
| 27 | +import java.nio.file.Paths; | ||
| 25 | import java.util.concurrent.Executors; | 28 | import java.util.concurrent.Executors; |
| 26 | import java.util.concurrent.TimeUnit; | 29 | import java.util.concurrent.TimeUnit; |
| 30 | +import java.util.jar.JarEntry; | ||
| 31 | +import java.util.jar.JarFile; | ||
| 27 | 32 | ||
| 28 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 33 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 29 | import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; | 34 | import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; |
| @@ -47,6 +52,9 @@ public class PluginInfoServiceImpl implements PluginInfoService { | @@ -47,6 +52,9 @@ public class PluginInfoServiceImpl implements PluginInfoService { | ||
| 47 | @Resource | 52 | @Resource |
| 48 | private FileApi fileApi; | 53 | private FileApi fileApi; |
| 49 | 54 | ||
| 55 | + @Value("${pf4j.pluginsDir}") | ||
| 56 | + private String pluginsDir; | ||
| 57 | + | ||
| 50 | @Override | 58 | @Override |
| 51 | public Long createPluginInfo(PluginInfoSaveReqVO createReqVO) { | 59 | public Long createPluginInfo(PluginInfoSaveReqVO createReqVO) { |
| 52 | // 插入 | 60 | // 插入 |
| @@ -132,7 +140,7 @@ public class PluginInfoServiceImpl implements PluginInfoService { | @@ -132,7 +140,7 @@ public class PluginInfoServiceImpl implements PluginInfoService { | ||
| 132 | // 4. 上传插件 | 140 | // 4. 上传插件 |
| 133 | String pluginIdNew; | 141 | String pluginIdNew; |
| 134 | try { | 142 | try { |
| 135 | - String path = fileApi.createFile(IoUtil.readBytes(file.getInputStream())); | 143 | + String path = fileApi.createFile(pluginsDir, IoUtil.readBytes(file.getInputStream())); |
| 136 | Path pluginPath = Path.of(path); | 144 | Path pluginPath = Path.of(path); |
| 137 | pluginIdNew = pluginManager.loadPlugin(pluginPath); | 145 | pluginIdNew = pluginManager.loadPlugin(pluginPath); |
| 138 | } catch (Exception e) { | 146 | } catch (Exception e) { |
| @@ -144,10 +152,31 @@ public class PluginInfoServiceImpl implements PluginInfoService { | @@ -144,10 +152,31 @@ public class PluginInfoServiceImpl implements PluginInfoService { | ||
| 144 | throw exception(PLUGIN_INSTALL_FAILED); | 152 | throw exception(PLUGIN_INSTALL_FAILED); |
| 145 | } | 153 | } |
| 146 | 154 | ||
| 147 | - | ||
| 148 | // 5. 读取配置文件和脚本 | 155 | // 5. 读取配置文件和脚本 |
| 149 | String configJson = ""; | 156 | String configJson = ""; |
| 150 | String script = ""; | 157 | String script = ""; |
| 158 | + try (JarFile jarFile = new JarFile(pluginWrapper.getPluginPath().toFile())) { | ||
| 159 | + // 5.1 获取config文件在jar包中的路径 | ||
| 160 | + String configFile = "classes/config.json"; | ||
| 161 | + JarEntry configEntry = jarFile.getJarEntry(configFile); | ||
| 162 | + | ||
| 163 | + if (configEntry != null) { | ||
| 164 | + // 5.2 读取配置文件 | ||
| 165 | + configJson = IoUtil.readUtf8(jarFile.getInputStream(configEntry)); | ||
| 166 | + log.info("configJson:{}", configJson); | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + // 5.3 读取script.js脚本 | ||
| 170 | + String scriptFile = "classes/script.js"; | ||
| 171 | + JarEntry scriptEntity = jarFile.getJarEntry(scriptFile); | ||
| 172 | + if (scriptEntity != null) { | ||
| 173 | + // 5.4 读取脚本文件 | ||
| 174 | + script = IoUtil.readUtf8(jarFile.getInputStream(scriptEntity)); | ||
| 175 | + log.info("script:{}", script); | ||
| 176 | + } | ||
| 177 | + } catch (Exception e) { | ||
| 178 | + throw exception(PLUGIN_INSTALL_FAILED); | ||
| 179 | + } | ||
| 151 | 180 | ||
| 152 | pluginInfoDo.setPluginId(pluginIdNew); | 181 | pluginInfoDo.setPluginId(pluginIdNew); |
| 153 | pluginInfoDo.setStatus(IotPluginStatusEnum.STOPPED.getStatus()); | 182 | pluginInfoDo.setStatus(IotPluginStatusEnum.STOPPED.getStatus()); |
| @@ -159,48 +188,6 @@ public class PluginInfoServiceImpl implements PluginInfoService { | @@ -159,48 +188,6 @@ public class PluginInfoServiceImpl implements PluginInfoService { | ||
| 159 | pluginInfoDo.setVersion(pluginDescriptor.getVersion()); | 188 | pluginInfoDo.setVersion(pluginDescriptor.getVersion()); |
| 160 | pluginInfoDo.setDescription(pluginDescriptor.getPluginDescription()); | 189 | pluginInfoDo.setDescription(pluginDescriptor.getPluginDescription()); |
| 161 | pluginInfoMapper.updateById(pluginInfoDo); | 190 | pluginInfoMapper.updateById(pluginInfoDo); |
| 162 | - | ||
| 163 | - | ||
| 164 | - // 5. 读取配置文件和脚本 | ||
| 165 | -// String configJson = ""; | ||
| 166 | - // String script = ""; | ||
| 167 | -// try (JarFile jarFile = new JarFile(pluginInfoUpdate.getPluginPath())) { | ||
| 168 | -// // 5.1 获取config文件在jar包中的路径 | ||
| 169 | -// String configFile = "classes/config.json"; | ||
| 170 | -// JarEntry configEntry = jarFile.getJarEntry(configFile); | ||
| 171 | -// | ||
| 172 | -// if (configEntry != null) { | ||
| 173 | -// // 5.2 读取配置文件 | ||
| 174 | -// configJson = IoUtil.read(jarFile.getInputStream(configEntry), Charset.defaultCharset()); | ||
| 175 | -// log.info("configJson:{}", configJson); | ||
| 176 | -// } | ||
| 177 | -// | ||
| 178 | -// // 5.3 读取script.js脚本 | ||
| 179 | -// String scriptFile = "classes/script.js"; | ||
| 180 | -// JarEntry scriptEntity = jarFile.getJarEntry(scriptFile); | ||
| 181 | -// if (scriptEntity != null) { | ||
| 182 | -// // 5.4 读取脚本文件 | ||
| 183 | -// script = IoUtil.read(jarFile.getInputStream(scriptEntity), Charset.defaultCharset()); | ||
| 184 | -// log.info("script:{}", script); | ||
| 185 | -// } | ||
| 186 | -// } catch (Exception e) { | ||
| 187 | -// throw exception(PLUGIN_INSTALL_FAILED); | ||
| 188 | -// } | ||
| 189 | - | ||
| 190 | - | ||
| 191 | -// PluginState pluginState = pluginInfoUpdate.getPluginState(); | ||
| 192 | -// if (pluginState == PluginState.STARTED) { | ||
| 193 | -// pluginInfoDo.setStatus(IotPluginStatusEnum.RUNNING.getStatus()); | ||
| 194 | -// } | ||
| 195 | -// pluginInfoDo.setPluginId(pluginInfoUpdate.getPluginId()); | ||
| 196 | -// pluginInfoDo.setFile(file.getOriginalFilename()); | ||
| 197 | -// pluginInfoDo.setConfigSchema(configJson); | ||
| 198 | -// pluginInfoDo.setScript(script); | ||
| 199 | -// | ||
| 200 | -// PluginDescriptor pluginDescriptor = pluginInfoUpdate.getPluginDescriptor(); | ||
| 201 | -// pluginInfoDo.setVersion(pluginDescriptor.getPluginVersion()); | ||
| 202 | -// pluginInfoDo.setDescription(pluginDescriptor.getDescription()); | ||
| 203 | -// pluginInfoMapper.updateById(pluginInfoDo); | ||
| 204 | } | 191 | } |
| 205 | 192 | ||
| 206 | @Override | 193 | @Override |
| @@ -213,26 +200,22 @@ public class PluginInfoServiceImpl implements PluginInfoService { | @@ -213,26 +200,22 @@ public class PluginInfoServiceImpl implements PluginInfoService { | ||
| 213 | throw exception(PLUGIN_STATUS_INVALID); | 200 | throw exception(PLUGIN_STATUS_INVALID); |
| 214 | } | 201 | } |
| 215 | 202 | ||
| 216 | - // 插件包为空 | ||
| 217 | -// String pluginId = pluginInfoDo.getPluginId(); | ||
| 218 | -// if (StrUtil.isBlank(pluginId)) { | ||
| 219 | -// throw exception(PLUGIN_INFO_NOT_EXISTS); | ||
| 220 | -// } | ||
| 221 | -// com.gitee.starblues.core.PluginInfo pluginInfo = pluginOperator.getPluginInfo(pluginId); | ||
| 222 | -// if (pluginInfo != null) { | ||
| 223 | -// if (pluginInfoDo.getStatus().equals(IotPluginStatusEnum.RUNNING.getStatus()) && pluginInfo.getPluginState() != PluginState.STARTED) { | ||
| 224 | -// // 启动插件 | ||
| 225 | -// pluginOperator.start(pluginId); | ||
| 226 | -// } else if (pluginInfoDo.getStatus().equals(IotPluginStatusEnum.STOPPED.getStatus()) && pluginInfo.getPluginState() == PluginState.STARTED) { | ||
| 227 | -// // 停止插件 | ||
| 228 | -// pluginOperator.stop(pluginId); | ||
| 229 | -// } | ||
| 230 | -// } else { | ||
| 231 | -// // 已经停止,未获取到插件 | ||
| 232 | -// if (IotPluginStatusEnum.STOPPED.getStatus().equals(pluginInfoDo.getStatus())) { | ||
| 233 | -// throw exception(PLUGIN_STATUS_INVALID); | ||
| 234 | -// } | ||
| 235 | -// } | 203 | + String pluginId = pluginInfoDo.getPluginId(); |
| 204 | + PluginWrapper plugin = pluginManager.getPlugin(pluginId); | ||
| 205 | + if (plugin != null) { | ||
| 206 | + if (status.equals(IotPluginStatusEnum.RUNNING.getStatus()) && plugin.getPluginState() != PluginState.STARTED) { | ||
| 207 | + // 启动插件 | ||
| 208 | + pluginManager.startPlugin(pluginId); | ||
| 209 | + } else if (status.equals(IotPluginStatusEnum.STOPPED.getStatus()) && plugin.getPluginState() == PluginState.STARTED) { | ||
| 210 | + // 停止插件 | ||
| 211 | + pluginManager.stopPlugin(pluginId); | ||
| 212 | + } | ||
| 213 | + } else { | ||
| 214 | + // 已经停止,未获取到插件 | ||
| 215 | + if (IotPluginStatusEnum.STOPPED.getStatus().equals(pluginInfoDo.getStatus())) { | ||
| 216 | + throw exception(PLUGIN_STATUS_INVALID); | ||
| 217 | + } | ||
| 218 | + } | ||
| 236 | pluginInfoDo.setStatus(status); | 219 | pluginInfoDo.setStatus(status); |
| 237 | pluginInfoMapper.updateById(pluginInfoDo); | 220 | pluginInfoMapper.updateById(pluginInfoDo); |
| 238 | } | 221 | } |
| @@ -244,20 +227,13 @@ public class PluginInfoServiceImpl implements PluginInfoService { | @@ -244,20 +227,13 @@ public class PluginInfoServiceImpl implements PluginInfoService { | ||
| 244 | 227 | ||
| 245 | @SneakyThrows | 228 | @SneakyThrows |
| 246 | private void startPlugins() { | 229 | private void startPlugins() { |
| 247 | -// while (!pluginOperator.inited()) { | ||
| 248 | -// Thread.sleep(1000L); | ||
| 249 | -// } | ||
| 250 | - | ||
| 251 | for (PluginInfoDO pluginInfoDO : pluginInfoMapper.selectList()) { | 230 | for (PluginInfoDO pluginInfoDO : pluginInfoMapper.selectList()) { |
| 252 | if (!IotPluginStatusEnum.RUNNING.getStatus().equals(pluginInfoDO.getStatus())) { | 231 | if (!IotPluginStatusEnum.RUNNING.getStatus().equals(pluginInfoDO.getStatus())) { |
| 253 | continue; | 232 | continue; |
| 254 | } | 233 | } |
| 255 | log.info("start plugin:{}", pluginInfoDO.getPluginId()); | 234 | log.info("start plugin:{}", pluginInfoDO.getPluginId()); |
| 256 | try { | 235 | try { |
| 257 | -// com.gitee.starblues.core.PluginInfo plugin = pluginOperator.getPluginInfo(pluginInfoDO.getPluginId()); | ||
| 258 | -// if (plugin != null) { | ||
| 259 | -// pluginOperator.start(plugin.getPluginId()); | ||
| 260 | -// } | 236 | + pluginManager.startPlugin(pluginInfoDO.getPluginId()); |
| 261 | } catch (Exception e) { | 237 | } catch (Exception e) { |
| 262 | log.error("start plugin error", e); | 238 | log.error("start plugin error", e); |
| 263 | } | 239 | } |
yudao-module-iot/yudao-module-iot-plugin-api/pom.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 5 | + <modelVersion>4.0.0</modelVersion> | ||
| 6 | + <groupId>cn.iocoder.boot</groupId> | ||
| 7 | + <artifactId>yudao-module-iot-plugin-api</artifactId> | ||
| 8 | + <version>0.0.1</version> | ||
| 9 | + <packaging>jar</packaging> | ||
| 10 | + | ||
| 11 | + <name>${project.artifactId}</name> | ||
| 12 | + <description> | ||
| 13 | + 物联网 模块插件 API,暴露给其它模块调用 | ||
| 14 | + </description> | ||
| 15 | + | ||
| 16 | + <properties> | ||
| 17 | + <pf4j-spring.version>0.9.0</pf4j-spring.version> | ||
| 18 | + </properties> | ||
| 19 | + | ||
| 20 | + <dependencies> | ||
| 21 | + <!-- PF4J Spring 集成 --> | ||
| 22 | + <dependency> | ||
| 23 | + <groupId>org.pf4j</groupId> | ||
| 24 | + <artifactId>pf4j-spring</artifactId> | ||
| 25 | + <version>${pf4j-spring.version}</version> | ||
| 26 | + <scope>provided</scope> | ||
| 27 | + </dependency> | ||
| 28 | + </dependencies> | ||
| 29 | + | ||
| 30 | +</project> |
yudao-module-iot/yudao-module-iot-plugin-api/src/main/java/cn/iocoder/yudao/module/iot/api/Greeting.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright (C) 2012-present the original author or authors. | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package cn.iocoder.yudao.module.iot.api; | ||
| 17 | + | ||
| 18 | +import org.pf4j.ExtensionPoint; | ||
| 19 | + | ||
| 20 | +/** | ||
| 21 | + * @author Decebal Suiu | ||
| 22 | + */ | ||
| 23 | +public interface Greeting extends ExtensionPoint { | ||
| 24 | + | ||
| 25 | + String getGreeting(); | ||
| 26 | + | ||
| 27 | +} |
yudao-module-iot/yudao-module-iot-plugin/src/main/java/cn/iocoder/yudao/module/iot/plugin/package-info.java renamed to yudao-module-iot/yudao-module-iot-plugin-api/src/main/java/cn/iocoder/yudao/module/iot/api/package-info.java
yudao-module-iot/yudao-module-iot-plugin/plugin.properties
0 → 100644
yudao-module-iot/yudao-module-iot-plugin/pom.xml
| 1 | <?xml version="1.0" encoding="UTF-8"?> | 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | -<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 5 | - <parent> | ||
| 6 | - <artifactId>yudao-module-iot</artifactId> | ||
| 7 | - <groupId>cn.iocoder.boot</groupId> | ||
| 8 | - <version>${revision}</version> | ||
| 9 | - </parent> | 2 | +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| 3 | + xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation=" | ||
| 4 | + http://maven.apache.org/POM/4.0.0 | ||
| 5 | + http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 10 | <modelVersion>4.0.0</modelVersion> | 6 | <modelVersion>4.0.0</modelVersion> |
| 7 | + <groupId>cn.iocoder.boot</groupId> | ||
| 11 | <artifactId>yudao-module-iot-plugin</artifactId> | 8 | <artifactId>yudao-module-iot-plugin</artifactId> |
| 9 | + <version>0.0.1</version> | ||
| 12 | <packaging>jar</packaging> | 10 | <packaging>jar</packaging> |
| 13 | 11 | ||
| 14 | <name>${project.artifactId}</name> | 12 | <name>${project.artifactId}</name> |
| 15 | - <description> | ||
| 16 | - 物联网 模块 - 插件 | ||
| 17 | - </description> | 13 | + <description>物联网 模块 - 插件</description> |
| 14 | + | ||
| 15 | + <properties> | ||
| 16 | + <!-- 插件相关 --> | ||
| 17 | + <plugin.id>iot-plugin-http</plugin.id> | ||
| 18 | + <plugin.class>cn.iocoder.yudao.module.iot.plugin.WelcomePlugin</plugin.class> | ||
| 19 | + <plugin.version>0.0.1</plugin.version> | ||
| 20 | + <plugin.provider>ahh</plugin.provider> | ||
| 21 | + <plugin.dependencies/> | ||
| 22 | + | ||
| 23 | + <!-- Maven 相关 --> | ||
| 24 | + <java.version>17</java.version> | ||
| 25 | + <maven.compiler.source>${java.version}</maven.compiler.source> | ||
| 26 | + <maven.compiler.target>${java.version}</maven.compiler.target> | ||
| 27 | + <maven-antrun-plugin.version>1.6</maven-antrun-plugin.version> | ||
| 28 | + <maven-assembly-plugin.version>2.3</maven-assembly-plugin.version> | ||
| 29 | + <maven-jar-plugin.version>2.4</maven-jar-plugin.version> | ||
| 30 | + <pf4j-spring.version>0.9.0</pf4j-spring.version> | ||
| 31 | + <!-- 看看咋放到 bom 里 --> | ||
| 32 | + <spring.boot.version>3.3.1</spring.boot.version> | ||
| 33 | + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
| 34 | + </properties> | ||
| 18 | 35 | ||
| 19 | <dependencies> | 36 | <dependencies> |
| 37 | + <!-- 其他依赖项 --> | ||
| 20 | <dependency> | 38 | <dependency> |
| 21 | - <groupId>cn.iocoder.boot</groupId> | ||
| 22 | - <artifactId>yudao-common</artifactId> | 39 | + <groupId>org.springframework.boot</groupId> |
| 40 | + <artifactId>spring-boot-starter-web</artifactId> | ||
| 41 | + <version>${spring.boot.version}</version> | ||
| 42 | + <scope>provided</scope> | ||
| 23 | </dependency> | 43 | </dependency> |
| 24 | - | 44 | + <!-- PF4J Spring 集成 --> |
| 25 | <dependency> | 45 | <dependency> |
| 26 | <groupId>org.pf4j</groupId> | 46 | <groupId>org.pf4j</groupId> |
| 27 | <artifactId>pf4j-spring</artifactId> | 47 | <artifactId>pf4j-spring</artifactId> |
| 48 | + <version>${pf4j-spring.version}</version> | ||
| 49 | + <scope>provided</scope> | ||
| 50 | + </dependency> | ||
| 51 | + <!-- 项目依赖 --> | ||
| 52 | + <dependency> | ||
| 53 | + <groupId>cn.iocoder.boot</groupId> | ||
| 54 | + <artifactId>yudao-module-iot-plugin-api</artifactId> | ||
| 55 | + <version>${project.version}</version> | ||
| 28 | </dependency> | 56 | </dependency> |
| 29 | </dependencies> | 57 | </dependencies> |
| 30 | 58 | ||
| 31 | -</project> | 59 | + <build> |
| 60 | + <plugins> | ||
| 61 | + <!-- DOESN'T WORK WITH MAVEN 3 (I defined the plugin metadata in properties section) | ||
| 62 | + <plugin> | ||
| 63 | + <groupId>org.codehaus.mojo</groupId> | ||
| 64 | + <artifactId>properties-maven-plugin</artifactId> | ||
| 65 | + <version>1.0-alpha-2</version> | ||
| 66 | + <executions> | ||
| 67 | + <execution> | ||
| 68 | + <phase>initialize</phase> | ||
| 69 | + <goals> | ||
| 70 | + <goal>read-project-properties</goal> | ||
| 71 | + </goals> | ||
| 72 | + <configuration> | ||
| 73 | + <files> | ||
| 74 | + <file>plugin.properties</file> | ||
| 75 | + </files> | ||
| 76 | + </configuration> | ||
| 77 | + </execution> | ||
| 78 | + </executions> | ||
| 79 | + </plugin> | ||
| 80 | + --> | ||
| 81 | + | ||
| 82 | + <plugin> | ||
| 83 | + <groupId>org.apache.maven.plugins</groupId> | ||
| 84 | + <artifactId>maven-antrun-plugin</artifactId> | ||
| 85 | + <version>${maven-antrun-plugin.version}</version> | ||
| 86 | + <executions> | ||
| 87 | + <execution> | ||
| 88 | + <id>unzip jar file</id> | ||
| 89 | + <phase>package</phase> | ||
| 90 | + <configuration> | ||
| 91 | + <target> | ||
| 92 | + <unzip src="target/${project.artifactId}-${project.version}.${project.packaging}" dest="target/plugin-classes" /> | ||
| 93 | + </target> | ||
| 94 | + </configuration> | ||
| 95 | + <goals> | ||
| 96 | + <goal>run</goal> | ||
| 97 | + </goals> | ||
| 98 | + </execution> | ||
| 99 | + </executions> | ||
| 100 | + </plugin> | ||
| 101 | + | ||
| 102 | + <plugin> | ||
| 103 | + <artifactId>maven-assembly-plugin</artifactId> | ||
| 104 | + <version>${maven-assembly-plugin.version}</version> | ||
| 105 | + <configuration> | ||
| 106 | + <descriptors> | ||
| 107 | + <descriptor> | ||
| 108 | + src/main/assembly/assembly.xml | ||
| 109 | + </descriptor> | ||
| 110 | + </descriptors> | ||
| 111 | + <appendAssemblyId>false</appendAssemblyId> | ||
| 112 | + </configuration> | ||
| 113 | + <executions> | ||
| 114 | + <execution> | ||
| 115 | + <id>make-assembly</id> | ||
| 116 | + <phase>package</phase> | ||
| 117 | + <goals> | ||
| 118 | + <goal>attached</goal> | ||
| 119 | + </goals> | ||
| 120 | + </execution> | ||
| 121 | + </executions> | ||
| 122 | + </plugin> | ||
| 123 | + | ||
| 124 | + <plugin> | ||
| 125 | + <groupId>org.apache.maven.plugins</groupId> | ||
| 126 | + <artifactId>maven-jar-plugin</artifactId> | ||
| 127 | + <version>${maven-jar-plugin.version}</version> | ||
| 128 | + <configuration> | ||
| 129 | + <archive> | ||
| 130 | + <manifestEntries> | ||
| 131 | + <Plugin-Id>${plugin.id}</Plugin-Id> | ||
| 132 | + <Plugin-Class>${plugin.class}</Plugin-Class> | ||
| 133 | + <Plugin-Version>${plugin.version}</Plugin-Version> | ||
| 134 | + <Plugin-Provider>${plugin.provider}</Plugin-Provider> | ||
| 135 | + <Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies> | ||
| 136 | + </manifestEntries> | ||
| 137 | + </archive> | ||
| 138 | + </configuration> | ||
| 139 | + </plugin> | ||
| 140 | + | ||
| 141 | + <plugin> | ||
| 142 | + <artifactId>maven-deploy-plugin</artifactId> | ||
| 143 | + <configuration> | ||
| 144 | + <skip>true</skip> | ||
| 145 | + </configuration> | ||
| 146 | + </plugin> | ||
| 147 | + </plugins> | ||
| 148 | + </build> | ||
| 149 | +</project> | ||
| 32 | \ No newline at end of file | 150 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-plugin/src/main/assembly/assembly.xml
0 → 100644
| 1 | +<!-- | ||
| 2 | + Describes the plugin archive | ||
| 3 | + | ||
| 4 | + @author Decebal Suiu | ||
| 5 | + @version 1.0 | ||
| 6 | +--> | ||
| 7 | +<assembly> | ||
| 8 | + <id>plugin</id> | ||
| 9 | + <formats> | ||
| 10 | + <format>zip</format> | ||
| 11 | + </formats> | ||
| 12 | + <includeBaseDirectory>false</includeBaseDirectory> | ||
| 13 | + <dependencySets> | ||
| 14 | + <dependencySet> | ||
| 15 | + <useProjectArtifact>false</useProjectArtifact> | ||
| 16 | + <scope>runtime</scope> | ||
| 17 | + <outputDirectory>lib</outputDirectory> | ||
| 18 | + <includes> | ||
| 19 | + <include>*:jar:*</include> | ||
| 20 | + </includes> | ||
| 21 | + </dependencySet> | ||
| 22 | + </dependencySets> | ||
| 23 | + <!-- | ||
| 24 | + <fileSets> | ||
| 25 | + <fileSet> | ||
| 26 | + <directory>target/classes</directory> | ||
| 27 | + <outputDirectory>classes</outputDirectory> | ||
| 28 | + </fileSet> | ||
| 29 | + </fileSets> | ||
| 30 | + --> | ||
| 31 | + <fileSets> | ||
| 32 | + <fileSet> | ||
| 33 | + <directory>target/plugin-classes</directory> | ||
| 34 | + <outputDirectory>classes</outputDirectory> | ||
| 35 | + </fileSet> | ||
| 36 | + </fileSets> | ||
| 37 | +</assembly> |
yudao-module-iot/yudao-module-iot-plugin/src/main/java/cn/iocoder/yudao/module/iot/plugin/IoTHttpPluginController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.plugin; | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +import org.pf4j.Extension; | ||
| 5 | +import org.pf4j.ExtensionPoint; | ||
| 6 | +import org.springframework.web.bind.annotation.*; | ||
| 7 | + | ||
| 8 | +@RestController | ||
| 9 | +@RequestMapping("/iot/plugin-demo") | ||
| 10 | +@Extension | ||
| 11 | +public class IoTHttpPluginController implements ExtensionPoint { | ||
| 12 | + | ||
| 13 | + @GetMapping("/greet") | ||
| 14 | + public String greet() { | ||
| 15 | + return "Hello from MyPlugin!"; | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + @PostMapping("/message") | ||
| 19 | + public void receiveMessage(@RequestBody String message) { | ||
| 20 | + System.out.println("Received message: " + message); | ||
| 21 | + } | ||
| 22 | +} |
yudao-module-iot/yudao-module-iot-plugin/src/main/java/cn/iocoder/yudao/module/iot/plugin/IoTPlugin.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.plugin; | ||
| 2 | + | ||
| 3 | +import org.pf4j.PluginWrapper; | ||
| 4 | +import org.pf4j.spring.SpringPlugin; | ||
| 5 | +import org.springframework.context.ApplicationContext; | ||
| 6 | +import org.springframework.context.annotation.AnnotationConfigApplicationContext; | ||
| 7 | + | ||
| 8 | +public class IoTPlugin extends SpringPlugin { | ||
| 9 | + public IoTPlugin(PluginWrapper wrapper) { | ||
| 10 | + super(wrapper); | ||
| 11 | + } | ||
| 12 | + | ||
| 13 | + @Override | ||
| 14 | + public void start() { | ||
| 15 | + System.out.println("IoTPlugin 启动"); | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + @Override | ||
| 19 | + public void stop() { | ||
| 20 | + System.out.println("IoTPlugin 停止"); | ||
| 21 | + super.stop(); // to close applicationContext | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + @Override | ||
| 25 | + protected ApplicationContext createApplicationContext() { | ||
| 26 | + AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); | ||
| 27 | + applicationContext.setClassLoader(getWrapper().getPluginClassLoader()); | ||
| 28 | + applicationContext.register(IoTHttpPluginController.class); // 注册 IoTPluginConfig | ||
| 29 | + applicationContext.refresh(); | ||
| 30 | + System.out.println("IoTPlugin 加载完成"); | ||
| 31 | + return applicationContext; | ||
| 32 | + } | ||
| 33 | +} |
yudao-module-iot/yudao-module-iot-plugin/src/main/java/cn/iocoder/yudao/module/iot/plugin/IotPluginConfig.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.plugin; | ||
| 2 | + | ||
| 3 | +import org.springframework.context.annotation.ComponentScan; | ||
| 4 | +import org.springframework.context.annotation.Configuration; | ||
| 5 | +import org.springframework.boot.web.server.WebServerFactoryCustomizer; | ||
| 6 | +import org.springframework.boot.web.server.ConfigurableWebServerFactory; | ||
| 7 | +import org.springframework.context.annotation.Bean; | ||
| 8 | + | ||
| 9 | +@Configuration | ||
| 10 | +public class IoTPluginConfig { | ||
| 11 | + | ||
| 12 | + @Bean | ||
| 13 | + public IoTHttpPluginController ioTHttpPluginController() { | ||
| 14 | + return new IoTHttpPluginController(); | ||
| 15 | + } | ||
| 16 | +} |
yudao-module-iot/yudao-module-iot-plugin/src/main/java/cn/iocoder/yudao/module/iot/plugin/WelcomePlugin.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright (C) 2012-present the original author or authors. | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package cn.iocoder.yudao.module.iot.plugin; | ||
| 17 | + | ||
| 18 | +import cn.iocoder.yudao.module.iot.api.Greeting; | ||
| 19 | +import org.apache.commons.lang.StringUtils; | ||
| 20 | +import org.pf4j.Extension; | ||
| 21 | +import org.pf4j.Plugin; | ||
| 22 | +import org.pf4j.PluginWrapper; | ||
| 23 | +import org.pf4j.RuntimeMode; | ||
| 24 | + | ||
| 25 | +/** | ||
| 26 | + * 打招呼 测试用例 | ||
| 27 | + */ | ||
| 28 | +public class WelcomePlugin extends Plugin { | ||
| 29 | + | ||
| 30 | + public WelcomePlugin(PluginWrapper wrapper) { | ||
| 31 | + super(wrapper); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + @Override | ||
| 35 | + public void start() { | ||
| 36 | + System.out.println("WelcomePlugin.start()"); | ||
| 37 | + // for testing the development mode | ||
| 38 | + if (RuntimeMode.DEVELOPMENT.equals(wrapper.getRuntimeMode())) { | ||
| 39 | + System.out.println(StringUtils.upperCase("WelcomePlugin")); | ||
| 40 | + } | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + @Override | ||
| 44 | + public void stop() { | ||
| 45 | + System.out.println("WelcomePlugin.stop()"); | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + @Extension | ||
| 49 | + public static class WelcomeGreeting implements Greeting { | ||
| 50 | + | ||
| 51 | + @Override | ||
| 52 | + public String getGreeting() { | ||
| 53 | + return "Welcome to PF4J"; | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | +} | ||
| 0 | \ No newline at end of file | 59 | \ No newline at end of file |