package jframe.mqtt.client.service.impl;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttAsyncClient;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jframe.core.conf.Config;
import jframe.core.plugin.annotation.InjectPlugin;
import jframe.core.plugin.annotation.Injector;
import jframe.core.plugin.annotation.Start;
import jframe.core.plugin.annotation.Stop;
import jframe.mqtt.client.MqttClientConf;
import jframe.mqtt.client.MqttClientPlugin;
import jframe.mqtt.client.service.Mqttv3Client;
/**
* <p>
* <li>connection pool</li>
* <li>TODO persistence</li>
* </p>
*
* @author dzh
* @date Jul 26, 2016 9:44:26 AM
* @since 1.0
*/
@Injector
public class Mqttv3ClientImpl implements Mqttv3Client {
static Logger LOG = LoggerFactory.getLogger(Mqttv3ClientImpl.class);
@InjectPlugin
static MqttClientPlugin Plugin;
private Map<String, ObjectPool<IMqttAsyncClient>> clnt;
@Start
void start() {
LOG.info("Mqttv3Client starting!");
try {
String file = Plugin.getConfig("file.mqttclient", Plugin.getConfig(Config.APP_HOME) + File.separator
+ "conf" + File.separator + "mqttclient.properties");
init(new FileInputStream(file));
LOG.info("Mqttv3Client starting successfully!");
} catch (Exception e) {
LOG.error(e.getMessage(), e.fillInStackTrace());
}
}
public void init(InputStream file) throws Exception {
MqttClientConf props = new MqttClientConf();
props.init(file);
String[] ids = props.getGroupIds();
clnt = new HashMap<>(ids.length, 1);
for (String id : ids) {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(props.getConfInt(id, MqttClientConf.F_pool_maxTotal, "100"));
config.setMaxIdle(props.getConfInt(id, MqttClientConf.F_pool_maxIdle, "10"));
config.setMinIdle(props.getConfInt(id, MqttClientConf.F_pool_minIdle, "1"));
clnt.put(id, new GenericObjectPool<IMqttAsyncClient>(new MqttAsyncClientFactory(id, props), config));
}
}
@Stop
public void stop() {
LOG.info("Mqttv3Client stoping!");
if (clnt != null) {
for (Entry<String, ObjectPool<IMqttAsyncClient>> entry : clnt.entrySet()) {
try {
entry.getValue().close();
} catch (Exception e) {
LOG.error(e.getMessage(), e.fillInStackTrace());
}
}
clnt = null;
}
LOG.info("Mqttv3Client finish stoping!");
}
@Override
public IMqttDeliveryToken publish(String id, String topic, MqttMessage message) {
return publish(id, topic, message, null, null);
}
@Override
public IMqttDeliveryToken publish(String id, String topic, MqttMessage message, Object userContext,
IMqttActionListener callback) {
IMqttAsyncClient mqtt = null;
try {
mqtt = clnt.get(id).borrowObject();
return mqtt.publish(topic, message, userContext, callback);
} catch (Exception e) {
LOG.error(e.getMessage(), e.fillInStackTrace());
} finally {
if (mqtt != null) {
try {
clnt.get(id).returnObject(mqtt);
} catch (Exception e) {
}
}
}
return null;
}
@Override
public IMqttAsyncClient borrowMqttClient(String id) {
try {
return clnt.get(id).borrowObject();
} catch (Exception e) {
LOG.error(e.getMessage(), e.fillInStackTrace());
}
return null;
}
@Override
public void returnMqttClient(String id, IMqttAsyncClient mqttClient) {
try {
clnt.get(id).returnObject(mqttClient);
} catch (Exception e) {
LOG.error(e.getMessage(), e.fillInStackTrace());
}
}
}