* Performs CRUD methods on individual annotation objects.
* @param tsdb The TSD to which we belong
* @param query The query to parse and respond to
*/
public void execute(final TSDB tsdb, HttpQuery query) throws IOException {
final HttpMethod method = query.getAPIMethod();
final Annotation note;
if (query.hasContent()) {
note = query.serializer().parseAnnotationV1();
} else {
note = parseQS(query);
}
// GET
if (method == HttpMethod.GET) {
try {
final Annotation stored_annotation =
Annotation.getAnnotation(tsdb, note.getTSUID(), note.getStartTime())
.joinUninterruptibly();
if (stored_annotation == null) {
throw new BadRequestException(HttpResponseStatus.NOT_FOUND,
"Unable to locate annotation in storage");
}
query.sendReply(query.serializer().formatAnnotationV1(stored_annotation));
} catch (BadRequestException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
// POST
} else if (method == HttpMethod.POST || method == HttpMethod.PUT) {
/**
* Storage callback used to determine if the storage call was successful
* or not. Also returns the updated object from storage.
*/
class SyncCB implements Callback<Deferred<Annotation>, Boolean> {
@Override
public Deferred<Annotation> call(Boolean success) throws Exception {
if (!success) {
throw new BadRequestException(
HttpResponseStatus.INTERNAL_SERVER_ERROR,
"Failed to save the Annotation to storage",
"This may be caused by another process modifying storage data");
}
return Annotation.getAnnotation(tsdb, note.getTSUID(),
note.getStartTime());
}
}
try {
final Deferred<Annotation> process_meta = note.syncToStorage(tsdb,
method == HttpMethod.PUT).addCallbackDeferring(new SyncCB());
final Annotation updated_meta = process_meta.joinUninterruptibly();
tsdb.indexAnnotation(note);
query.sendReply(query.serializer().formatAnnotationV1(updated_meta));
} catch (IllegalStateException e) {
query.sendStatusOnly(HttpResponseStatus.NOT_MODIFIED);
} catch (IllegalArgumentException e) {
throw new BadRequestException(e);
} catch (Exception e) {
throw new RuntimeException(e);
}
// DELETE
} else if (method == HttpMethod.DELETE) {
try {
note.delete(tsdb).joinUninterruptibly();
tsdb.deleteAnnotation(note);
} catch (IllegalArgumentException e) {
throw new BadRequestException(
"Unable to delete Annotation information", e);
} catch (Exception e) {
throw new RuntimeException(e);
}
query.sendStatusOnly(HttpResponseStatus.NO_CONTENT);
} else {
throw new BadRequestException(HttpResponseStatus.METHOD_NOT_ALLOWED,
"Method not allowed", "The HTTP method [" + method.getName() +
"] is not permitted for this endpoint");
}
}