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

gu.simplemq.MQPropertiesHelper Maven / Gradle / Ivy

There is a newer version: 2.3.17
Show newest version
package gu.simplemq;

import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.*;
import static gu.simplemq.utils.TypeConversionSupport.stringValueOf;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import com.google.common.base.Predicates;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.net.HostAndPort;

import gu.simplemq.utils.URISupport;

/**
 * @author guyadong
 *
 */
public abstract class MQPropertiesHelper implements Constant {
	private static final ThreadLocal locationType = new ThreadLocal<>();
	protected MQConstProvider constProvider = getConstProvider();
	protected MQPropertiesHelper() {}
	
	public abstract MQConstProvider getConstProvider() ;
	
	public MQProperties makeMQProperties(Properties defaults){
		return new MQPropertiesImpl(defaults);
	}
	public MQPropertiesHelper with(MQLocationType type){
		if(type != null){
			locationType.set(type);
		}else{
			locationType.remove();
		}		
		return this;
	}
	/**
	 * 从Map中返回指定的连接参数值(字符串)
	 * @param props 为{@code null}返回{@code null}
	 * @param keys 连接参数名,会以此数组顺序为优先序返回参数值
	 * @return 参数值字符串,没有返回{@code null}
	 */
	@SuppressWarnings("rawtypes")
	private static String connInfoOf(Map props, String... keys){
		if(null == props){
			return null;
		}
        if(keys != null){
        	for(String key : Sets.newLinkedHashSet(Iterables.filter(Arrays.asList(keys),Predicates.notNull()))){
    			String temp = stringValueOf(props,key);    			
    			if (!Strings.isNullOrEmpty(temp)) {
    				return temp;
    			}
        	}
        }
        return null;
	}
	@SuppressWarnings("rawtypes")
	public String usernameOf(Map props){
		return connInfoOf(props,MQ_USERNAME,constProvider.getMainUserName());
	}
	@SuppressWarnings("rawtypes")
	public String passwordOf(Map props){		
		return connInfoOf(props,MQ_PASSWORD,constProvider.getMainPassword());		
	}
	@SuppressWarnings("rawtypes")
	public String clientidOf(Map props){		
		return connInfoOf(props,MQ_CLIENTID,constProvider.getMainClientID());		
	}
	/**
	 * 从Map中返回服务地址(URI)
	 * @param props
	 * @return 服务地址(URI)实例,没有返回{@code null}
	 */
	@SuppressWarnings("rawtypes")
	public URI getLocation(Map props){
		try {
			String temp = firstNonNull(locationType.get(), MQLocationType.DEFAULT)
					.locationStringOf(props, true, constProvider.getOptionalLocationNames());
		    if(temp != null){
		    	return new MQLocation(temp).getUri();
		    }
		    return null;			
		} finally {
			locationType.remove();
		}
	}
	/**
	 * 从Map中返回服务地址(URI)字符串
	 * @param props
	 * @return 服务地址(URI)字符串,没有返回{@code null}
	 */
	@SuppressWarnings("rawtypes")
	public String getLocationAsString(Map props){
	    URI uri = getLocation(props);
	    return uri == null ? null : uri.toString();
	}

