com.logicbus.kvalue.common.AbstractPartitioner Maven / Gradle / Ivy
package com.logicbus.kvalue.common;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.anysoft.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* 分区器的虚基类
*
* @author duanyy
* @version 1.0.0.2 [20141108 duanyy]
* - 补充Reportable实现.
*
* @version 1.6.7.9 [20170201 duanyy]
* - 采用SLF4j日志框架输出日志
*
* @version 1.6.13.24 [20201005 duanyy]
* - domainInKey可以定制
*/
abstract public class AbstractPartitioner implements Partitioner {
/**
* a logger of log4j
*/
protected final static Logger logger = LoggerFactory.getLogger(Partitioner.class);
/**
* 缺省的分区
*/
protected Partition defaultPartition = null;
/**
* 是否从Key中提取出domain(用于改变分区规则)
*/
protected boolean domainInKey = false;
/**
* 分区信息
*/
protected Map partitions = new HashMap();
/**
* 通过Key计算PartitionCase.
*
* @param key 数据的Key
* @return PartitionCase,用于对Key进行分组,实际上是一个分区的id
*/
abstract protected String getPartitionCase(String key);
/**
* 处理Configure事件,在{@link #configure(Element, Properties)}中触发。提供给子类,让子类能够进行配置。
* @param _e XML配置节点
* @param _p 变量集
*/
abstract protected void onConfigure(Element _e,Properties _p);
/**
* 装入配置
*
*
* Partitioner的配置信息全部定义在XML节点中。
*
* @param _e XML节点
* @param _properties 环境变量集
*
*/
public void configure(Element _e, Properties _properties) {
XmlElementProperties p = new XmlElementProperties(_e,_properties);
domainInKey = PropertiesConstants.getBoolean(p,"domainInKey",domainInKey);
TheFactory factory = new TheFactory();
{
//default partition
Element dftElement = XmlTools.getFirstElementByPath(_e, "partition");
if (dftElement != null){
defaultPartition = factory.newInstance(
dftElement,
p,
"module",
DefaultPartition.class.getName()
);
}
}
{
//partitions
NodeList nodeList= XmlTools.getNodeListByPath(_e, "partitions/partition");
for (int i = 0 ;i < nodeList.getLength() ; i ++){
Node n = nodeList.item(i);
if (n.getNodeType() != Node.ELEMENT_NODE){
continue;
}
Element ePartition = (Element)n;
String _case = ePartition.getAttribute("case");
if (_case == null || _case.length() <= 0){
continue;
}
try {
Partition instance = factory.newInstance(
ePartition,
p,
"module",
DefaultPartition.class.getName()
);
partitions.put(_case, instance);
}catch (Exception ex){
logger.warn("Can not create Partition instance",ex);
continue;
}
}
}
onConfigure(_e,p);
}
public void close() {
partitions.clear();
}
/**
* report到XML
*
* @param xml XML节点
*/
public void report(Element xml) {
if (xml == null) return;
Document doc = xml.getOwnerDocument();
if (defaultPartition != null){
Element e = doc.createElement("partition");
defaultPartition.report(e);
xml.appendChild(e);
}
if (partitions != null && partitions.size() > 0){
Element es = doc.createElement("partitions");
Iterator> iterator = partitions.entrySet().iterator();
while (iterator.hasNext()){
Element e = doc.createElement("partition");
Entry entry = iterator.next();
e.setAttribute("case", entry.getKey());
entry.getValue().report(e);
es.appendChild(e);
}
xml.appendChild(es);
}
}
/**
* report到JSON
*
* @param json JSON节点
*/
public void report(Map json) {
if (json == null) return ;
if (defaultPartition != null){
Map _partition = new HashMap();
defaultPartition.report(_partition);
json.put("partition", _partition);
}
if (partitions != null && partitions.size() > 0){
List