EventuateRESTClient implements AggregateCrud { @Override public <T extends Aggregate<T>> CompletableFuture<LoadedEvents> find(String aggregateType, String entityId, Optional<AggregateCrudFindOptions> findOptions) { return withRetry(() -> { CompletableFuture<LoadedEvents> cf = new CompletableFuture<>(); context.runOnContext(ignore -> { httpClient.get(makePath() + "/" + aggregateType + "/" + entityId + makeGetQueryString(findOptions.flatMap(AggregateCrudFindOptions::getTriggeringEvent))) .handler(response -> { if (response.statusCode() == 200) { response.bodyHandler(body -> { try { GetEntityResponse r = JSonMapper.fromJson(body.toString(), GetEntityResponse.class); if (r.getEvents().isEmpty()) cf.completeExceptionally(new EntityNotFoundException(aggregateType, entityId)); else { Optional<SerializedSnapshotWithVersion> snapshot = Optional.empty(); cf.complete(new LoadedEvents(snapshot, r.getEvents())); } } catch (Throwable e) { cf.completeExceptionally(e); } }); } else { handleErrorResponse(cf, response, new EntityIdAndType(entityId, aggregateType), null); } }) .putHeader("authorization", authorizationHeader) .putHeader("accept", "application/json") .exceptionHandler(cf::completeExceptionally) .end(); }); return cf; }); } EventuateRESTClient(Vertx vertx, EventuateCredentials credentials, URI url); @Override CompletableFuture<EntityIdVersionAndEventIds> save(String aggregateType, List<EventTypeAndData> events, Optional<AggregateCrudSaveOptions> options); @Override CompletableFuture<LoadedEvents> find(String aggregateType, String entityId, Optional<AggregateCrudFindOptions> findOptions); @Override CompletableFuture<EntityIdVersionAndEventIds> update(EntityIdAndType aggregateIdAndType, Int128 entityVersion, List<EventTypeAndData> events, Optional<AggregateCrudUpdateOptions> updateOptions);  }
@Test public void shouldRetryAfterServiceUnavailable() throws InterruptedException, ExecutionException, TimeoutException { mockHttpServer.expect().respondingWith(503); mockHttpServer.expect().respondingWith(200, RequestResponseJsonObjects.makeFindResponse()); CompletableFuture<LoadedEvents> f = client.find(RequestResponseJsonObjects.aggregateType, RequestResponseJsonObjects.ENTITY_ID, Optional.empty()); f.get(4, TimeUnit.SECONDS); mockHttpServer.assertSatisfied(); }