feat: 核心模块实现

This commit is contained in:
椰子 2021-07-02 13:11:50 +08:00
parent 5c34975b81
commit 216a059169
15 changed files with 587 additions and 0 deletions

View File

@ -0,0 +1,27 @@
package com.cicdi.notify;
import com.cicdi.notify.template.Template;
import com.cicdi.notify.template.TemplateManager;
import java.util.Map;
/**
* @author xueye
*/
public abstract class AbstractNotifier<T extends Template> implements Notifier<T> {
private final TemplateManager templateManager;
public AbstractNotifier(TemplateManager templateManager) {
this.templateManager = templateManager;
}
@Override
public void send(String templateId, Map<String, Object> context) {
Template template = templateManager.getTemplate(this.getType(), templateId);
if (null == template) {
throw new UnsupportedOperationException("模版不存在:" + templateId);
}
this.send((T) template, context);
}
}

View File

@ -0,0 +1,68 @@
package com.cicdi.notify;
import com.cicdi.notify.template.Template;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author xueye
*/
public class DefaultNotifierManager implements NotifierManager {
private final Map<String, Map<String, NotifierProvider>> providers = new ConcurrentHashMap<>();
private Map<String, Notifier> notifiers = new ConcurrentHashMap<>();
private NotifyConfigManager configManager;
// private EventBus eventBus;
public DefaultNotifierManager(NotifyConfigManager manager/*, EventBus eventBus*/) {
this.configManager = manager;
// this.eventBus = eventBus;
}
protected NotifierProperties getProperties(NotifyType notifyType, String id) {
return configManager.getNotifyConfig(notifyType, id);
}
public void reload(String id) {
Notifier notifier = notifiers.remove(id);
if (null != notifier) {
notifier.close();
}
}
protected Notifier createNotifier(NotifierProperties properties) {
Map<String, NotifierProvider> providerMap = providers.get(properties.getType());
if (null == providerMap) {
throw new UnsupportedOperationException("不支持的通知类型: " + properties.getType());
}
NotifierProvider provider = providerMap.get(properties.getProvider());
if (null == provider) {
throw new UnsupportedOperationException("不支持的服务商: " + properties.getProvider());
}
Notifier<? extends Template> notifier1 = provider.createNotifier(properties);
Notifier notifier2 = notifiers.put(properties.getId(), notifier1);
if (null != notifier2) {
notifier2.close();
}
return notifier1;
}
@Override
public Notifier getNotifier(NotifyType type, String id) {
Notifier notifier = notifiers.get(id);
if (null == notifier) {
notifier = createNotifier(getProperties(type, id));
}
return notifier;
}
@Override
public void registerProvider(NotifierProvider provider) {
providers.computeIfAbsent(provider.getType().getId(), ignore -> new ConcurrentHashMap<>())
.put(provider.getProvider().getId(), provider);
}
}

View File

@ -0,0 +1,29 @@
package com.cicdi.notify;
/**
* 默认通知类型
*
* @author xueye
*/
public enum DefaultNotifyType implements NotifyType {
email("邮件"),
;
private final String name;
DefaultNotifyType(String name) {
this.name = name;
}
@Override
public String getId() {
return name();
}
@Override
public String getName() {
return name;
}
}

View File

@ -0,0 +1,55 @@
package com.cicdi.notify;
import com.cicdi.notify.template.Template;
import java.util.Map;
/**
* 通知器
*
* @param <T> 通知模板
* @author xueye
*/
public interface Notifier<T extends Template> {
/**
* @return 通知器唯一标识
*/
String getNotifierId();
/**
* @return 通知器类型
* @see NotifyType
*/
NotifyType getType();
/**
* @return 通知提供商
*/
Provider getProvider();
/**
* 指定模板ID进行发送
*
* @param templateId 模板唯一标识
* @param context 上下文
*/
void send(String templateId, Map<String, Object> context);
/**
* 指定模板进行发送
*
* @param template 通知模板
* @param context 上下文
*/
void send(T template, Map<String, Object> context);
/**
* 关闭通知器
*/
void close();
default <R extends Notifier<T>> R unwrap(Class<R> type) {
return type.cast(this);
}
}

View File

@ -0,0 +1,28 @@
package com.cicdi.notify;
import com.cicdi.notify.template.Template;
/**
* 通知器管理
*
* @author xueye
*/
public interface NotifierManager {
/**
* @param type 通知类型 {@link NotifyType}
* @param id 唯一标识
* @param <T> 模板类型
* @return 通知器
*/
<T extends Template> Notifier<T> getNotifier(NotifyType type, String id);
/**
* 重新加载通知管理器
*
* @param id 通知管理器ID
*/
void reload(String id);
void registerProvider(NotifierProvider provider);
}

View File

