001package gu.dtalk.client; 002 003import org.apache.commons.cli.CommandLine; 004import org.apache.commons.cli.Option; 005import org.apache.commons.cli.Options; 006import org.apache.commons.cli.ParseException; 007 008import com.google.common.base.Strings; 009import com.google.common.net.HostAndPort; 010 011import gu.dtalk.OptionType; 012import gu.dtalk.activemq.DefaultCustomActivemqConfigProvider; 013import gu.simplemq.Constant; 014import gu.simplemq.MQProperties; 015import gu.simplemq.MessageQueueType; 016import gu.simplemq.utils.URISupport; 017import net.gdface.cli.BaseAppConfig; 018import static redis.clients.jedis.Protocol.*; 019 020import java.net.URI; 021import java.net.URISyntaxException; 022import java.util.HashMap; 023import java.util.Map; 024 025import static com.google.common.base.Preconditions.checkArgument; 026import static com.google.common.base.Preconditions.checkState; 027import static gu.dtalk.client.SampleConsole.run; 028import static net.gdface.utils.ConditionChecks.checkTrue; 029import static gu.dtalk.activemq.ActivemqContext.HELPER; 030import static gu.dtalk.activemq.ActivemqContext.CONST_PROVIDER; 031 032/** 033 * 终端命令行配置参数 034 * @author guyadong 035 * 036 */ 037public class SampleConsoleActivemqConfig extends BaseAppConfig implements SampleConsoleConstants,Constant { 038 @SuppressWarnings("serial") 039 private static final HashMap<String, Object> CONSTANTS = 040 new HashMap<String, Object>(){{put(IMPL_TYPE, MessageQueueType.ACTIVEMQ);}}; 041 private final MQProperties activemqProperties = HELPER.initParameters(null); 042 043 private String mac; 044 private SampleConsoleActivemqConfig() { 045 super(true); 046 options.addOption(Option.builder().longOpt(AMQ_HOST_OPTION_LONG) 047 .desc(AMQ_HOST_OPTION_DESC + CONST_PROVIDER.getDefaultHost()).numberOfArgs(1).build()); 048 049 options.addOption(Option.builder().longOpt(AMQ_PORT_OPTION_LONG) 050 .desc(AMQ_PORT_OPTION_DESC + CONST_PROVIDER.getDefaultPort()).numberOfArgs(1).type(Number.class).build()); 051 052 options.addOption(Option.builder(AMQ_USERNAME_OPTION).longOpt(AMQ_USERNAME_OPTION_LONG) 053 .desc(AMQ_USERNAME_OPTION_DESC).numberOfArgs(1).build()); 054 055 options.addOption(Option.builder(AMQ_PWD_OPTION).longOpt(AMQ_PWD_OPTION_LONG) 056 .desc(AMQ_PWD_OPTION_DESC).numberOfArgs(1).build()); 057 058 options.addOption(Option.builder().longOpt(AMQ_URI_OPTION_LONG) 059 .desc(AMQ_URI_OPTION_DESC).numberOfArgs(1).build()); 060 061 options.addOption(Option.builder().longOpt(AMQ_TIMEOUT_OPTION_LONG) 062 .desc(AMQ_TIMEOUT_OPTION_DESC + DEFAULT_TIMEOUT + " ms.").numberOfArgs(1).type(Number.class).build()); 063 064 options.addOption(Option.builder().longOpt(DEVICE_MAC_OPTION_LONG) 065 .desc(DEVICE_MAC_OPTION_DESC ).numberOfArgs(1).build()); 066 067 options.addOption(Option.builder().longOpt(MQTT_OPTION_LONG).desc(MQTT_OPTION_DESC).optionalArg(true).numberOfArgs(1).build()); 068 069 defaultValue.setProperty(AMQ_HOST_OPTION_LONG, activemqProperties.get(MQ_HOST)); 070 defaultValue.setProperty(AMQ_PORT_OPTION_LONG, activemqProperties.get(MQ_PORT)); 071 defaultValue.setProperty(AMQ_USERNAME_OPTION_DESC, activemqProperties.get(MQ_USERNAME)); 072 defaultValue.setProperty(AMQ_PWD_OPTION_LONG, activemqProperties.get(MQ_PASSWORD)); 073 defaultValue.setProperty(AMQ_URI_OPTION_LONG, activemqProperties.get(MQ_URI)); 074 defaultValue.setProperty(AMQ_TIMEOUT_OPTION_LONG, activemqProperties.get(MQ_TIMEOUT)); 075 defaultValue.setProperty(DEVICE_MAC_OPTION_LONG, ""); 076 077 } 078 @Override 079 public void loadConfig(Options options, CommandLine cmd) throws ParseException { 080 super.loadConfig(options, cmd); 081 082 if(hasProperty(MQ_HOST)){ 083 activemqProperties.setProperty(MQ_HOST, (String) getProperty(AMQ_HOST_OPTION_LONG)); 084 } 085 if(hasProperty(AMQ_PORT_OPTION_LONG)){ 086 activemqProperties.setProperty(MQ_PORT, (String) getProperty(AMQ_PORT_OPTION_LONG)); 087 } 088 if(hasProperty(AMQ_USERNAME_OPTION_LONG)){ 089 activemqProperties.setProperty(MQ_USERNAME, (String) getProperty(AMQ_USERNAME_OPTION_LONG)); 090 } 091 if(hasProperty(AMQ_PWD_OPTION_LONG)){ 092 activemqProperties.setProperty(MQ_PASSWORD, (String) getProperty(AMQ_PWD_OPTION_LONG)); 093 } 094 if(hasProperty(AMQ_URI_OPTION_LONG)){ 095 activemqProperties.setProperty(MQ_URI, (String) getProperty(AMQ_URI_OPTION_LONG)); 096 } 097 if(hasProperty(AMQ_TIMEOUT_OPTION_LONG)){ 098 activemqProperties.setProperty(MQ_TIMEOUT, (String) getProperty(AMQ_TIMEOUT_OPTION_LONG)); 099 } 100 this.mac = (String) getProperty(DEVICE_MAC_OPTION_LONG); 101 if(!Strings.isNullOrEmpty(this.mac)){ 102 // 检查输入的mac地址字符串是否符合格式要求 103 checkTrue(OptionType.MAC.strValidator.apply(this.mac), 104 ParseException.class,"INVALID MAC address %s",this.mac); 105 this.mac = this.mac.replaceAll("[:-]", ""); 106 } 107 108 parseMQTTOption(); 109 110 } 111 112 private void parseMQTTOption() throws ParseException{ 113 if(hasProperty(MQTT_OPTION_LONG)){ 114 Object v = getProperty(MQTT_OPTION_LONG); 115 activemqProperties.setProperty(MQ_PUBSUB_MQTT, "true"); 116 if(v instanceof String){ 117 String value = (String) v; 118 try { 119 // 尝试解析为端口号(整数) 120 int port = Integer.parseInt(value); 121 checkArgument(port > 0,"INVALID option %s:%s,as port ,>0 required", MQTT_OPTION_LONG, port); 122 activemqProperties.setProperty(MQ_PUBSUB_URI, String.format("mqtt://%s:%d",CONST_PROVIDER.getDefaultHost(), port)); 123 } catch (NumberFormatException e) { 124 HostAndPort hostAndPort; 125 try { 126 // 尝试解析为 HOST:PORT OR HOST 格式 127 // 如果为 HOST 格式,则端口号使用默认值 128 hostAndPort = HostAndPort.fromString(value).withDefaultPort(DEFAULT_MQTT_PORT); 129 } catch (IllegalArgumentException e2) { 130 try { 131 // 尝试解析为URI 132 URI u = new URI(value); 133 // 强制修改schema为mqtt, 134 URI r = URISupport.changeScheme(u, "mqtt"); 135 activemqProperties.setProperty(MQ_PUBSUB_URI, r.toString()); 136 return ; 137 } catch (URISyntaxException e1) { 138 throw new ParseException(String.format("INVALID value %s for option %s", value, MQTT_OPTION_LONG)); 139 } 140 } 141 activemqProperties.setProperty(MQ_PUBSUB_URI, String.format("mqtt://%s:%d",hostAndPort.getHost(), hostAndPort.getPort())); 142 return; 143 } 144 }else { 145 // v 为 true 146 checkState(Boolean.TRUE.equals(v),"INVALID VALUE TYPE FOR %s=%s",MQTT_OPTION_LONG,v); 147 // 参数个数为0时,默认使用 DEFAULT_MQTT_CONNECTOR 148 activemqProperties.setProperty(MQ_PUBSUB_URI, DEFAULT_MQTT_CONNECTOR); 149 } 150 } 151 } 152 /** 153 * @return activemqProperties 154 */ 155 public MQProperties getActivemqParameters() { 156 return activemqProperties; 157 } 158 /** 159 * @return 目标设备MAC地址 160 */ 161 public String getMac() { 162 return mac; 163 } 164 165 @Override 166 protected String getAppName() { 167 return SampleConsole.class.getSimpleName(); 168 } 169 @Override 170 protected String getHeader() { 171 return "Text terminal for Dtalk Device(Dtalk设备交互字符终端)"; 172 } 173 @Override 174 protected void doAfterParse() { 175 DefaultCustomActivemqConfigProvider.INIT_PROPERTIES.init(activemqProperties); 176 } 177 @Override 178 protected Map<String, Object> doGetConstants() { 179 return CONSTANTS; 180 } 181 public static void main(String []args){ 182 run(new SampleConsoleActivemqConfig(), args); 183 } 184}