Package com.xiaomi.common.service.dal.routing

Source Code of com.xiaomi.common.service.dal.routing.RoutingConfigurator$RouterFactory

/**
* @author 54chen(陈臻) [chenzhen@xiaomi.com czhttp@gmail.com]
* @since 2011-3-9 下午04:36:01
*/

package com.xiaomi.common.service.dal.routing;

import com.xiaomi.common.service.dal.routing.router.DirectRouter;
import com.xiaomi.common.service.dal.routing.router.HashRouter;
import com.xiaomi.common.service.dal.routing.router.HexHashRouter;
import com.xiaomi.common.service.dal.routing.router.RangeRouter;
import com.xiaomi.common.service.dal.routing.router.RoundRouter;
import com.xiaomi.common.service.dal.routing.router.XmHashRouter;
import com.xiaomi.common.service.dal.routing.router.XmStringHashRouter;

import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class RoutingConfigurator {
    static Log logger = LogFactory.getLog(RoutingConfigurator.class);

    protected ConcurrentHashMap<String, RoutingDescriptor> map = new ConcurrentHashMap<String, RoutingDescriptor>();

    private List<String> partitions;

    // 加锁保护配置信息
    protected ReadWriteLock rwLock = new ReentrantReadWriteLock();

    boolean inited = false;

    // 路由的名称
    public static final String DIRECT = "direct";

    public static final String ROUND = "round";

    public static final String RANGE = "range";

    public static final String HASH = "hash";

    public static final String XM_HASH = "xm-hash";

    public static final String XM_STRING_HASH = "xm-str-hash";

    public static final String HEX_HASH = "hex-hash";

    public RoutingDescriptor getDescriptor(String name) {
        if (!inited) {
            initPartitions();
        }

        String keyword = name;

        // 加锁保护配置信息的完整性
        Lock lock = rwLock.readLock();

        try {
            lock.lock();

            RoutingDescriptor descriptor = map.get(keyword);

            // if (descriptor == null) {
            //
            // descriptor = map.get(catalog); // 获取全局设置
            // }

            return descriptor;

        } finally {

            lock.unlock();
        }
    }

    private void initPartitions() {
        List<String> partitions = getPartitions();
        for (int i = 0; i < partitions.size(); i++) {
            String[] conf = partitions.get(i).split(":");
            map.put(conf[1], new RoutingDescriptorImpl().setPartitionRouter(createRouter(conf)));
        }
        inited = true;
    }

    public void setPartitions(List<String> partitions) {
        this.partitions = partitions;
    }

    public List<String> getPartitions() {
        return partitions;
    }

    private Router createRouter(String[] conf) {
        if (HASH.equalsIgnoreCase(conf[0])) {
            RouterFactory factory = new RouterFactory(HASH) {
                @Override
                public Router onCreateRouter(String column, String pattern, int partitions) {
                    return new HashRouter(column, pattern, partitions);
                }
            };
            return factory.setColumn(conf[2]).setPattern(conf[3]).setPartition(conf[4]).createRouter();
        } else if (RANGE.equalsIgnoreCase(conf[0])) {
            RouterFactory factory = new RouterFactory(RANGE) {
                @Override
                public Router onCreateRouter(String column, String pattern, int partitions) {
                    return new RangeRouter(column, pattern);
                }
            };
            return factory.setColumn(conf[2]).setPattern(conf[3]).createRouter();
        } else if (DIRECT.equalsIgnoreCase(conf[0])) {
            RouterFactory factory = new RouterFactory(DIRECT) {
                @Override
                public Router onCreateRouter(String column, String pattern, int partitions) {
                    return new DirectRouter(column, pattern);
                }
            };
            return factory.setColumn(conf[2]).setPattern(conf[3]).createRouter();
        } else if (ROUND.equalsIgnoreCase(conf[0])) {
            RouterFactory factory = new RouterFactory(ROUND) {
                @Override
                public Router onCreateRouter(String column, String pattern, int partitions) {
                    return new RoundRouter(pattern, partitions);
                }
            };
            return factory.setPattern(conf[3]).setPartition(conf[4]).createRouter();
        } else if (HEX_HASH.equalsIgnoreCase(conf[0])) {
            RouterFactory factory = new RouterFactory(HEX_HASH) {
                @Override
                public Router onCreateRouter(String column, String pattern, int partitions) {
                    return new HexHashRouter(column, pattern, partitions);
                }
            };
            return factory.setColumn(conf[2]).setPattern(conf[3]).setPartition(conf[4]).createRouter();
        } else if (XM_HASH.equalsIgnoreCase(conf[0])) {
            RouterFactory factory = new RouterFactory(XM_HASH) {
                @Override
                public Router onCreateRouter(String column, String pattern, int partitions) {
                    return new XmHashRouter(column, pattern, partitions);
                }
            };
            return factory.setColumn(conf[2]).setPattern(conf[3]).setPartition(conf[4]).createRouter();
        } else if (XM_STRING_HASH.equalsIgnoreCase(conf[0])) {
            RouterFactory factory = new RouterFactory(XM_STRING_HASH) {
                @Override
                public Router onCreateRouter(String column, String pattern, int partitions) {
                    return new XmStringHashRouter(column, pattern, partitions);
                }
            };
            return factory.setColumn(conf[2]).setPattern(conf[3]).setPartition(conf[4]).createRouter();
        }
        return null;
    }
    private static abstract class RouterFactory {
        private String name;
        private Map<String, String> values = new HashMap<String, String>();
       
        public static final String KEY_COLUMN = "by-column";
        public static final String KEY_PATTERN = "target-pattern";
        public static final String KEY_PARTITION = "partitions";
       
        public RouterFactory(String name) {
            this.name = name;
        }
       
        public RouterFactory add(String key, String value) {
            values.put(key, value);
            return this;
        }
       
        public RouterFactory setColumn(String column) {
            return add(KEY_COLUMN, column);
        }
       
        public RouterFactory setPattern(String pattern) {
            return add(KEY_PATTERN, pattern);
        }
       
        public RouterFactory setPartition(String partition) {
            return add(KEY_PARTITION, partition);
        }
       
        public Router createRouter() {
            for(Entry<String, String> entry : this.values.entrySet()) {
                if (entry.getValue() == null) {
                    if (logger.isErrorEnabled()) {
                        logger.error(String.format("Router '%s' must have '%s' property.", name, entry.getKey()));
                    }
                    return null;
                }
            }

            String column = values.get(KEY_COLUMN);
            String pattern = values.get(KEY_PATTERN);
            String partition = values.get(KEY_PARTITION);
            int count = 0;
            if (partition != null) {
                try {
                    count = NumberUtils.toInt(partition.trim());
                } catch (NumberFormatException e) {
                    if (logger.isErrorEnabled()) {
                        logger.error(String.format("Router '%s' property '%s' must be number.", name, KEY_PARTITION));
                    }
                    return null;
                }
            }

            // 输出日志
            if (logger.isDebugEnabled()) {
                logger.debug(String.format("Creating router '%s' [ %s ]", name, values));
            }

            return onCreateRouter(column, pattern, count);
        }
       
        public abstract Router onCreateRouter(String column, String pattern, int partitions);
    }
}
TOP

Related Classes of com.xiaomi.common.service.dal.routing.RoutingConfigurator$RouterFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.