return Observable.concat(Observable.from(fbClients).map( fbClient -> getData(fbClients.indexOf(fbClient), fbClients.size(), fbClient, canonicalKey, tc, throwEx, throwExc, false, scheduler) //TODO : for the last one make sure to pass throwExc .doOnSuccess(fbData -> increment(fbClient.getServerGroupName(), _cacheName, "RETRY_" + ((fbData == null) ? "MISS" : "HIT"))) .toObservable())) .firstOrDefault(null, fbData -> (fbData != null)).toSingle();
return Observable.concat(Observable.from(fbClients).map( fbClient -> getData(fbClients.indexOf(fbClient), fbClients.size(), fbClient, canonicalKey, tc, throwEx, throwExc, false, scheduler) //TODO : for the last one make sure to pass throwExc .doOnSuccess(fbData -> increment(fbClient.getServerGroupName(), _cacheName, "RETRY_" + ((fbData == null) ? "MISS" : "HIT"))) .toObservable())) .firstOrDefault(null, fbData -> (fbData != null)).toSingle();
private AsyncLazy(Single<TValue> single) { logger.debug("constructor"); this.single = single .doOnSuccess(v -> this.succeeded = true) .doOnError(e -> this.failed = true) .cache(); }
@Override public void destroy() throws Exception { Set<String> deploymentIds = vertx.deploymentIDs(); boolean hasDeployedVerticles = !deploymentIds.isEmpty(); if (hasDeployedVerticles) { CountDownLatch countDownLatch = new CountDownLatch(deploymentIds.size()); deploymentIds.forEach(id -> vertx.rxUndeploy(id) .doOnSuccess(foo -> countDownLatch.countDown()) .doOnError(e -> { log.error("", e); countDownLatch.countDown(); }) .subscribe()); countDownLatch.await(); } vertx.close(); } }
private Single<Void> publish(Record record) { return discovery.rxPublish(record) .doOnSuccess(rec -> { registeredRecords.add(record); logger.info("Service <" + rec.getName() + "> published"); }) .map(r -> null); }
/** * Grants a new access token using the given OAuth2 grant. * * @param grant A class implementing the OAuth2Grant interface. * @param calendar A calendar instance used to calculate the expiration date of the token. * @return - An observable emitting the granted access token. */ public Single<TAccessToken> grantNewAccessToken(OAuth2Grant<TAccessToken> grant, Calendar calendar) { if (grant == null) { throw new IllegalArgumentException("Grant MUST NOT be null."); } return grant.grantNewAccessToken() .doOnSuccess(accessToken -> { if (accessToken.expiresIn != null) { Calendar expirationDate = (Calendar) calendar.clone(); expirationDate.add(Calendar.SECOND, accessToken.expiresIn); accessToken.expirationDate = expirationDate; } mStorage.storeAccessToken(accessToken); }).toObservable().cache().toSingle(); }
@Override public Observable<Long> call(Observable<? extends Throwable> t) { return t.flatMap(f -> { Exception e = Utils.as(f, Exception.class); if (e instanceof Exception) { if (preRetryCallback != null) { // TODO: is retry callback invoked immediately on the same thread? // we should verify this return retryFunc.call(e).doOnSuccess(v -> preRetryCallback.call(e)).toObservable(); } else { return retryFunc.call(e).toObservable(); } } else { return Observable.error(f); } }); } };
private Single<DocumentCollection> resolveByNameAsync( String resourceAddress) { String resourceFullName = PathsHelper.getCollectionPath(resourceAddress); return this.collectionInfoByNameCache.getAsync( resourceFullName, null, () -> { Single<DocumentCollection> collectionObs = this.getByNameAsync(resourceFullName); return collectionObs.doOnSuccess(collection -> { this.collectionInfoByIdCache.set(collection.getResourceId(), collection); }); }); }
private Completable doPostJobExecutionWithoutRescheduling(Completable job, JobDetailsImpl jobDetails, Date timeSlice, Set<UUID> activeJobs) { return job .toSingle(() -> new JobExecutionState(jobDetails, activeJobs)) .flatMap(this::releaseJobExecutionLock) .flatMap(this::setJobFinished) .doOnError(t -> { logger.debug("There was an error during post-job execution, but the job has already been " + "rescheduled.", t); publishJobFinished(jobDetails); }) .doOnSuccess(states -> publishJobFinished(states.currentDetails)) .toCompletable(); }
/** * This method is only used in retry policy as it doesn't have request handy. * @param resourceAddress */ public void refresh(String resourceAddress) { if (PathsHelper.isNameBased(resourceAddress)) { String resourceFullName = PathsHelper.getCollectionPath(resourceAddress); this.collectionInfoByNameCache.refresh( resourceFullName, () -> { Single<DocumentCollection> collectionObs = this.getByNameAsync(resourceFullName); return collectionObs.doOnSuccess(collection -> { this.collectionInfoByIdCache.set(collection.getResourceId(), collection); }); }); } }
@Override public void start(Future<Void> startFuture) { // load and copy all indexer factories now and not lazily to avoid // concurrent modifications to the service loader's internal cache indexerFactories = ImmutableList.copyOf(FilteredServiceLoader.load(IndexerFactory.class)); queryCompiler = createQueryCompiler(); queryCompiler.setQueryCompilers(indexerFactories); new ElasticsearchClientFactory(vertx).createElasticsearchClient(INDEX_NAME) .doOnSuccess(es -> { client = es; }) .flatMapCompletable(v -> client.ensureIndex()) .andThen(Completable.defer(() -> ensureMapping())) .subscribe(() -> { registerMessageConsumers(); startFuture.complete(); }, startFuture::fail); }
private void handleMessage(Exchange outputExchange, RabbitPublisher publisher, Message message) { try { //change in logback.xml to DEBUG level to see every message payload logged log.debugWithParams("Received message.", "payload", new String(message.payload), "metadata", message.basicProperties); publisher.call( outputExchange, new RoutingKey(message.envelope.getRoutingKey()), message.basicProperties, new Payload(message.payload) ) .doOnSuccess(ignore -> message.acknowledger.ack()) .doOnError(throwable -> message.acknowledger.reject()) .subscribe(); }catch (Exception e){ message.acknowledger.reject(); } }
/** * Test if six requests can be sent to four hosts */ @Test public void fourHostsSixRequests(TestContext ctx) { client.setHosts(Arrays.asList( URI.create("http://localhost:" + wireMockRule1.port()), URI.create("http://localhost:" + wireMockRule2.port()), URI.create("http://localhost:" + wireMockRule3.port()), URI.create("http://localhost:" + wireMockRule4.port()))); Async async = ctx.async(); client.performRequest("/") .doOnSuccess(o -> ctx.assertEquals(expected1, o)) .flatMap(v -> client.performRequest("/")) .doOnSuccess(o -> ctx.assertEquals(expected2, o)) .flatMap(v -> client.performRequest("/")) .doOnSuccess(o -> ctx.assertEquals(expected3, o)) .flatMap(v -> client.performRequest("/")) .doOnSuccess(o -> ctx.assertEquals(expected4, o)) .flatMap(v -> client.performRequest("/")) .doOnSuccess(o -> ctx.assertEquals(expected1, o)) .flatMap(v -> client.performRequest("/")) .doOnSuccess(o -> ctx.assertEquals(expected2, o)) .subscribe(o -> async.complete()); }
/** * Test if four requests can be sent to four hosts */ @Test public void fourHostsFourRequests(TestContext ctx) { client.setHosts(Arrays.asList( URI.create("http://localhost:" + wireMockRule1.port()), URI.create("http://localhost:" + wireMockRule2.port()), URI.create("http://localhost:" + wireMockRule3.port()), URI.create("http://localhost:" + wireMockRule4.port()))); Async async = ctx.async(); client.performRequest("/") .doOnSuccess(o -> ctx.assertEquals(expected1, o)) .flatMap(v -> client.performRequest("/")) .doOnSuccess(o -> ctx.assertEquals(expected2, o)) .flatMap(v -> client.performRequest("/")) .doOnSuccess(o -> ctx.assertEquals(expected3, o)) .flatMap(v -> client.performRequest("/")) .doOnSuccess(o -> ctx.assertEquals(expected4, o)) .subscribe(o -> async.complete()); }
/** * Test if five requests can be sent to three hosts in a pseudo-random order */ @Test public void anotherOrder(TestContext ctx) { client.setHosts(Arrays.asList( URI.create("http://localhost:" + wireMockRule4.port()), URI.create("http://localhost:" + wireMockRule1.port()), URI.create("http://localhost:" + wireMockRule3.port()))); Async async = ctx.async(); client.performRequest("/") .doOnSuccess(o -> ctx.assertEquals(expected4, o)) .flatMap(v -> client.performRequest("/")) .doOnSuccess(o -> ctx.assertEquals(expected1, o)) .flatMap(v -> client.performRequest("/")) .doOnSuccess(o -> ctx.assertEquals(expected3, o)) .flatMap(v -> client.performRequest("/")) .doOnSuccess(o -> ctx.assertEquals(expected4, o)) .flatMap(v -> client.performRequest("/")) .doOnSuccess(o -> ctx.assertEquals(expected1, o)) .subscribe(o -> async.complete()); }
@Override public Completable call(FlowContext context) { Operation operation = new Operation.Builder(address, READ_RESOURCE_OPERATION).build(); return dispatcher.execute(operation) .doOnSuccess(result -> context.push(200)) .onErrorResumeNext(throwable -> { if (throwable instanceof DispatchFailure) { context.push(404); return Single.just(new ModelNode()); } else { return Single.error(throwable); } }) .toCompletable(); } }
/** * Test what happens if the first host is unreachable */ @Test public void retrySecondHost(TestContext ctx) { client.setDefaultOptions(new HttpClientOptions().setConnectTimeout(500)); client.setHosts(Arrays.asList( URI.create("http://192.0.2.0:80"), URI.create("http://localhost:" + wireMockRule2.port()))); Async async = ctx.async(); client.performRequest("/") .doOnSuccess(o -> ctx.assertEquals(expected2, o)) .subscribe(o -> async.complete()); }
private Completable refreshAsync(RxDocumentServiceRequest request) { // TODO System.Diagnostics.Debug.Assert(request.IsNameBased); String resourceFullName = PathsHelper.getCollectionPath(request.getResourceAddress()); Completable completable = null; if (request.requestContext.resolvedCollectionRid != null) { // Here we will issue backend call only if cache wasn't already refreshed (if whatever is there corresponds to previously resolved collection rid). DocumentCollection obsoleteValue = new DocumentCollection(); obsoleteValue.setResourceId(request.requestContext.resolvedCollectionRid); completable = this.collectionInfoByNameCache.getAsync( resourceFullName, obsoleteValue, () -> { Single<DocumentCollection> collectionObs = this.getByNameAsync(resourceFullName); return collectionObs.doOnSuccess(collection -> { this.collectionInfoByIdCache.set(collection.getResourceId(), collection); }); }).toCompletable(); } else { // In case of ForceRefresh directive coming from client, there will be no ResolvedCollectionRid, so we // need to refresh unconditionally. completable = Completable.fromAction(() -> this.refresh(request.getResourceAddress())); } return completable.doOnCompleted(() -> request.requestContext.resolvedCollectionRid = null); }
/** * Test if the client can connect to multiple hosts * @param context the test context */ @Test public void multipleHosts(TestContext context) { List<URI> hosts = Arrays.asList(URI.create("http://localhost:" + wireMockRule1.port()), URI.create("http://localhost:" + wireMockRule2.port())); client = new RemoteElasticsearchClient(hosts, INDEX, null, false, rule.vertx()); wireMockRule1.stubFor(head(urlEqualTo("/" + INDEX)) .willReturn(aResponse() .withStatus(200))); wireMockRule2.stubFor(head(urlEqualTo("/" + INDEX)) .willReturn(aResponse() .withStatus(404))); Async async = context.async(); client.indexExists() .doOnSuccess(context::assertTrue) .flatMap(v -> client.indexExists()) .doOnSuccess(context::assertFalse) .subscribe(v -> async.complete(), context::fail); }
/** * Make sure request bodies that are too small are not compressed */ @Test public void compressRequestBodiesMessageTooSmall(TestContext ctx) { client.close(); client = new LoadBalancingHttpClient(rule.vertx(), true); Buffer body = Buffer.buffer("Hello World"); wireMockRule1.stubFor(post(urlEqualTo("/")) .withHeader("Content-Encoding", absent()) .withRequestBody(binaryEqualTo(body.getBytes())) .willReturn(aResponse() .withBody(expected1.encode()))); client.setHosts(Collections.singletonList( URI.create("http://localhost:" + wireMockRule1.port()))); Async async = ctx.async(); client.performRequest(HttpMethod.POST, "/", body) .doOnSuccess(o -> ctx.assertEquals(expected1, o)) .subscribe(o -> async.complete()); } }