All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.neoremind.fountain.DataSource Maven / Gradle / Ivy

package net.neoremind.fountain;

import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import net.neoremind.fountain.util.CollectionUtil;
import net.neoremind.fountain.util.CollectionUtils;

/**
 * 数据源的一种基于字符串的配置
 *
 * @author zhangxu
 */
public class DataSource {

    /**
     * 默认数据库端口
     */
    public static final Integer DEFAULT_PORT = 3306;

    /**
     * IP:PORT的字符串,按照逗号分隔,对于同一个数据源可以提供多个IP:PORT对,用于binlog-syncer内部做高可用切换
     * 

* 举例: *

     *     10.1.1.2:3306,10.1.1.3:3307
     * 
*/ private String ipPortString; /** * 用户名字符串,按照逗号分隔 *

* Note: 至少一个,如果是一个则默认{@link #ipPortString}都用这一个,否则需要数量上一一对应 *

* 举例: *

     *     admin123,admin456
     * 
*/ private String usernameString; /** * 密码字符串,按照逗号分隔 *

* Note: 至少一个,如果是一个则默认{@link #ipPortString}都用这一个,否则需要数量上一一对应 *

* 举例: *

     *     pwd123,pwd456
     * 
*/ private String passwordString; /** * slaveId字符串,按照逗号分隔 *

* Note:

* 1)可以为空,为空则采用随机生成策略。

* 2)不为空则至少一个,如果是一个则默认{@link #ipPortString}都用这一个,否则需要数量上一一对应 *

* 举例: *

     *     pwd123,pwd456
     * 
*/ private String slaveIdString; /** * 构造方法 * * @param ipPortString IP:PORT的字符串 */ public DataSource(String ipPortString) { this.ipPortString = ipPortString; } /** * 静态构造方法 * * @param ipPortString IP:PORT的字符串 */ public static DataSource of(String ipPortString) { return new DataSource(ipPortString); } /** * 转换为entity实体,共内部更好的使用 * * @return DataSourceEntity列表 */ public List toEntities() { List result = CollectionUtil.createArrayList(8); final List> ipPortList = toIpPortList(); List> usernameList = toStringList(usernameString, "usernameString"); List> passwordList = toStringList(passwordString, "passwordString"); List> slaveIdList = toIntList(slaveIdString, "slaveIdString"); P2 expected = new P2() { @Override public Integer _1() { return 1; } @Override public Integer _2() { return ipPortList.size(); } }; checkMatch(expected, usernameList); checkMatch(expected, passwordList); for (int i = 0; i < ipPortList.size(); i++) { P2 ipPort = ipPortList.get(i); DataSourceEntity e = new DataSourceEntity(); e.setIp(ipPort._1()); e.setPort(ipPort._2()); e.setUsername(getFirstOrByIndex(usernameList, i)); e.setPassword(getFirstOrByIndex(passwordList, i)); if (!CollectionUtil.isEmpty(slaveIdList)) { e.setSlaveId(getFirstOrByIndex(slaveIdList, i)); } result.add(e); } Preconditions.checkState(!CollectionUtils.isEmpty(result), "Datasource should not be empty"); return result; } /** * 获取{@code list}的第一个元素或者按照索引index获取。 * 如果为空则返回{@code null}。 * * @param list 列表 * @param index 索引 * * @return 对象 */ private T getFirstOrByIndex(List> list, int index) { if (CollectionUtil.isEmpty(list)) { return null; } if (list.size() == 1) { return list.get(0)._1(); } return list.get(index)._1(); } /** * 检查{@code list}数量是否正确 * * @param exptectedNum 预计的数量,包括2个 * @param list 列表 * * @throws IllegalStateException 如果不合法则抛出异常 */ private void checkMatch(P2 exptectedNum, List list) throws IllegalStateException { if (CollectionUtil.isEmpty(list) || (list.size() != exptectedNum._1() && list.size() != exptectedNum._2())) { throw new IllegalStateException("Datasource argument not match"); } } /** * 逗号 */ public static final String COMMA = ","; /** * 将IP:PORT列表转换为列表,列表中是的元素含有两个对象,一个是IP,一个是Port * * @return List> P2的一个是IP,一个是Port */ private List> toIpPortList() { Preconditions.checkNotNull(ipPortString, "ipPort should not be empty"); String[] ipPortArray = ipPortString.split(COMMA); List> result = CollectionUtil.createArrayList(8); for (String ipPort : ipPortArray) { String ip = ipPort; int port = DEFAULT_PORT; int pidx = ipPort.lastIndexOf(':'); if (pidx >= 0) { if (pidx < ipPort.length() - 1) { port = Integer.parseInt(ipPort.substring(pidx + 1)); } ip = ipPort.substring(0, pidx); } final String finalIp = ip; final int finalPort = port; result.add(new P2() { @Override public String _1() { return finalIp; } @Override public Integer _2() { return finalPort; } }); } return result; } /** * 将字符串按照分隔符拆分为String列表 * * @param str 字符串 * @param name 字符串标示的名称,用于打印异常日志 * * @return List> */ private List> toStringList(String str, String name) { return toList(str, name, new F() { @Override public String f(String s) { return s.trim(); } }); } /** * 将字符串按照分隔符拆分为整型列表 * * @param str 字符串 * @param name 字符串标示的名称,用于打印异常日志 * * @return List> */ private List> toIntList(String str, String name) { return toList(str, name, new F() { @Override public Integer f(String s) { return Integer.parseInt(s.trim()); } }); } /** * 将字符串按照分隔符拆分为列表,并使用{@link DataSource.F}函数来做转换 * * @param str 字符串 * @param name 字符串标示的名称,用于打印异常日志 * @param f 转换函数 * * @return List> */ private List> toList(String str, String name, final F f) { if (StringUtils.isEmpty(str)) { return Collections.emptyList(); } String[] strArray = str.split(COMMA); List> result = CollectionUtil.createArrayList(8); for (final String s : strArray) { result.add(new P1() { @Override public T _1() { return f.f(s); } }); } return result; } /** * 从A转成B的函数 * * @param 源对象类型 * @param 目标对象类型 */ interface F { /** * 转换 * * @param a 源对象 * * @return 目标对象 */ B f(A a); } public String getIpPortString() { return ipPortString; } public DataSource ipPort(String ipPortString) { this.ipPortString = ipPortString; return this; } public String getUsernameString() { return usernameString; } public DataSource username(String usernameString) { this.usernameString = usernameString; return this; } public String getPasswordString() { return passwordString; } public DataSource password(String passwordString) { this.passwordString = passwordString; return this; } public String getSlaveIdString() { return slaveIdString; } public DataSource slaveId(String slaveIdString) { this.slaveIdString = slaveIdString; return this; } public void setIpPortString(String ipPortString) { this.ipPortString = ipPortString; } public void setUsernameString(String usernameString) { this.usernameString = usernameString; } public void setPasswordString(String passwordString) { this.passwordString = passwordString; } public void setSlaveIdString(String slaveIdString) { this.slaveIdString = slaveIdString; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy