wildfire chat server source initial submit
This commit is contained in:
@@ -0,0 +1,317 @@
|
||||
package net.xmeter.samplers;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import io.moquette.spi.impl.security.AES;
|
||||
import org.fusesource.mqtt.client.MQTT;
|
||||
import org.apache.jmeter.samplers.Entry;
|
||||
import org.apache.jmeter.samplers.SampleResult;
|
||||
import org.apache.jmeter.testelement.ThreadListener;
|
||||
import org.apache.jorphan.logging.LoggingManager;
|
||||
import org.apache.log.Logger;
|
||||
import org.apache.log.Priority;
|
||||
import org.fusesource.hawtbuf.Buffer;
|
||||
import org.fusesource.hawtbuf.UTF8Buffer;
|
||||
|
||||
import net.xmeter.Util;
|
||||
import org.fusesource.mqtt.client.Callback;
|
||||
import org.fusesource.mqtt.client.CallbackConnection;
|
||||
import org.fusesource.mqtt.client.Listener;
|
||||
import org.fusesource.mqtt.client.QoS;
|
||||
|
||||
|
||||
public class SendMessageSampler extends AbstractMQTTSampler implements ThreadListener {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -4312341622759500786L;
|
||||
private transient static Logger logger = LoggingManager.getLoggerForClass();
|
||||
private transient MQTT mqtt = new MQTT();
|
||||
private transient CallbackConnection connection = null;
|
||||
private String payload = null;
|
||||
private QoS qos_enum = QoS.AT_MOST_ONCE;
|
||||
private String topicName = "";
|
||||
private String connKey = "";
|
||||
|
||||
public String getQOS() {
|
||||
return getPropertyAsString(QOS_LEVEL, String.valueOf(QOS_0));
|
||||
}
|
||||
|
||||
public void setQOS(String qos) {
|
||||
setProperty(QOS_LEVEL, qos);
|
||||
}
|
||||
|
||||
public String getTopic() {
|
||||
return getPropertyAsString(TOPIC_NAME, DEFAULT_TOPIC_NAME);
|
||||
}
|
||||
|
||||
public void setTopic(String topicName) {
|
||||
setProperty(TOPIC_NAME, topicName);
|
||||
}
|
||||
|
||||
public void setTarget(String target) {
|
||||
setProperty(TARGET, target);
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return getPropertyAsString(TARGET, DEFAULT_TARGET);
|
||||
}
|
||||
|
||||
public void setConvType(String type) {
|
||||
setProperty(CONV_TYPE, type);
|
||||
}
|
||||
|
||||
public String getConvType() {
|
||||
return getPropertyAsString(CONV_TYPE, CONV_TYPE_SINGLE);
|
||||
}
|
||||
|
||||
public boolean isAddTimestamp() {
|
||||
return getPropertyAsBoolean(ADD_TIMESTAMP);
|
||||
}
|
||||
|
||||
public void setAddTimestamp(boolean addTimestamp) {
|
||||
setProperty(ADD_TIMESTAMP, addTimestamp);
|
||||
}
|
||||
|
||||
public String getMessageType() {
|
||||
return getPropertyAsString(MESSAGE_TYPE, MESSAGE_TYPE_RANDOM_STR_WITH_FIX_LEN);
|
||||
}
|
||||
|
||||
public void setMessageType(String messageType) {
|
||||
setProperty(MESSAGE_TYPE, messageType);
|
||||
}
|
||||
|
||||
public String getMessageLength() {
|
||||
return getPropertyAsString(MESSAGE_FIX_LENGTH, DEFAULT_MESSAGE_FIX_LENGTH);
|
||||
}
|
||||
|
||||
public void setMessageLength(String length) {
|
||||
setProperty(MESSAGE_FIX_LENGTH, length);
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return getPropertyAsString(MESSAGE_TO_BE_SENT, "hello");
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
setProperty(MESSAGE_TO_BE_SENT, message);
|
||||
}
|
||||
|
||||
public String getConnPrefix() {
|
||||
return getPropertyAsString(CONN_CLIENT_ID_PREFIX, DEFAULT_CONN_PREFIX_FOR_PUB);
|
||||
}
|
||||
|
||||
public static byte[] hexToBinary(String hex) {
|
||||
return DatatypeConverter.parseHexBinary(hex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnectionShareShow() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getKey() {
|
||||
String key = getThreadName();
|
||||
if(!isConnectionShare()) {
|
||||
key = new String(getThreadName() + this.hashCode());
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SampleResult sample(Entry arg0) {
|
||||
this.connKey = getKey();
|
||||
if(connection == null) {
|
||||
connection = ConnectionsManager.getInstance().getConnection(connKey);
|
||||
if(connection != null) {
|
||||
logger.info("Use the shared connection: " + connection);
|
||||
ConnectionsManager.ConnectionInfo info = ConnectionsManager.getInstance().getConnectionInfo(connKey);
|
||||
setUserName(info.userName);
|
||||
token = info.token;
|
||||
privateSecret = info.privateSecrect;
|
||||
mqttServerIp = info.serverAddress;
|
||||
mqttServerPort = info.serverPort;
|
||||
} else {
|
||||
try {
|
||||
if (!getToken(getUserNameAuth())) {
|
||||
throw new Exception("get token failure!!!");
|
||||
}
|
||||
|
||||
if (!route(getUserNameAuth(), token)) {
|
||||
throw new Exception("route failure!!!");
|
||||
}
|
||||
|
||||
mqtt.setHost("tcp://" + mqttServerIp + ":" + mqttServerPort);
|
||||
mqtt.setVersion(getMqttVersion());
|
||||
mqtt.setKeepAlive((short) Integer.parseInt(getConnKeepAlive()));
|
||||
|
||||
mqtt.setClientId(getClientId());
|
||||
mqtt.setConnectAttemptsMax(Integer.parseInt(getConnAttamptMax()));
|
||||
mqtt.setReconnectAttemptsMax(Integer.parseInt(getConnReconnAttamptMax()));
|
||||
|
||||
mqtt.setUserName(getUserNameAuth());
|
||||
|
||||
byte[] password = AES.AESEncrypt(token, privateSecret);
|
||||
mqtt.setPassword(new UTF8Buffer(password));
|
||||
|
||||
Object connLock = new Object();
|
||||
connection = ConnectionsManager.getInstance().createConnection(connKey, mqtt, new ConnectionsManager.ConnectionInfo(getUserNameAuth(), token, privateSecret, mqttServerIp, mqttServerPort));
|
||||
|
||||
connection.listener(new Listener() {
|
||||
@Override
|
||||
public void onConnected() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPublish(UTF8Buffer topic, Buffer body, Runnable ack) {
|
||||
logger.log(Priority.DEBUG, "receive publish with topic:" + topic);
|
||||
ack.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable value) {
|
||||
|
||||
}
|
||||
});
|
||||
synchronized (connLock) {
|
||||
ConnectionCallback callback = new ConnectionCallback(connection, connLock);
|
||||
connection.connect(callback);
|
||||
connLock.wait(TimeUnit.SECONDS.toMillis(Integer.parseInt(getConnTimeout())));
|
||||
ConnectionsManager.getInstance().setConnectionStatus(connKey, callback.isConnectionSucc());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Priority.ERROR, e.getMessage(), e);
|
||||
ConnectionsManager.getInstance().setConnectionStatus(connKey, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
payload = getMessage();
|
||||
if(payload == null) {
|
||||
payload = Util.generatePayload(120);
|
||||
}
|
||||
|
||||
SampleResult result = new SampleResult();
|
||||
result.setSampleLabel(getName());
|
||||
|
||||
if(!ConnectionsManager.getInstance().getConnectionStatus(connKey)) {
|
||||
result.sampleStart();
|
||||
result.setSuccessful(false);
|
||||
result.sampleEnd();
|
||||
result.setResponseMessage(MessageFormat.format("Publish failed for connection {0}.", connection));
|
||||
result.setResponseData("Publish failed becasue the connection has not been established.".getBytes());
|
||||
result.setResponseCode("500");
|
||||
return result;
|
||||
}
|
||||
try {
|
||||
byte[] toSend;
|
||||
result.sampleStart();
|
||||
|
||||
final Object connLock = new Object();
|
||||
SendMessageCallback pubCallback = new SendMessageCallback(connLock);
|
||||
|
||||
WFCMessage.Message message = WFCMessage.Message.newBuilder()
|
||||
.setConversation(WFCMessage.Conversation.newBuilder().setType(getConvType().equals(CONV_TYPE_SINGLE) ? ProtoConstants.ConversationType.ConversationType_Private : ProtoConstants.ConversationType.ConversationType_Group).setTarget(getTarget()).setLine(0).build())
|
||||
.setFromUser("")
|
||||
.setContent(WFCMessage.MessageContent.newBuilder().setType(1).setSearchableContent(getMessage()).build())
|
||||
.build();
|
||||
toSend = message.toByteArray();
|
||||
toSend = AES.AESEncrypt(toSend, privateSecret);
|
||||
|
||||
//wildfire send message use Qos1 and MS topic
|
||||
topicName = "MS";
|
||||
synchronized (connLock) {
|
||||
connection.publish(topicName, toSend, QoS.AT_LEAST_ONCE, false, pubCallback);
|
||||
connLock.wait();
|
||||
}
|
||||
|
||||
String sendData = "Conversation(" + getConvType() + ":" + getTarget() + "), Message(" + getMessage() + ")";
|
||||
result.sampleEnd();
|
||||
result.setSamplerData(sendData);
|
||||
result.setSentBytes(sendData.length());
|
||||
result.setLatency(result.getEndTime() - result.getStartTime());
|
||||
result.setSuccessful(pubCallback.isSuccessful());
|
||||
|
||||
if(pubCallback.isSuccessful()) {
|
||||
result.setResponseData("Publish successfuly.".getBytes());
|
||||
result.setResponseMessage(MessageFormat.format("publish successfully for Connection {0}.", connection));
|
||||
result.setResponseCodeOK();
|
||||
} else {
|
||||
result.setSuccessful(false);
|
||||
result.setResponseMessage(MessageFormat.format("Publish failed for connection {0}.", connection));
|
||||
result.setResponseData(("Publish failed with error code " + pubCallback.getErrorCode()).getBytes());
|
||||
result.setResponseCode("500");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.log(Priority.ERROR, ex.getMessage(), ex);
|
||||
result.sampleEnd();
|
||||
result.setLatency(result.getEndTime() - result.getStartTime());
|
||||
result.setSuccessful(false);
|
||||
result.setResponseMessage(MessageFormat.format("Publish failed for connection {0}.", connection));
|
||||
result.setResponseData(ex.getMessage().getBytes());
|
||||
result.setResponseCode("500");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void threadStarted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void threadFinished() {
|
||||
if (!isConnectionShare()) {
|
||||
if (this.connection != null) {
|
||||
final CountDownLatch cdl = new CountDownLatch(1);
|
||||
Callback<Void> cb = new Callback<Void>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Void value) {
|
||||
logger.info(MessageFormat.format("The connection {0} disconneted successfully.", connection));
|
||||
cdl.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable value) {
|
||||
logger.log(Priority.ERROR, value.getMessage(), value);
|
||||
cdl.countDown();
|
||||
}
|
||||
};
|
||||
logger.info("before disconnection");
|
||||
this.connection.disconnect(cb);
|
||||
logger.info("after disconnection");
|
||||
try {
|
||||
cdl.await();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (ConnectionsManager.getInstance().containsConnection(connKey)) {
|
||||
ConnectionsManager.getInstance().removeConnection(connKey);
|
||||
}
|
||||
} else {
|
||||
logger.info("share connection, not disconnect the connection");
|
||||
}
|
||||
}
|
||||
public static String getUUID() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
String str = uuid.toString();
|
||||
|
||||
str = str.replace("-", "");
|
||||
return str;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user