@ -0,0 +1,94 @@
package com.cicdi.notify;
import java.util.Map;
import java.util.Optional;
/**
* 通知器属性
*
* @author xueye
*/
public class NotifierProperties {
/**
* 唯一标识
*/
private String id;
/**
* 通知类型标识
*
* @see NotifyType
*/
private String type;
/**
* 通知服务提供商标识,: aliyun ...
*/
private String provider;
/**
* 配置名称
*/
private String name;
/**
* 配置内容,不同的服务提供商,配置不同.
*
* @see NotifierProvider
*/
private Map<String, Object> configuration;
public Optional<Object> getConfig(String key) {
return Optional.ofNullable(configuration)
.map(conf -> conf.get(key));
}
public Object getConfigOrNull(String key) {
return Optional.ofNullable(configuration)
.map(conf -> conf.get(key))
.orElse(null);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getProvider() {
return provider;
}
public void setProvider(String provider) {
this.provider = provider;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, Object> getConfiguration() {
return configuration;
}
public void setConfiguration(Map<String, Object> configuration) {
this.configuration = configuration;
}
}

View File

@ -0,0 +1,40 @@
package com.cicdi.notify;
import com.cicdi.notify.template.Template;
/**
* 通知器提供商
*
* @author xueye
*/
public interface NotifierProvider {
/**
* 获取通知类型
*
* @return 通知类型
* @see NotifyType
*/
NotifyType getType();
/**
* @return 服务商
*/
Provider getProvider();
/**
* 根据配置创建通知器
*
* @param properties 通知配置
* @return 创建结果
*/
Notifier<? extends Template> createNotifier(NotifierProperties properties);
// /**
// * 获取通知配置元数据,通过元数据可以知道此通知所需要的配置信息
// *
// * @return 配置元数据
// */
// default ConfigMetadata getNotifierConfigMetadata() {
// return null;
// }
}

View File

@ -0,0 +1,19 @@
package com.cicdi.notify;
/**
* 通知器配置管理
*
* @author xueye
*/
public interface NotifyConfigManager {
/**
* 根据类型和配置ID获取通知器配置
*
* @param notifyType 通知器类型 {@link NotifyType}
* @param configId 通知器配置ID
* @return 通知器配置
*/
NotifierProperties getNotifyConfig(NotifyType notifyType, String configId);
}

View File

@ -0,0 +1,20 @@
package com.cicdi.notify;
/**
* 通知器类型
*
* @author xueye
*/
public interface NotifyType {
/**
* @return 唯一标识
*/
String getId();
/**
* @return 通知器名称
*/
String getName();
}

View File

@ -0,0 +1,20 @@
package com.cicdi.notify;
/**
* 提供商标识
*
* @author xueye
*/
public interface Provider {
/**
* @return 唯一标识
*/
String getId();
/**
* @return 提供商名称
*/
String getName();
}

View File

@ -0,0 +1,63 @@
package com.cicdi.notify.template;
import com.cicdi.notify.NotifyType;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 模板管理器
*
* @author xueye
*/
public abstract class AbstractTemplateManager implements TemplateManager {
protected Map<String, Map<String, TemplateProvider>> providers = new ConcurrentHashMap<>();
protected Map<String, Template> templates = new ConcurrentHashMap<>();
protected abstract TemplateProperties getProperties(NotifyType type, String id);
/**
* 注册模板提供商
*
* @param provider 模板提供商
*/
@Override
public void register(TemplateProvider provider) {
providers.computeIfAbsent(provider.getType().getId(), ignore -> new ConcurrentHashMap<>()).put(provider.getProvider().getId(), provider);
}
@Override
public Template createTemplate(NotifyType type, TemplateProperties prop) {
Map<String, TemplateProvider> providerMap = providers.get(type.getId());
if (null == providerMap) {
throw new UnsupportedOperationException("不支持的通知类型: " + prop.getType());
}
TemplateProvider templateProvider = providerMap.get(prop.getProvider());
if (null == templateProvider) {
throw new UnsupportedOperationException("不支持的提供商: " + prop.getProvider());
}
return templateProvider.createTemplate(prop);
}
@Override
public Template getTemplate(NotifyType type, String id) {
Template template = templates.get(id);
if (null == template) {
TemplateProperties properties = this.getProperties(type, id);
template = this.createTemplate(type, properties);
if (null == template) {
throw new UnsupportedOperationException("通知类型不支持: " + type.getId());
}
templates.put(id, template);
}
return template;
}
@Override
public void reload(String templateId) {
templates.remove(templateId);
}
}

View File

@ -0,0 +1,11 @@
package com.cicdi.notify.template;
import java.io.Serializable;
/**
* 通知模板
*
* @author xueye
*/
public interface Template extends Serializable {
}

View File

@ -0,0 +1,34 @@
package com.cicdi.notify.template;
import com.cicdi.notify.NotifyType;
/**
* 通知模板管理器用于模板的转换
*
* @author xueye
*/
public interface TemplateManager {
/**
* @param type 模板类型
* @param id 模板ID
* @return 模板
*/
Template getTemplate(NotifyType type, String id);
/**
* @param type 模板类型
* @param properties 模板属性
* @return 模板
*/
Template createTemplate(NotifyType type, TemplateProperties properties);
/**
* 重新加载模板
*
* @param id 模板ID
*/
void reload(String id);
void register(TemplateProvider provider);
}

View File

@ -0,0 +1,50 @@
package com.cicdi.notify.template;
import java.io.Serializable;
/**
* 模板属性
*
* @author xueye
*/
public class TemplateProperties implements Serializable {
/**
* 模板类型
*/
private String type;
/**
* 模板提供商
*/
private String provider;
/**
* 模板
*/
private String template;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getProvider() {
return provider;
}
public void setProvider(String provider) {
this.provider = provider;
}
public String getTemplate() {
return template;
}
public void setTemplate(String template) {
this.template = template;
}
}

View File

@ -0,0 +1,29 @@
package com.cicdi.notify.template;
import com.cicdi.notify.NotifyType;
import com.cicdi.notify.Provider;
/**
* 模板提供商
*
* @author xueye
*/
public interface TemplateProvider {
/**
* @return 通知类型
* @see NotifyType
*/
NotifyType getType();
/**
* @return 通知提供商
*/
Provider getProvider();
/**
* @param properties 模板属性
* @return 模板
*/
Template createTemplate(TemplateProperties properties);
}