	/**
	 * 对参数(props)中的服务地址归一化
* 优先使用{@code ACON_BROKER_URL}提供的地址, * 如果没有则调用 {@link ActivemqProperties#getLocationAsString(Map, MQLocationType)}获取地址 * (为{@code null}则使用默认值{@code DEFAULT_BROKER_BIND_URL}), * 最后将{@code MQTT_serverURI}设置为该值, * 返回时删除props中的其他可代表服务地址的值{@code MQ_URI,MQ_HOST,MQ_PORT,PROVIDER_URL} * @param props * @return always props,确保{@code ACON_BROKER_URL}有定义 */ @SuppressWarnings({ "rawtypes", "unchecked" }) M normalizeLocation(M props){ if(null != props){ String s = stringValueOf(props, constProvider.getMainLocationName()); if (Strings.isNullOrEmpty(s)) { props.put(constProvider.getMainLocationName(), firstNonNull(getLocationAsString(props), constProvider.getDefaultMQLocation())); } props.remove(MQ_QUEUE_URI); props.remove(MQ_QUEUE_HOST); props.remove(MQ_QUEUE_PORT); props.remove(MQ_PUBSUB_URI); props.remove(MQ_PUBSUB_HOST); props.remove(MQ_PUBSUB_PORT); props.remove(MQ_URI); props.remove(MQ_HOST); props.remove(MQ_PORT); for(String name:constProvider.getOptionalLocationNames()){ if(!constProvider.getMainLocationName().equals(name)){ props.remove(name); } } } return props; } @SuppressWarnings({ "rawtypes", "unchecked" }) private M normalizeKey(M props,String nativeKey,String generalKey){ if(null != props){ if(nativeKey != null && generalKey != null && !generalKey.equals(nativeKey)){ String s = stringValueOf(props, nativeKey); if (Strings.isNullOrEmpty(s)) { s = stringValueOf(props,generalKey); if(!Strings.isNullOrEmpty(s)){ props.put(nativeKey, s); } } props.remove(generalKey); } } return props; } /** * 对参数(props)中的连接参数归一化
* @param props * @return always props */ @SuppressWarnings({ "rawtypes" }) public M normalizeProps(M props){ normalizeLocation(props); normalizeKey(props,constProvider.getMainUserName(),MQ_USERNAME); normalizeKey(props,constProvider.getMainPassword(),MQ_PASSWORD); normalizeKey(props,constProvider.getMainClientID(),MQ_CLIENTID); normalizeKey(props,constProvider.getMainTimeout(),MQ_TIMEOUT); return props; } /** * 根据{@code props}提供的参数创建一组完整的初始化参数
* @param props * @return */ @SuppressWarnings({ "rawtypes", "unchecked" }) public MQProperties initParameters(Map props){ // 初始化时复制一份缺省参数 MQProperties params = asMQProperties(constProvider.getDefaultMQProperties()); if(null != props){ // 过滤掉所有为null的参数,避免将缺省参数覆盖为null Map filtered = Maps.filterValues(asMQProperties(props), Predicates.notNull()); // 缺省参数与输入参数合并 params.putAll(filtered); URI uri = getLocation(params); String userinfo = uri.getUserInfo(); if(userinfo != null && userinfo.indexOf(':') >= 0){ // 如果URI中以${username}:${password}格式定义了用户名和密码,则优先使用之 String[] u = userinfo.split(":"); if(!Strings.isNullOrEmpty(u[0])){ String keyUsername = firstNonNull(constProvider.getMainUserName(), MQ_USERNAME); params.setProperty(keyUsername, u[0]); } if(!Strings.isNullOrEmpty(u[1])){ String keyPassword = firstNonNull(constProvider.getMainPassword(), MQ_PASSWORD); params.setProperty(keyPassword, u[1]); } try { // 删除URI中的userinfo信息 uri = URISupport.changeUserinfo(uri, null); } catch (URISyntaxException e) { throw new RuntimeException(e); } } params.initURI(new MQLocation(uri).toString()); } return normalizeProps(params); } @SuppressWarnings("rawtypes") public MQProperties asMQProperties(Map props){ if(props instanceof MQProperties){ return (MQProperties)props; } return new MQPropertiesImpl().init(props); } /** * 将类型为{@link Properties}的参数转换为{@code HashMap}, * key为枚举变量名 * @param props * @return HashMap实例,props为{@code null}时返回空实例 */ public HashMap asMqParameters2(Properties props){ if(props == null){ props = new Properties(); } HashMap map = Maps.newHashMap(); for(Enumeration itor = props.propertyNames();itor.hasMoreElements();){ String key = (String) itor.nextElement(); map.put(key, props.get(key).toString()); } return map; } /** * 将指定的 {@link Map} 对象转为{@link EnumMap} * @param keyType 枚举类型 * @param props * @param removeIfSet 是否从props删除枚举类型的key * @param strippedPrefix 需要剥离key的前缀 * @return {@link EnumMap}对象 */ @SuppressWarnings({ "rawtypes", "unchecked" }) public > EnumMap asEnumMap(Class keyType, Map props , boolean removeIfSet, String strippedPrefix){ EnumMap map = new EnumMap<>(keyType); if(props != null){ for(Iterator itor = props.keySet().iterator();itor.hasNext();){ try { Object key = itor.next(); Object value = props.get(key); if(keyType.isInstance(key)){ map.put((E) key, value); }else{ String name = key.toString(); if (strippedPrefix != null && name.startsWith(strippedPrefix)) { name = name.substring(strippedPrefix.length()); } E ekey = Enum.valueOf(keyType, name); map.put(ekey, value); } if(removeIfSet){ itor.remove(); } } catch (Throwable e) { } } } return map; } @SuppressWarnings("rawtypes") public HostAndPort getHostAndPort(Map parameters){ checkArgument(null != parameters,"parameters is null"); URI uri = getLocation(parameters); checkArgument(uri != null, "NOT DEFINED LOCATION FOR MQLocationType:%s",locationType.get()); return HostAndPort.fromParts(uri.getHost(), uri.getPort()); } /** * 根据连接参数创建一个{@link URI}对象 * @param parameters * @return */ @SuppressWarnings("rawtypes") public URI getCanonicalURI(Map parameters){ MQProperties props = initParameters(parameters); return new MQLocation(props.getProperty(constProvider.getMainLocationName())).getUri(); } /** * 根据连接参数创建一个{@link URI}对象 * @param parameters * @return */ @SuppressWarnings("rawtypes") public URI getLocationlURI(Map parameters){ MQProperties props = initParameters(parameters); return new MQLocation(props.getProperty(constProvider.getMainLocationName())).asLocation(); } /** * 测试接参数是否有效,无效抛出异常 * @param props * @param timeoutMills 超时参数(毫秒),为{@code null}使用默认值 * @throws JMSException 无法连接 */ public abstract void checkConnect(Properties input, Integer timeoutMills) throws Exception; /** * 测试接参数是否有效 * @param props * @param timeoutMills 超时参数(毫秒),为{@code null}使用默认值 * @return 连接失败返回{@code false} */ public abstract boolean testConnect(Properties props,Integer timeoutMills); protected class MQLocation extends BaseMQURI{ public MQLocation(String uri) { super(uri); } public MQLocation(URI uri) { super(uri); } @Override protected MQConstProvider getConstProvider() { return constProvider; } } @SuppressWarnings("serial") protected class MQPropertiesImpl extends MQProperties{ MQPropertiesImpl() { super(); } MQPropertiesImpl(Properties defaults) { super(defaults); } @Override public MQPropertiesHelper getPropertiesHelper() { return MQPropertiesHelper.this; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy