Skip to content

Commit

Permalink
支持重复安装插件,通过'#'分隔插件副本,插件服务和配置的Key信息携带类加载器
Browse files Browse the repository at this point in the history
  • Loading branch information
luanwenfei-venus committed Oct 18, 2023
1 parent 6b19b6b commit cdc1f25
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ public static void initPlugins(Set<String> pluginNames, boolean isDynamic) {
continue;
}
try {
final String pluginPath = pluginPackage + File.separatorChar + pluginName;
// 通过形如 plugin-name#1 plugin-name#2 方式标记插件副本,共用资源文件
final String pluginPath = pluginPackage + File.separatorChar + pluginName.split("#")[0];
if (!new File(pluginPath).exists()) {
LOGGER.log(Level.WARNING, "Plugin directory {0} does not exist, so skip initializing {1}. ",
new String[]{pluginPath, pluginName});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ public static boolean checkSchema(String name, JarFile jarFile) throws IOExcepti
if (nameAttr == null) {
return false;
}
if (!nameAttr.toString().equals(name)) {
String realPluginName = name.split("#")[0];
if (!nameAttr.toString().equals(realPluginName)) {
throw new SchemaException(SchemaException.UNEXPECTED_NAME, nameAttr.toString(), name);
}
final Object versionAttr = JarFileUtils.getManifestAttr(jarFile, PluginConstant.PLUGIN_VERSION_KEY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,28 +63,29 @@ public static void loadPluginConfigs(Plugin plugin) {
ClassLoader classLoader =
plugin.getServiceClassLoader() != null ? plugin.getServiceClassLoader() : plugin.getPluginClassLoader();
for (BaseConfig config : ServiceLoader.load(PluginConfig.class, classLoader)) {
final String typeKey = ConfigKeyUtil.getTypeKey(config.getClass());
final BaseConfig retainedConfig = PLUGIN_CONFIG_MAP.get(typeKey);
Class<? extends BaseConfig> pluginConfigCls = config.getClass();
String pluginConfigKey = ConfigKeyUtil.getTypeKey(pluginConfigCls) + "_" + pluginConfigCls.getClassLoader();
final BaseConfig retainedConfig = PLUGIN_CONFIG_MAP.get(pluginConfigKey);
if (pluginConfigFile.exists() && pluginConfigFile.isFile()) {
if (retainedConfig == null) {
PLUGIN_CONFIG_MAP.put(typeKey, ConfigManager.doLoad(pluginConfigFile, config));
plugin.getConfigs().add(typeKey);
} else if (retainedConfig.getClass() == config.getClass()) {
PLUGIN_CONFIG_MAP.put(pluginConfigKey, ConfigManager.doLoad(pluginConfigFile, config));
plugin.getConfigs().add(pluginConfigKey);
} else if (retainedConfig.getClass() == pluginConfigCls) {
LOGGER.fine(String.format(Locale.ROOT, "Skip load config [%s] repeatedly. ",
config.getClass().getName()));
pluginConfigCls.getName()));
} else {
LOGGER.warning(String.format(Locale.ROOT, "Type key of %s is %s, same as %s's. ",
config.getClass().getName(), typeKey, retainedConfig.getClass().getName()));
pluginConfigCls.getName(), pluginConfigKey, retainedConfig.getClass().getName()));
}
continue;
}
if (PLUGIN_CONFIG_MAP.containsKey(typeKey)) {
if (PLUGIN_CONFIG_MAP.containsKey(pluginConfigKey)) {
continue;
}

// 不能从文件加载,则为默认配置
PLUGIN_CONFIG_MAP.put(typeKey, config);
plugin.getConfigs().add(typeKey);
PLUGIN_CONFIG_MAP.put(pluginConfigKey, config);
plugin.getConfigs().add(pluginConfigKey);
}
}

Expand All @@ -107,7 +108,8 @@ public static void cleanPluginConfigs(Plugin plugin) {
* @return 插件配置实例
*/
public static <R extends PluginConfig> R getPluginConfig(Class<R> cls) {
return (R) PLUGIN_CONFIG_MAP.get(ConfigKeyUtil.getTypeKey(cls));
String pluginConfigKey = ConfigKeyUtil.getTypeKey(cls) + "_" + cls.getClassLoader();
return (R) PLUGIN_CONFIG_MAP.get(pluginConfigKey);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ public static void initPluginServices(Plugin plugin) {
for (PluginService service : ServiceLoader.load(PluginService.class, classLoader)) {
if (loadService(service, service.getClass(), PluginService.class)) {
try {
String serviceName = service.getClass().getName();
String pluginServiceKey = service.getClass().getName() + "_" + service.getClass().getClassLoader();
service.start();
plugin.getServices().add(serviceName);
plugin.getServices().add(pluginServiceKey);
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, "Error occurs while starting plugin service: " + service.getClass(), ex);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ public static void initServices() {
* @throws IllegalArgumentException IllegalArgumentException 找不到对应的服务
*/
public static <T extends BaseService> T getService(Class<T> serviceClass) {
final BaseService baseService = SERVICES.get(serviceClass.getName());
String serviceKey = serviceClass.getName() + "_" + serviceClass.getClassLoader();
final BaseService baseService = SERVICES.get(serviceKey);
if (baseService != null && serviceClass.isAssignableFrom(baseService.getClass())) {
return (T) baseService;
}
Expand All @@ -141,8 +142,8 @@ protected static boolean loadService(BaseService service, Class<?> serviceCls,
if (serviceCls == null || serviceCls == baseCls || !baseCls.isAssignableFrom(serviceCls)) {
return false;
}
final String serviceName = serviceCls.getName();
final BaseService oldService = SERVICES.get(serviceName);
final String serviceKey = serviceCls.getName() + "_" + serviceCls.getClassLoader();
final BaseService oldService = SERVICES.get(serviceKey);
if (oldService != null && oldService.getClass() == service.getClass()) {
return false;
}
Expand All @@ -151,11 +152,11 @@ protected static boolean loadService(BaseService service, Class<?> serviceCls,
SpiLoadUtils.getBetter(oldService, service, new SpiLoadUtils.WeightEqualHandler<BaseService>() {
@Override
public BaseService handle(BaseService source, BaseService target) {
throw new DupServiceException(serviceName);
throw new DupServiceException(serviceKey);
}
});
if (betterService != oldService) {
SERVICES.put(serviceName, service);
SERVICES.put(serviceKey, service);
isLoadSucceed = true;
}
isLoadSucceed |= loadService(service, serviceCls.getSuperclass(), baseCls);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ public NacosRegistryFactoryTest() throws NoSuchFieldException, IllegalAccessExce
Field field = ServiceManager.class.getDeclaredField("SERVICES");
field.setAccessible(true);
Map<String, BaseService> map = (Map<String, BaseService>) field.get(null);
map.put(NacosRegistryService.class.getCanonicalName(), new NacosRegistryService() {
map.put(NacosRegistryService.class.getCanonicalName() + "_" + NacosRegistryService.class.getClassLoader(),
new NacosRegistryService() {

@Override
public void doRegister(Object url) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public RegistryFactoryTest() throws NoSuchFieldException, IllegalAccessException
Field field = ServiceManager.class.getDeclaredField("SERVICES");
field.setAccessible(true);
Map<String, BaseService> map = (Map<String, BaseService>) field.get(null);
map.put(RegistryService.class.getCanonicalName(), new RegistryService() {
map.put(RegistryService.class.getCanonicalName() + "_" + RegistryService.class.getClassLoader(), new RegistryService() {
@Override
public void startRegistration() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
package com.huawei.registry.service.client;

import com.huawei.registry.config.RegisterConfig;

import com.huawei.registry.config.RegisterServiceCommonConfig;

import com.huaweicloud.sermant.core.config.ConfigManager;
import com.huaweicloud.sermant.core.config.common.BaseConfig;
import com.huaweicloud.sermant.core.plugin.config.PluginConfigManager;
Expand Down Expand Up @@ -49,15 +49,16 @@ public static void init() throws IllegalAccessException, NoSuchFieldException, C
removeFinalModify(configMap);

configManagerMap = (Map<String, BaseConfig>) configMap.get(null);
configManagerMap.put("servicecomb.service", new RegisterConfig());
configManagerMap.put("register.service", new RegisterServiceCommonConfig());
configManagerMap.put("servicecomb.service" + "_" + RegisterConfig.class.getClassLoader(), new RegisterConfig());
configManagerMap.put("register.service" + "_" + RegisterServiceCommonConfig.class.getClassLoader(),
new RegisterServiceCommonConfig());
}

/**
* 移除final修饰符
*
* @param field 字段
* @throws NoSuchFieldException 无该字段抛出
* @throws NoSuchFieldException 无该字段抛出
* @throws IllegalAccessException 无法拿到该字段抛出
*/
protected static void removeFinalModify(Field field) throws NoSuchFieldException, IllegalAccessException {
Expand Down

0 comments on commit cdc1f25

Please sign in to comment.