private BulkheadMetrics(String prefix, Iterable<Bulkhead> bulkheads) { requireNonNull(prefix); requireNonNull(bulkheads); bulkheads.forEach(bulkhead -> { String name = bulkhead.getName(); //number of available concurrent calls as an integer metricRegistry.register(name(prefix, name, AVAILABLE_CONCURRENT_CALLS), (Gauge<Integer>) () -> bulkhead.getMetrics().getAvailableConcurrentCalls()); } ); }
@Test public void shouldDecorateRunnableAndReturnWithException() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); // When Runnable runnable = Bulkhead.decorateRunnable(bulkhead, () -> {throw new RuntimeException("BAM!");}); Try<Void> result = Try.run(runnable::run); //Then assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }
@Test public void shouldDecorateCheckedRunnableAndReturnWithException() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); // When CheckedRunnable checkedRunnable = Bulkhead.decorateCheckedRunnable(bulkhead, () -> {throw new RuntimeException("BAM!");}); Try<Void> result = Try.run(checkedRunnable); // Then assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }
@Test public void shouldReleaseBulkheadOnlyOnce() { Maybe.just(Arrays.asList(1, 2, 3)) .lift(BulkheadOperator.of(bulkhead)) .flatMapObservable(Observable::fromIterable) .take(2) //this with the previous line triggers an extra dispose .test() .assertResult(1, 2); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); } }
@Test public void shouldPropagateError() { Maybe.error(new IOException("BAM!")) .lift(BulkheadOperator.of(bulkhead)) .test() .assertSubscribed() .assertError(IOException.class) .assertNotComplete(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }
@Test public void shouldEmitAllEvents() { Maybe.just(1) .lift(BulkheadOperator.of(bulkhead)) .test() .assertResult(1); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }
@Test public void shouldReturnTheCorrectName() { Bulkhead bulkhead = registry.bulkhead("test"); assertThat(bulkhead).isNotNull(); assertThat(bulkhead.getName()).isEqualTo("test"); assertThat(bulkhead.getBulkheadConfig().getMaxConcurrentCalls()).isEqualTo(25); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(25); }
@Test public void shouldEmitErrorWithBulkheadFullException() { bulkhead.isCallPermitted(); StepVerifier.create( Mono.just("Event") .transform(BulkheadOperator.of(bulkhead))) .expectSubscription() .expectError(BulkheadFullException.class) .verify(Duration.ofSeconds(1)); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldDecorateConsumerAndReturnWithSuccess() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); // When Bulkhead.decorateConsumer(bulkhead, helloWorldService::sayHelloWorldWithName) .accept("Tom"); // Then assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); BDDMockito.then(helloWorldService).should(times(1)).sayHelloWorldWithName("Tom"); }
@Test public void shouldEmitErrorWithBulkheadFullException() { bulkhead.isCallPermitted(); StepVerifier.create( Flux.just("Event") .transform(BulkheadOperator.of(bulkhead))) .expectSubscription() .expectError(BulkheadFullException.class) .verify(Duration.ofSeconds(1)); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldEmitBulkheadFullExceptionEvenWhenErrorNotOnSubscribe() { bulkhead.isCallPermitted(); StepVerifier.create( Mono.error(new IOException("BAM!")).delayElement(Duration.ofMillis(1)) .transform(BulkheadOperator.of(bulkhead, Schedulers.immediate()))) .expectSubscription() .expectError(BulkheadFullException.class) .verify(Duration.ofSeconds(1)); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); } }
@Test public void shouldEmitBulkheadFullExceptionEvenWhenErrorDuringSubscribe() { bulkhead.isCallPermitted(); StepVerifier.create( Mono.error(new IOException("BAM!")) .transform(BulkheadOperator.of(bulkhead, Schedulers.immediate()))) .expectSubscription() .expectError(BulkheadFullException.class) .verify(Duration.ofSeconds(1)); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldExecuteCallableAndReturnWithSuccess() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); BDDMockito.given(helloWorldService.returnHelloWorldWithException()).willReturn("Hello world"); // When String result = bulkhead.executeCallable(helloWorldService::returnHelloWorldWithException); // Then assertThat(result).isEqualTo("Hello world"); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); BDDMockito.then(helloWorldService).should(times(1)).returnHelloWorldWithException(); }
@Test public void shouldExecuteSupplierAndReturnWithSuccess() { // Given Bulkhead bulkhead = Bulkhead.of("test", config); BDDMockito.given(helloWorldService.returnHelloWorld()).willReturn("Hello world"); // When String result = bulkhead.executeSupplier(helloWorldService::returnHelloWorld); // Then assertThat(result).isEqualTo("Hello world"); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); BDDMockito.then(helloWorldService).should(times(1)).returnHelloWorld(); }
@Test public void shouldComplete() { Completable.complete() .lift(BulkheadOperator.of(bulkhead)) .test() .assertSubscribed() .assertComplete(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }
@Test public void shouldEmitBulkheadFullExceptionEvenWhenErrorNotOnSubscribe() { bulkhead.isCallPermitted(); StepVerifier.create( Flux.error(new IOException("BAM!"), true) .transform(BulkheadOperator.of(bulkhead, Schedulers.immediate()))) .expectSubscription() .expectError(BulkheadFullException.class) .verify(Duration.ofSeconds(1)); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); } }
@Test public void shouldEmitErrorWithBulkheadFullException() { bulkhead.isCallPermitted(); Observable.fromArray("Event 1", "Event 2") .lift(BulkheadOperator.of(bulkhead)) .test() .assertSubscribed() .assertError(BulkheadFullException.class) .assertNotComplete(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldEmitEvent() { StepVerifier.create( Mono.just("Event") .transform(BulkheadOperator.of(bulkhead))) .expectNext("Event") .verifyComplete(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }
@Test public void shouldDecorateCallableAndReturnWithSuccess() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); BDDMockito.given(helloWorldService.returnHelloWorldWithException()).willReturn("Hello world"); // When Callable<String> callable = Bulkhead.decorateCallable(bulkhead, helloWorldService::returnHelloWorldWithException); // Then assertThat(callable.call()).isEqualTo("Hello world"); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); BDDMockito.then(helloWorldService).should(times(1)).returnHelloWorldWithException(); }
@Test public void shouldPropagateError() { StepVerifier.create( Flux.error(new IOException("BAM!")) .transform(BulkheadOperator.of(bulkhead))) .expectSubscription() .expectError(IOException.class) .verify(Duration.ofSeconds(1)); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }