mirror of https://github.com/halo-dev/halo
feat: add plugin unstructured resource loader (#2154)
* feat: add plugin unstructured resource loader * feat: add test unit casepull/2158/head
parent
6bbaa9aeba
commit
83d668b0a9
|
@ -82,8 +82,6 @@ public class HaloPluginManager extends DefaultPluginManager
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
// This method load, start plugins and inject extensions in Spring
|
|
||||||
loadPlugins();
|
|
||||||
this.pluginApplicationInitializer = new PluginApplicationInitializer(this);
|
this.pluginApplicationInitializer = new PluginApplicationInitializer(this);
|
||||||
|
|
||||||
this.requestMappingManager =
|
this.requestMappingManager =
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package run.halo.app.plugin;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load plugins after application ready.
|
||||||
|
*
|
||||||
|
* @author guqing
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class PluginInitializationLoadOnApplicationReady
|
||||||
|
implements ApplicationListener<ApplicationReadyEvent> {
|
||||||
|
|
||||||
|
private final HaloPluginManager haloPluginManager;
|
||||||
|
|
||||||
|
public PluginInitializationLoadOnApplicationReady(HaloPluginManager haloPluginManager) {
|
||||||
|
this.haloPluginManager = haloPluginManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||||
|
haloPluginManager.loadPlugins();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package run.halo.app.plugin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import org.pf4j.PluginRuntimeException;
|
||||||
|
import org.pf4j.PluginWrapper;
|
||||||
|
import org.springframework.core.io.DefaultResourceLoader;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
|
import run.halo.app.extension.Unstructured;
|
||||||
|
import run.halo.app.infra.utils.YamlUnstructuredLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plug in unstructured data loader.
|
||||||
|
* TODO Rename this class to an appropriate name.
|
||||||
|
*
|
||||||
|
* @author guqing
|
||||||
|
* @see YamlUnstructuredLoader
|
||||||
|
* @see PluginWrapper
|
||||||
|
* @see DefaultResourceLoader
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
public class PluginUnstructuredResourceLoader {
|
||||||
|
private static final String DEFAULT_RESOURCE_LOCATION = "extensions/";
|
||||||
|
private final String resourceLocation;
|
||||||
|
|
||||||
|
public PluginUnstructuredResourceLoader() {
|
||||||
|
resourceLocation = DEFAULT_RESOURCE_LOCATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginUnstructuredResourceLoader(String resourceLocation) {
|
||||||
|
this.resourceLocation = resourceLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loading unstructured yaml configuration files in plugins.
|
||||||
|
*
|
||||||
|
* @param pluginWrapper Wrapper object holding plugin data
|
||||||
|
* @return a collection of {@link Unstructured} data(never null)
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public List<Unstructured> loadUnstructured(PluginWrapper pluginWrapper) {
|
||||||
|
List<String> unstructuredFilePaths =
|
||||||
|
getUnstructuredFilePathFromJar(pluginWrapper.getPluginPath());
|
||||||
|
|
||||||
|
DefaultResourceLoader resourceLoader =
|
||||||
|
new DefaultResourceLoader(pluginWrapper.getPluginClassLoader());
|
||||||
|
Resource[] resources = unstructuredFilePaths.stream()
|
||||||
|
.map(resourceLoader::getResource)
|
||||||
|
.filter(Resource::exists)
|
||||||
|
.toArray(Resource[]::new);
|
||||||
|
|
||||||
|
YamlUnstructuredLoader yamlUnstructuredLoader = new YamlUnstructuredLoader(resources);
|
||||||
|
return yamlUnstructuredLoader.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Lists the path of the unstructured yaml configuration file from the plugin jar.</p>
|
||||||
|
*
|
||||||
|
* @param jarPath plugin jar path
|
||||||
|
* @return Unstructured file paths relative to plugin classpath
|
||||||
|
* @throws PluginRuntimeException If loading the file fails
|
||||||
|
*/
|
||||||
|
public List<String> getUnstructuredFilePathFromJar(Path jarPath) {
|
||||||
|
try (JarFile jarFile = new JarFile(jarPath.toFile())) {
|
||||||
|
return jarFile.stream()
|
||||||
|
.filter(jarEntry -> {
|
||||||
|
String name = jarEntry.getName();
|
||||||
|
return name.startsWith(resourceLocation)
|
||||||
|
&& !jarEntry.isDirectory()
|
||||||
|
&& isYamlFile(name);
|
||||||
|
})
|
||||||
|
.map(ZipEntry::getName)
|
||||||
|
.toList();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new PluginRuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isYamlFile(String path) {
|
||||||
|
return path.endsWith(".yaml") || path.endsWith(".yml");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package run.halo.app.plugin;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.util.ResourceUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link PluginUnstructuredResourceLoader}.
|
||||||
|
*
|
||||||
|
* @author guqing
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
class PluginUnstructuredResourceLoaderTest {
|
||||||
|
|
||||||
|
private PluginUnstructuredResourceLoader unstructuredResourceLoader;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
unstructuredResourceLoader = new PluginUnstructuredResourceLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getUnstructuredFilePathFromJar() throws FileNotFoundException {
|
||||||
|
File file = ResourceUtils.getFile("classpath:plugin/test-unstructured-resource-loader.jar");
|
||||||
|
List<String> unstructuredFilePathFromJar =
|
||||||
|
unstructuredResourceLoader.getUnstructuredFilePathFromJar(file.toPath());
|
||||||
|
assertThat(unstructuredFilePathFromJar).hasSize(3);
|
||||||
|
assertThat(unstructuredFilePathFromJar).contains("extensions/roles.yaml",
|
||||||
|
"extensions/reverseProxy.yaml", "extensions/test.yml");
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Loading…
Reference in New Issue