package org.apache.mesos.hbase.state;
import com.google.inject.Inject;
import org.apache.commons.io.IOUtils;
import org.apache.mesos.state.State;
import org.apache.mesos.state.Variable;
import org.apache.mesos.state.ZooKeeperState;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.apache.mesos.hbase.config.HBaseFrameworkConfig;
/**
* Manages persistence state of the application. It does NOT have an references to Protocol Buffers. It
* throws exceptions to allow the manager to handle the logic. It currently is tied to zookeeper, but should
* be replaceable with any mesos state abstraction.
*/
public class HBaseZkStore implements IHBaseStore {
private State state;
@Inject
public HBaseZkStore(HBaseFrameworkConfig hbaseFrameworkConfig) {
this.state = new ZooKeeperState(hbaseFrameworkConfig.getStateZkServers(),
hbaseFrameworkConfig.getStateZkTimeout(),
TimeUnit.MILLISECONDS,
"/hbase-mesos/" + hbaseFrameworkConfig.getFrameworkName());
}
public byte[] getRawValueForId(String id) throws ExecutionException, InterruptedException {
byte[] value = state.fetch(id).get().value();
return value;
}
public void setRawValueForId(String id, byte[] frameworkId) throws ExecutionException,
InterruptedException {
Variable value = state.fetch(id).get();
value = value.mutate(frameworkId);
state.store(value).get();
}
/**
* Get serializable object from store.
*
* @return serialized object or null if none
* @throws ExecutionException
* @throws InterruptedException
* @throws java.io.IOException
* @throws ClassNotFoundException
*/
@SuppressWarnings("unchecked")
public <T extends Object> T get(String key) throws InterruptedException, ExecutionException,
IOException, ClassNotFoundException {
byte[] existingNodes = state.fetch(key).get().value();
if (existingNodes.length > 0) {
ByteArrayInputStream bis = new ByteArrayInputStream(existingNodes);
ObjectInputStream in = null;
try {
in = new ObjectInputStream(bis);
// generic in java lose their runtime information, there is no way to get this casted
// without
// the need for the SuppressWarnings on the method.
return (T) in.readObject();
} finally {
IOUtils.closeQuietly(bis);
IOUtils.closeQuietly(in);
}
} else {
return null;
}
}
/**
* Set serializable object in store.
*
* @throws ExecutionException
* @throws InterruptedException
* @throws IOException
*/
public <T extends Object> void set(String key, T object) throws InterruptedException,
ExecutionException, IOException {
Variable value = state.fetch(key).get();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(object);
value = value.mutate(bos.toByteArray());
state.store(value).get();
} finally {
IOUtils.closeQuietly(bos);
IOUtils.closeQuietly(out);
}
}
}