void executeBulkUpdate ( final TSDB tsdb , final HttpMethod method , HttpQuery query ) { final List < Annotation > notes ; try { notes = query . serializer ( ) . parseAnnotationsV1 ( ) ; } catch ( IllegalArgumentException e ) { throw new BadRequestException ( e ) ; } catch ( JSONException e ) { throw new BadRequestException ( e ) ; } final List < Deferred < Annotation > > callbacks = new ArrayList < Deferred < Annotation > > ( notes . size ( ) ) ; /** * 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 > { final private Annotation note ; public SyncCB ( final Annotation note ) { this . note = note ; } @ Override public Deferred < Annotation > call ( Boolean success ) throws Exception { if ( ! success ) { throw new BadRequestException ( HttpResponseStatus . INTERNAL_SERVER_ERROR , "Failed to save an Annotation to storage" , "This may be caused by another process modifying storage data: " + note ) ; } return Annotation . getAnnotation ( tsdb , note . getTSUID ( ) , note . getStartTime ( ) ) ; } } /** * Simple callback that will index the updated annotation */ class IndexCB implements Callback < Deferred < Annotation > , Annotation > { @ Override public Deferred < Annotation > call ( final Annotation note ) throws Exception { tsdb . indexAnnotation ( note ) ; return Deferred . fromResult ( note ) ; } } for ( Annotation note : notes ) { try { Deferred < Annotation > deferred = note . syncToStorage ( tsdb , method == HttpMethod . PUT ) . addCallbackDeferring ( new SyncCB ( note ) ) ; Deferred < Annotation > indexer = deferred . addCallbackDeferring ( new IndexCB ( ) ) ; callbacks . add ( indexer ) ; } catch ( IllegalStateException e ) { LOG . info ( "No changes for annotation: " + note ) ; } catch ( IllegalArgumentException e ) { throw new BadRequestException ( HttpResponseStatus . BAD_REQUEST , e . getMessage ( ) , "Annotation error: " + note , e ) ; } } try { // wait untill all of the syncs have completed, then rebuild the list // of annotations using the data synced from storage. Deferred . group ( callbacks ) . joinUninterruptibly ( ) ; notes . clear ( ) ; for ( Deferred < Annotation > note : callbacks ) { notes . add ( note . joinUninterruptibly ( ) ) ; } query . sendReply ( query . serializer ( ) . formatAnnotationsV1 ( notes ) ) ; } catch ( IllegalArgumentException e ) { throw new BadRequestException ( e ) ; } catch ( Exception e ) { throw new RuntimeException ( e ) ; } }
Performs CRU methods on a list of annotation objects to reduce calls to the API . Only supports body content and adding or updating annotation objects . Deletions are separate .