package cgl.iotcloud.core.zk;
import cgl.iotcloud.core.api.thrift.TChannel;
import cgl.iotcloud.core.api.thrift.TSensor;
import cgl.iotcloud.core.api.thrift.TSensorState;
import cgl.iotcloud.core.api.thrift.TSite;
import cgl.iotcloud.core.master.MasterContext;
import cgl.iotcloud.core.utils.SerializationUtils;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
public class SensorUpdater {
private static Logger LOG = LoggerFactory.getLogger(SensorUpdater.class);
public static final String SENSORS_NODE = "sensors";
public static void addSite(CuratorFramework client, String parent, TSite descriptor) {
// this will create the given ZNode with the given data
try {
if (client.checkExists().forPath(parent + "/" + descriptor.getSiteId()) != null) {
client.delete().forPath(parent + "/" + descriptor.getSiteId());
}
client.create().forPath(parent + "/" + descriptor.getSiteId(), SerializationUtils.serializeToBytes(descriptor));
} catch (Exception e) {
String msg = "Failed to register the site: " + getSitePath(parent, descriptor) + " in ZK";
LOG.error(msg, e);
}
}
public static void removeSite(CuratorFramework client, String path, TSite descriptor) {
// this will create the given ZNode with the given data
try {
client.delete().forPath(getSitePath(path, descriptor));
} catch (Exception e) {
String msg = "Failed to remove the site: " + getSitePath(path, descriptor) + " from ZK";
LOG.error(msg, e);
}
}
public static void addSensor(CuratorFramework client, MasterContext context, String site, TSensor descriptor) {
// this will create the given ZNode with the given data
try {
if (client.checkExists().forPath(context.getParentPath() + "/" + SENSORS_NODE) == null) {
client.create().forPath(context.getParentPath() + "/" + SENSORS_NODE);
}
if (client.checkExists().forPath(context.getParentPath() + "/" + SENSORS_NODE + "/" + descriptor.getName()) == null) {
client.create().withMode(CreateMode.PERSISTENT).forPath(context.getParentPath() + "/" + SENSORS_NODE + "/" + descriptor.getName());
}
if (client.checkExists().forPath(context.getParentPath() + "/" + SENSORS_NODE + "/" + descriptor.getName() + "/" + descriptor.getSensorId()) != null) {
String msg = "The sensor: " + descriptor.getName() + " is already deployed in the site:" + site + " with id: " + descriptor.getSensorId();
LOG.error(msg);
throw new RuntimeException(msg);
}
client.create().withMode(CreateMode.PERSISTENT).forPath(
context.getParentPath() + "/" + SENSORS_NODE + "/" + descriptor.getName() + "/" + descriptor.getSensorId(),
SerializationUtils.serializeThriftObject(descriptor));
// now get the channels for this sensor and add them to the zookeeper
// for each channel we need
/**
* 1. transport
* 2. properties
* 3. broker url
*/
for (TChannel channel : descriptor.getChannels()) {
if (client.checkExists().forPath(context.getParentPath() + "/" + SENSORS_NODE + "/" + descriptor.getName() + "/" + descriptor.getSensorId() + "/" + channel.getName()) != null) {
String msg = "The channel: " + channel.getName() + " for sensor: " + descriptor.getName() + " is already registered in the site:" + site + " with id: " + descriptor.getSensorId() + "/" + channel.getName();
LOG.error(msg);
throw new RuntimeException(msg);
}
client.create().withMode(CreateMode.PERSISTENT).forPath(
context.getParentPath() + "/" + SENSORS_NODE + "/" + descriptor.getName() + "/" + descriptor.getSensorId() + "/" + channel.getName(),
SerializationUtils.serializeThriftObject(channel));
}
} catch (Exception e) {
String msg = "Failed to register the sensor in ZK";
LOG.error(msg, e);
}
}
public static void removeSensor(CuratorFramework client, MasterContext context, String site, TSensor descriptor) {
String path = context.getParentPath() + "/" + SENSORS_NODE + "/" + descriptor.getName() + "/" + descriptor.getSensorId();
try {
// delete all the channels for this
List<String> clients = client.getChildren().forPath(context.getParentPath() + "/" + SENSORS_NODE + "/" + descriptor.getName() + "/" + descriptor.getSensorId());
for (String cl : clients) {
client.delete().forPath(context.getParentPath() + "/" + SENSORS_NODE + "/" + descriptor.getName() + "/" + descriptor.getSensorId() + "/" + cl);
}
if (client.checkExists().forPath(path) == null) {
String msg = "The sensor: " + descriptor.getName() + " is not deployed in the site:" + site + " with id: " + descriptor.getSensorId();
LOG.error(msg);
throw new RuntimeException(msg);
}
client.delete().forPath(path);
} catch (Exception e) {
String msg = "Failed to remove the sensor: " + path + " from ZK";
LOG.error(msg, e);
}
}
public static void markSensorForDeletion(CuratorFramework client, MasterContext context, String site, TSensor descriptor) {
String path = context.getParentPath() + "/" + SENSORS_NODE + "/" + descriptor.getName() + "/" + descriptor.getSensorId();
try {
if (client.checkExists().forPath(path) == null) {
String msg = "The sensor: " + descriptor.getName() + " is not deployed in the site:" + site + " with id: " + descriptor.getSensorId();
LOG.error(msg);
throw new RuntimeException(msg);
}
descriptor.setState(TSensorState.UN_DEPLOY);
client.setData().forPath(path, SerializationUtils.serializeThriftObject(descriptor));
} catch (Exception e) {
String msg = "Failed to remove the sensor: " + path + " from ZK";
LOG.error(msg, e);
}
}
private static String getSitePath(String parent, TSite descriptor) {
return parent + "/" + descriptor.getSiteId();
}
}