use of org.json_voltpatches.JSONObject in project voltdb by VoltDB.
the class RestoreAgent method deserializeRestoreInformation.
/**
* This function, like all good functions, does three things.
* It produces the command log start transaction Id.
* It produces a map of SnapshotInfo objects.
* And, it errors if the remote start action does not match the local action.
*/
private Long deserializeRestoreInformation(List<String> children, Map<String, Set<SnapshotInfo>> snapshotFragments) throws Exception {
try {
int recover = m_action.ordinal();
Long clStartTxnId = null;
for (String node : children) {
//This might be created before we are done fetching the restore info
if (node.equals("snapshot_id"))
continue;
byte[] data = null;
data = m_zk.getData(VoltZK.restore + "/" + node, false, null);
String jsonData = new String(data, "UTF8");
JSONObject json = new JSONObject(jsonData);
long maxTxnId = json.optLong("max", Long.MIN_VALUE);
if (maxTxnId != Long.MIN_VALUE) {
if (clStartTxnId == null || maxTxnId > clStartTxnId) {
clStartTxnId = maxTxnId;
}
}
int remoteRecover = json.getInt("action");
if (remoteRecover != recover) {
String msg = "Database actions are not consistent. Remote node action is not 'recover'. " + "Please enter the same database action on the command-line.";
VoltDB.crashLocalVoltDB(msg, false, null);
}
JSONArray snapInfos = json.getJSONArray("snapInfos");
int snapInfoCnt = snapInfos.length();
for (int i = 0; i < snapInfoCnt; i++) {
JSONObject jsonInfo = snapInfos.getJSONObject(i);
SnapshotInfo info = new SnapshotInfo(jsonInfo);
Set<SnapshotInfo> fragments = snapshotFragments.get(info.nonce);
if (fragments == null) {
fragments = new HashSet<SnapshotInfo>();
snapshotFragments.put(info.nonce, fragments);
}
fragments.add(info);
}
}
return clStartTxnId;
} catch (JSONException je) {
VoltDB.crashLocalVoltDB("Error exchanging snapshot information", true, je);
}
throw new RuntimeException("impossible");
}
use of org.json_voltpatches.JSONObject in project voltdb by VoltDB.
the class SnapshotDeleteAgent method collectStatsImpl.
@Override
protected void collectStatsImpl(Connection c, long clientHandle, OpsSelector selector, ParameterSet params) throws Exception {
JSONObject obj = new JSONObject();
obj.put("selector", "SNAPSHOTDELETE");
String err = null;
if (selector == OpsSelector.SNAPSHOTDELETE) {
err = parseParams(params, obj);
} else {
err = "SnapshotDeleteAgent received non-SNAPSHOTDELETE selector: " + selector.name();
}
if (err != null) {
// Maintain old @SnapshotDelete behavior.
ColumnInfo[] result_columns = new ColumnInfo[1];
result_columns[0] = new ColumnInfo("ERR_MSG", VoltType.STRING);
VoltTable[] results = new VoltTable[] { new VoltTable(result_columns) };
results[0].addRow(err);
ClientResponseImpl errorResponse = new ClientResponseImpl(ClientResponse.SUCCESS, ClientResponse.UNINITIALIZED_APP_STATUS_CODE, null, results, err);
errorResponse.setClientHandle(clientHandle);
ByteBuffer buf = ByteBuffer.allocate(errorResponse.getSerializedSize() + 4);
buf.putInt(buf.capacity() - 4);
errorResponse.flattenToBuffer(buf).flip();
c.writeStream().enqueue(buf);
return;
}
String subselector = obj.getString("subselector");
PendingOpsRequest psr = new PendingOpsRequest(selector, subselector, c, clientHandle, System.currentTimeMillis(), obj);
distributeOpsWork(psr, obj);
}
use of org.json_voltpatches.JSONObject in project voltdb by VoltDB.
the class SnapshotInitiationInfo method getJSONObjectForZK.
/**
* When we write to ZK to request the snapshot, generate the JSON which will be written to the node's data.
*/
public JSONObject getJSONObjectForZK() throws JSONException {
final JSONObject jsObj = new JSONObject();
jsObj.put(SnapshotUtil.JSON_PATH, m_path);
jsObj.put(SnapshotUtil.JSON_PATH_TYPE, m_stype.toString());
jsObj.put(SnapshotUtil.JSON_NONCE, m_nonce);
jsObj.put(SnapshotUtil.JSON_BLOCK, m_blocking);
jsObj.put(SnapshotUtil.JSON_FORMAT, m_format.toString());
jsObj.putOpt(SnapshotUtil.JSON_DATA, m_data);
jsObj.putOpt(SnapshotUtil.JSON_TERMINUS, m_terminus);
return jsObj;
}
use of org.json_voltpatches.JSONObject in project voltdb by VoltDB.
the class SnapshotInitiationInfo method parseJsonParams.
/**
* Parse the JSON blob. Schema is roughly:
* keys:
* (optional) service: currently only 'log_truncation' is valid. Will
* induce a command log truncation snapshot if command logging is present
* and enabled. This will cause all other keys to be unnecessary and/or
* ignored.
*
* uripath: the URI where the snapshot should be written to. Only file:// URIs are currently accepted.
*
* nonce: the nonce to be used for the snapshot. '-' and ',' are forbidden nonce characters
*
* block: whether or not the snapshot should block the database or not
* while it's being generated. All non-zero numbers will be interpreted
* as blocking. true/false will be interpreted as you'd expect
*
* format: one of 'native' or 'csv'.
*/
private boolean parseJsonParams(Object[] params) throws Exception {
boolean checkValidity = true;
if (params[0] == null) {
throw new Exception("@SnapshotSave JSON blob is null");
}
if (!(params[0] instanceof String)) {
throw new Exception("@SnapshotSave JSON blob is a " + params[0].getClass().getSimpleName() + " and should be a java.lang.String");
}
final JSONObject jsObj = new JSONObject((String) params[0]);
// we every introduce another one
if (jsObj.has(SnapshotUtil.JSON_SERVICE)) {
String service = jsObj.getString(SnapshotUtil.JSON_SERVICE);
if (service.equalsIgnoreCase("log_truncation")) {
m_truncationRequest = true;
if (!VoltDB.instance().getCommandLog().isEnabled()) {
throw new Exception("Cannot ask for a command log truncation snapshot when " + "command logging is not present or enabled.");
}
// for CL truncation, don't care about any of the rest of the blob.
return checkValidity;
} else {
throw new Exception("Unknown snapshot save service type: " + service);
}
}
m_stype = SnapshotPathType.valueOf(jsObj.optString(SnapshotUtil.JSON_PATH_TYPE, SnapshotPathType.SNAP_PATH.toString()));
if (jsObj.has(SnapshotUtil.JSON_URIPATH)) {
m_path = jsObj.getString(SnapshotUtil.JSON_URIPATH);
if (m_path.isEmpty()) {
throw new Exception("uripath cannot be empty");
}
} else {
m_stype = SnapshotPathType.SNAP_AUTO;
m_path = "file:///" + VoltDB.instance().getCommandLogSnapshotPath();
}
URI pathURI = new URI(m_path);
String pathURIScheme = pathURI.getScheme();
if (pathURIScheme == null) {
throw new Exception("URI scheme cannot be null");
}
if (!pathURIScheme.equals("file")) {
throw new Exception("Unsupported URI scheme " + pathURIScheme + " if this is a file path then you must prepend file://");
}
m_path = pathURI.getPath();
if (jsObj.has(SnapshotUtil.JSON_NONCE)) {
m_nonce = jsObj.getString(SnapshotUtil.JSON_NONCE);
if (m_nonce.isEmpty()) {
throw new Exception("nonce cannot be empty");
}
} else {
m_nonce = MAGIC_NONCE_PREFIX + System.currentTimeMillis();
//This is a valid JSON
checkValidity = false;
}
Object blockingObj = false;
if (jsObj.has(SnapshotUtil.JSON_BLOCK)) {
blockingObj = jsObj.get(SnapshotUtil.JSON_BLOCK);
}
if (blockingObj instanceof Number) {
m_blocking = ((Number) blockingObj).byteValue() == 0 ? false : true;
} else if (blockingObj instanceof Boolean) {
m_blocking = (Boolean) blockingObj;
} else if (blockingObj instanceof String) {
m_blocking = Boolean.valueOf((String) blockingObj);
} else {
throw new Exception(blockingObj.getClass().getName() + " is not supported as " + " type for the block parameter");
}
m_format = SnapshotFormat.NATIVE;
String formatString = jsObj.optString(SnapshotUtil.JSON_FORMAT, SnapshotFormat.NATIVE.toString());
m_terminus = jsObj.has(SnapshotUtil.JSON_TERMINUS) ? jsObj.getLong(SnapshotUtil.JSON_TERMINUS) : null;
/*
* Try and be very flexible about what we will accept
* as the type of the block parameter.
*/
try {
m_format = SnapshotFormat.getEnumIgnoreCase(formatString);
} catch (IllegalArgumentException argException) {
throw new Exception("@SnapshotSave format param is a " + m_format + " and should be one of [\"native\" | \"csv\"]");
}
m_data = (String) params[0];
return checkValidity;
}
use of org.json_voltpatches.JSONObject in project voltdb by VoltDB.
the class SnapshotSaveAPI method logParticipatingHostCount.
/**
* Once participating host count is set, SnapshotCompletionMonitor can check this ZK node to
* determine whether the snapshot has finished or not.
*
* This should only be called when all participants have responded. It is possible that some
* hosts finish taking snapshot before the coordinator logs the participating host count. In
* this case, the host count would have been decremented multiple times already. To make sure
* finished hosts are logged correctly, this method adds participating host count + 1 to the
* current host count.
*
* @param txnId The snapshot txnId
* @param participantCount The number of hosts participating in this snapshot
*/
public static void logParticipatingHostCount(long txnId, int participantCount) {
ZooKeeper zk = VoltDB.instance().getHostMessenger().getZK();
final String snapshotPath = VoltZK.completed_snapshots + "/" + txnId;
boolean success = false;
while (!success) {
Stat stat = new Stat();
byte[] data = null;
try {
data = zk.getData(snapshotPath, false, stat);
} catch (KeeperException e) {
if (e.code() == KeeperException.Code.NONODE) {
// If snapshot creation failed for some reason, the node won't exist. ignore
return;
}
VoltDB.crashLocalVoltDB("Failed to get snapshot completion node", true, e);
} catch (InterruptedException e) {
VoltDB.crashLocalVoltDB("Interrupted getting snapshot completion node", true, e);
}
if (data == null) {
VoltDB.crashLocalVoltDB("Data should not be null if the node exists", false, null);
}
try {
JSONObject jsonObj = new JSONObject(new String(data, Charsets.UTF_8));
if (jsonObj.getLong("txnId") != txnId) {
VoltDB.crashLocalVoltDB("TxnId should match", false, null);
}
int hostCount = jsonObj.getInt("hostCount");
// +1 because hostCount was initialized to -1
jsonObj.put("hostCount", hostCount + participantCount + 1);
zk.setData(snapshotPath, jsonObj.toString(4).getBytes(Charsets.UTF_8), stat.getVersion());
} catch (KeeperException.BadVersionException e) {
continue;
} catch (Exception e) {
VoltDB.crashLocalVoltDB("This ZK call should never fail", true, e);
}
success = true;
}
}
Aggregations