初步实现插件机制

This commit is contained in:
mxd
2022-01-22 22:40:39 +08:00
parent e6578fc3b3
commit 5710801fda
75 changed files with 985 additions and 469 deletions

View File

@@ -0,0 +1,28 @@
package org.ssssssss.magicapi.cluster;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.UUID;
/**
* 集群配置
*
* @author mxd
* @since 1.2.0
*/
@ConfigurationProperties(prefix = "magic-api.cluster")
public class ClusterConfig {
/**
* redis 通道
*/
private String channel = "magic-api:notify:channel";
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
}

View File

@@ -0,0 +1,79 @@
package org.ssssssss.magicapi.cluster;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.ssssssss.magicapi.core.config.MagicAPIProperties;
import org.ssssssss.magicapi.core.config.MagicPluginConfiguration;
import org.ssssssss.magicapi.core.model.MagicNotify;
import org.ssssssss.magicapi.core.model.Plugin;
import org.ssssssss.magicapi.core.service.MagicAPIService;
import org.ssssssss.magicapi.core.service.MagicNotifyService;
import org.ssssssss.magicapi.utils.JsonUtils;
import java.util.Objects;
@EnableConfigurationProperties(ClusterConfig.class)
@Configuration
public class MagicClusterConfiguration implements MagicPluginConfiguration {
private final ClusterConfig config;
private final MagicAPIProperties properties;
private final StringRedisTemplate stringRedisTemplate;
private final Logger logger = LoggerFactory.getLogger(MagicClusterConfiguration.class);
public MagicClusterConfiguration(MagicAPIProperties properties, ClusterConfig config, ObjectProvider<StringRedisTemplate> stringRedisTemplateProvider) {
this.properties = properties;
this.config = config;
this.stringRedisTemplate = stringRedisTemplateProvider.getIfAvailable();
}
@Override
public Plugin plugin() {
return new Plugin("Cluster");
}
/**
* 使用Redis推送通知
*/
@Bean
@ConditionalOnMissingBean
public MagicNotifyService magicNotifyService() {
return magicNotify -> stringRedisTemplate.convertAndSend(config.getChannel(), Objects.requireNonNull(JsonUtils.toJsonString(magicNotify)));
}
/**
* 消息处理服务
*/
@Bean
@ConditionalOnMissingBean
public MagicSynchronizationService magicSynchronizationService(MagicNotifyService magicNotifyService) {
return new MagicSynchronizationService(magicNotifyService, properties.getInstanceId());
}
/**
* 集群通知监听
*/
@Bean
public RedisMessageListenerContainer magicRedisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory, MagicAPIService magicAPIService) {
logger.info("开启集群通知监听, Redis channel: {}", config.getChannel());
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
redisMessageListenerContainer.addMessageListener((message, pattern) -> magicAPIService.processNotify(JsonUtils.readValue(message.getBody(), MagicNotify.class)), ChannelTopic.of(config.getChannel()));
return redisMessageListenerContainer;
}
}

View File

@@ -0,0 +1,54 @@
package org.ssssssss.magicapi.cluster;
import org.springframework.context.event.EventListener;
import org.ssssssss.magicapi.core.event.*;
import org.ssssssss.magicapi.core.config.Constants;
import org.ssssssss.magicapi.core.model.MagicNotify;
import org.ssssssss.magicapi.core.service.MagicNotifyService;
public class MagicSynchronizationService {
private final MagicNotifyService magicNotifyService;
/**
* 当前实例ID
*/
private final String instanceId;
public MagicSynchronizationService(MagicNotifyService magicNotifyService, String instanceId) {
this.magicNotifyService = magicNotifyService;
this.instanceId = instanceId;
}
@EventListener(condition = "#event.source != T(org.ssssssss.magicapi.core.config.Constants).EVENT_SOURCE_NOTIFY")
public void onFolderEvent(GroupEvent event) {
switch (event.getAction()) {
case CREATE:
case SAVE:
case MOVE:
case DELETE:
magicNotifyService.sendNotify(new MagicNotify(instanceId, event.getGroup().getId(), event.getAction(), event.getType()));
break;
}
}
@EventListener(condition = "#event.source != T(org.ssssssss.magicapi.core.config.Constants).EVENT_SOURCE_NOTIFY")
public void onFileEvent(FileEvent event) {
if (Constants.EVENT_SOURCE_NOTIFY.equals(event.getSource())) {
return;
}
switch (event.getAction()) {
case CREATE:
case SAVE:
case MOVE:
case DELETE:
magicNotifyService.sendNotify(new MagicNotify(instanceId, event.getEntity().getId(), event.getAction(), Constants.EVENT_TYPE_FILE));
break;
}
}
@EventListener(condition = "#event.action == T(org.ssssssss.magicapi.core.event.EventAction).CLEAR && #event.source != T(org.ssssssss.magicapi.core.config.Constants).EVENT_SOURCE_NOTIFY")
public void onClearEvent(MagicEvent event){
magicNotifyService.sendNotify(new MagicNotify(instanceId, null, event.getAction(), null));
}
}

View File

@@ -0,0 +1 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ssssssss.magicapi.cluster.MagicClusterConfiguration