com.logicbus.backend.ServantRegistry Maven / Gradle / Ivy
package com.logicbus.backend;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.alogic.load.Scanner;
import com.anysoft.util.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.logicbus.models.catalog.Path;
import com.logicbus.models.servant.ServantCatalog;
import com.logicbus.models.servant.ServiceDescription;
import com.logicbus.models.servant.ServiceDescriptionWatcher;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* 服务注册表
*
*
* 服务注册表用于为服务工厂提供服务规格配置信息
*
* @author duanyy
*
* @since 1.6.7.20
* @version 1.6.14.12 [20210617 duanyy]
* - 支持自己的AccessController和Normalizer
*/
public interface ServantRegistry extends Configurable,XMLConfigurable,AutoCloseable,Reportable, Scanner {
/**
* 查找指定服务的服务规格
*
* 在服务目录中查找指定服务的服务规格配置信息,如果服务不存在,返回为空.
* @param id 指定的服务id
* @return 服务规格
*/
public ServiceDescription get(Path id);
/**
* 获取当前服务目录列表
* @return 服务目录列表
*/
public ServantCatalog[] getServantCatalog();
public Normalizer getNormalizer(Normalizer dft);
public AccessController getAccessController(AccessController dft);
/**
* 增加监听器
* @param watcher 监听器
*/
public void addWatcher(ServiceDescriptionWatcher watcher);
/**
* 注销监听器
* @param watcher 监听器
*/
public void removeWatcher(ServiceDescriptionWatcher watcher);
/**
* 虚基类
* @author duanyy
*
*/
public static abstract class Abstract implements ServantRegistry,Scanner.Listener{
/**
* a slf4j logger
*/
protected static final Logger logger = LoggerFactory.getLogger(ServantRegistry.class);
protected String id;
protected Normalizer normalizer = null;
protected AccessController accessController = null;
/**
* 服务目录列表
*/
protected List catalogs = new ArrayList();
@Override
public String getId(){
return id;
}
@Override
public Normalizer getNormalizer(Normalizer dft) {
return normalizer == null ? dft:normalizer;
}
@Override
public AccessController getAccessController(AccessController dft) {
return accessController == null?dft:accessController;
}
protected Normalizer getNormalizer(){
return normalizer;
}
protected AccessController getAccessController(){
return accessController;
}
@Override
public void configure(Element e, Properties p) {
Properties props = new XmlElementProperties(e,p);
Element elem = XmlTools.getFirstElementByPath(e,"normalizer");
if (elem != null){
try {
Normalizer.TheFactory ncf = new Normalizer.TheFactory(Settings.getClassLoader());
normalizer = ncf.newInstance(elem,props,"module",DefaultNormalizer.class.getName());
} catch (Throwable t) {
logger.error("Failed to initialize normalizer:" + XmlTools.node2String(elem));
logger.error(ExceptionUtils.getStackTrace(t));
}
}
elem = XmlTools.getFirstElementByPath(e,"ac");
if (elem != null){
AccessController.TheFactory f = new AccessController.TheFactory();
try {
accessController = f.newInstance(elem,props,"module", IpAndServiceAccessController.class.getName());
} catch (Throwable t) {
logger.error("Failed to create access controller:" + XmlTools.node2String(elem));
logger.error(ExceptionUtils.getStackTrace(t));
}
}
loadConfig(props,e);
configure(props);
scan(this);
}
@Override
public void configure(Properties p){
id = PropertiesConstants.getString(p,"id","default");
}
@Override
public void close() {
}
@Override
public void report(Element xml) {
if (xml != null){
xml.setAttribute("module", getClass().getName());
}
}
@Override
public void report(Map json) {
if (json != null){
JsonTools.setString(json,"module",getClass().getName());
}
}
protected void loadConfig(Properties p, Element root) {
if (root == null) {
return;
}
Factory factory = new Factory();
NodeList children = XmlTools.getNodeListByPath(root,"catalog");
for (int i = 0; i < children.getLength() ; i++){
Node item = children.item(i);
if (item.getNodeType() != Node.ELEMENT_NODE){
continue;
}
Element e = (Element)item;
try {
ServantCatalog servantCatalog = factory.newInstance(e, p, "module");
if (servantCatalog != null){
catalogs.add(servantCatalog);
}
}catch (Exception ex){
logger.error("Can not create instance of ServantCatalog.", ex);
}
}
}
/**
* 查询指定服务的服务规格
* @param id 服务ID
* @return 服务规格
*/
@Override
public ServiceDescription get(Path id){
for (int i = 0 ; i < catalogs.size() ; i ++){
ServantCatalog __catalog = catalogs.get(i);
if (__catalog == null){
continue;
}
ServiceDescription sd = __catalog.findService(id);
if (sd != null){
return sd;
}
}
return null;
}
/**
* 获得服务目录列表
*
* @return 服务目录列表
*/
@Override
public ServantCatalog[] getServantCatalog(){
return (ServantCatalog[]) catalogs.toArray(new ServantCatalog[0]);
}
@Override
public void addWatcher(ServiceDescriptionWatcher watcher){
for (ServantCatalog catalog:catalogs){
if (catalog != null){
catalog.addWatcher(watcher);
}
}
}
@Override
public void removeWatcher(ServiceDescriptionWatcher watcher) {
for (ServantCatalog catalog:catalogs){
if (catalog != null){
catalog.removeWatcher(watcher);
}
}
}
@Override
public void scan(Listener listener) {
for (ServantCatalog catalog:catalogs){
if (catalog != null){
catalog.scan(listener);
}
}
}
@Override
public Object begin(String scannerId) {
return this;
}
@Override
public void found(Object cookie, ServiceDescription data) {
String pattern = data.getPattern();
logger.info("Service Found:{}({})",data.getPath(), StringUtils.isNotEmpty(pattern)?pattern:"");
if (normalizer != null && normalizer instanceof PathPatternSupport) {
PathPatternSupport pp = (PathPatternSupport)normalizer;
if (StringUtils.isNotEmpty(pattern)) {
pp.apply(data.getPath(),String.format("%s/%s",data.getPath(),data.getPattern()));
}
}
}
@Override
public void end(Object cookie, String scannerId) {
}
}
}