@@ -53,6 +53,8 @@ public class DocumentCRUDQuickstartAsync {
5353 Family family = new Family ();
5454 Family family2 = new Family ();
5555
56+ List <Family > families = new ArrayList <>();
57+
5658 protected static Logger logger = LoggerFactory .getLogger (DocumentCRUDQuickstartAsync .class );
5759
5860 public void close () {
@@ -79,7 +81,7 @@ public static void main(String[] args) {
7981 logger .info ("Demo complete, please hold while resources are released" );
8082 } catch (Exception e ) {
8183 e .printStackTrace ();
82- logger .error (String . format ( "Cosmos getStarted failed with %s " , e ) );
84+ logger .error ("Cosmos getStarted failed with {} " , e );
8385 } finally {
8486 logger .info ("Closing the client" );
8587 p .shutdown ();
@@ -103,7 +105,7 @@ private void documentCRUDDemo() throws Exception {
103105 createContainerIfNotExists ();
104106
105107 //add docs to array
106- List < Family > families = new ArrayList <>();
108+
107109 families .add (Families .getAndersenFamilyItem ());
108110 families .add (Families .getWakefieldFamilyItem ());
109111 families .add (Families .getJohnsonFamilyItem ());
@@ -210,7 +212,7 @@ private void createDocument() throws Exception {
210212 }
211213
212214 private void createDocuments (Flux <Family > families ) throws Exception {
213- logger .info ("Create documents {}" , documentId );
215+ logger .info ("Create documents {}" , this . families . stream (). map ( x -> x . getId ()). collect ( Collectors . toList ()) );
214216
215217 // Define a document as a POJO (internally this
216218 // is converted to JSON via custom serialization)
@@ -220,10 +222,8 @@ private void createDocuments(Flux<Family> families) throws Exception {
220222 return container .createItem (family );
221223 }) // Flux of item request responses
222224 .flatMap (itemResponse -> {
223- logger .info (String .format ("Created item with request charge of %.2f within" +
224- " duration %s" ,
225- itemResponse .getRequestCharge (), itemResponse .getDuration ()));
226- logger .info (String .format ("Item ID: %s\n " , itemResponse .getItem ().getId ()));
225+ logger .info ("Created item with request charge of {} within duration {}" , itemResponse .getRequestCharge (), itemResponse .getDuration ());
226+ logger .info ("Item ID: {}\n " , itemResponse .getItem ().getId ());
227227 return Mono .just (itemResponse .getRequestCharge ());
228228 }) // Flux of request charges
229229 .reduce (0.0 ,
@@ -232,7 +232,7 @@ private void createDocuments(Flux<Family> families) throws Exception {
232232 .doOnSuccess (itemResponse -> {
233233 logger .info ("Aggregated charge (all decimals): {}" , itemResponse );
234234 // Preserve the total charge and print aggregate charge/item count stats.
235- logger .info (String . format ( "Created items with total request charge of %.2f \n " , itemResponse ) );
235+ logger .info ("Created items with total request charge of {} \n " , itemResponse );
236236 })
237237 .doOnError ((exception ) -> {
238238 logger .error (
@@ -366,45 +366,33 @@ private void upsertDocument() throws Exception {
366366 private void replaceDocumentWithConditionalEtagCheck () throws Exception {
367367 logger .info ("Replace document {}, employing optimistic concurrency using ETag." , documentId );
368368
369- // Obtained current document ETag
369+ //chain reading and replacing of item together in reactive stream
370370 container .readItem (documentId , new PartitionKey (documentLastName ), Family .class )
371- .doOnSuccess (itemResponse -> {
372- logger .info ("Request charge of readItem operation: {} RU" , itemResponse .getRequestCharge ());
373- this .family = itemResponse .getItem ();
374- this .etag1 = itemResponse .getETag ();
375- })
376- .doOnError ((exception ) -> {
377- logger .error (
378- "Exception 1. e: {}" ,
379- exception .getLocalizedMessage (),
380- exception );
381- }).subscribe ();
382-
383- // We are adding Thread.sleep to mimic the some business computation that can
384- // happen while waiting for earlier processes to finish.
385- Thread .sleep (1000 );
386-
387- String etag = this .etag1 ;
388- logger .info ("Read document {} to obtain current ETag: {}" , documentId , etag );
389-
390- // Modify document
391- Family family = this .family ;
392- family .setRegistered (!family .isRegistered ());
393-
394- // Persist the change back to the server, updating the ETag in the process
395- // This models a concurrent change made to the document
396- container .replaceItem (family , family .getId (), new PartitionKey (family .getLastName ()), new CosmosItemRequestOptions ())
397- .doOnSuccess (itemResponse -> {
398- logger .info ("'Concurrent' update to document {} so ETag is now {}" ,documentId , itemResponse .getResponseHeaders ().get ("etag" ));
399- })
400- .doOnError ((exception ) -> {
401- logger .error (
402- "Exception 2. e: {}" ,
403- exception .getLocalizedMessage (),
404- exception );
371+ .flatMap (response -> {
372+ logger .info ("Read document {} to obtain current ETag: {}" , documentId , response .getETag ());
373+ //set instance variables for family nd etag1 to use later
374+ this .family = response .getItem ();
375+ this .etag1 = response .getETag ();
376+ logger .info ("Request charge of readItem operation: {} RU" , response .getRequestCharge ());
377+ Family family = this .family ;
378+ family .setRegistered (!family .isRegistered ());
379+ // Persist the change back to the server, updating the ETag in the process
380+ // This models a concurrent change made to the document
381+ return container
382+ .replaceItem (family , family .getId (), new PartitionKey (family .getLastName ()),
383+ new CosmosItemRequestOptions ())
384+ .doOnSuccess (itemResponse -> {
385+ logger .info ("'Concurrent' update to document {} so ETag is now {}" , documentId ,
386+ itemResponse .getResponseHeaders ().get ("etag" ));
387+ })
388+ .doOnError ((exception ) -> {
389+ logger .error (
390+ "Exception e: {}" ,
391+ exception .getLocalizedMessage (),
392+ exception );
393+ });
405394 }).subscribe ();
406395
407-
408396 // We are adding Thread.sleep to mimic the some business computation that can
409397 // happen while waiting for earlier processes to finish.
410398 Thread .sleep (1000 );
@@ -413,7 +401,8 @@ private void replaceDocumentWithConditionalEtagCheck() throws Exception {
413401 // This should fail because the "concurrent" document change updated the ETag.
414402
415403 CosmosItemRequestOptions requestOptions = new CosmosItemRequestOptions ();
416- requestOptions .setIfMatchETag (etag );
404+ //using etag1 instance variable saved from earlier update to etag
405+ requestOptions .setIfMatchETag (this .etag1 .toString ());
417406
418407 family .setDistrict ("Seafood" );
419408
@@ -454,39 +443,32 @@ private void readDocumentOnlyIfChanged() throws Exception {
454443 String etag = this .etag2 ;
455444
456445 // Re-read doc but with conditional access requirement that ETag has changed.
457- // This should fail.
446+ // This should fail (304) .
458447 CosmosItemRequestOptions requestOptions = new CosmosItemRequestOptions ();
459448 requestOptions .setIfNoneMatchETag (etag );
460449
461- container
462- .readItem (documentId , new PartitionKey (documentLastName ), requestOptions , Family .class )
463- .doOnSuccess (itemResponse -> {
464- logger .info ("Re-read doc with status code of {} (we anticipate failure due to ETag not having changed.)" , itemResponse .getStatusCode ());
465- })
466- .doOnError ((exception ) -> {
467- logger .info ("Exception. e: {}" );
468- })
469- .onErrorResume (exception -> Mono .empty ())
470- .subscribe ();
471-
472- // We are adding Thread.sleep to mimic the some business computation that can
473- // happen while waiting for earlier processes to finish.
474- Thread .sleep (1000 );
475-
476- // Replace the doc with a modified version, which will update ETag
477- Family family = this .family2 ;
478- family .setRegistered (!family .isRegistered ());
479- container .replaceItem (family , family .getId (), new PartitionKey (family .getLastName ()), new CosmosItemRequestOptions ())
480- .doOnSuccess (itemResponse -> {
481- logger .info ("Request charge of replace operation: {} RU" , itemResponse .getRequestCharge ());
482- logger .info ("Modified and replaced the doc (updates ETag.)" );
483- })
484- .doOnError ((exception ) -> {
485- logger .error (
486- "Exception. e: {}" ,
487- exception .getLocalizedMessage (),
488- exception );
489- }).subscribe ();
450+ //chain reading and replacing of item together in reactive stream
451+ container .readItem (documentId , new PartitionKey (documentLastName ), requestOptions , Family .class )
452+ .flatMap (response -> {
453+ logger .info ("Re-read doc with status code of {} (we anticipate 304 failure due to ETag not having changed.)" , response .getStatusCode ());
454+ logger .info ("Request charge of readItem operation: {} RU" , response .getRequestCharge ());
455+ Family family = this .family2 ;
456+ family .setRegistered (!family .isRegistered ());
457+ // Replace the doc with a modified version, which will update ETag
458+ return container
459+ .replaceItem (family , family .getId (), new PartitionKey (family .getLastName ()),
460+ new CosmosItemRequestOptions ())
461+ .doOnSuccess (itemResponse -> {
462+ logger .info ("'Concurrent' update to document {} so ETag is now {}" , documentId ,
463+ itemResponse .getResponseHeaders ().get ("etag" ));
464+ })
465+ .doOnError ((exception ) -> {
466+ logger .error (
467+ "Exception e: {}" ,
468+ exception .getLocalizedMessage (),
469+ exception );
470+ });
471+ }).subscribe ();
490472
491473 // We are adding Thread.sleep to mimic the some business computation that can
492474 // happen while waiting for earlier processes to finish.
0 commit comments