/** * Returns a tupled version of this function. * * @return a tupled function equivalent to this. */ default CheckedFunction1<Tuple1<T1>, R> tupled() { return t -> apply(t._1); }
/** * Returns a composed function that first applies this CheckedFunction1 to the given argument and then applies * {@linkplain CheckedFunction1} {@code after} to the result. * * @param <V> return type of after * @param after the function applied after this * @return a function composed of this and after * @throws NullPointerException if after is null */ default <V> CheckedFunction1<T1, V> andThen(CheckedFunction1<? super R, ? extends V> after) { Objects.requireNonNull(after, "after is null"); return (t1) -> after.apply(apply(t1)); }
/** * Returns a composed function that first applies this CheckedFunction4 to the given argument and then applies * {@linkplain CheckedFunction1} {@code after} to the result. * * @param <V> return type of after * @param after the function applied after this * @return a function composed of this and after * @throws NullPointerException if after is null */ default <V> CheckedFunction4<T1, T2, T3, T4, V> andThen(CheckedFunction1<? super R, ? extends V> after) { Objects.requireNonNull(after, "after is null"); return (t1, t2, t3, t4) -> after.apply(apply(t1, t2, t3, t4)); }
/** * Lifts the given {@code partialFunction} into a total function that returns an {@code Try} result. * * @param partialFunction a function that is not defined for all values of the domain (e.g. by throwing) * @param <R> return type * @param <T1> 1st argument * @return a function that applies arguments to the given {@code partialFunction} and returns {@code Success(result)} * if the function is defined for the given arguments, and {@code Failure(throwable)} otherwise. */ static <T1, R> Function1<T1, Try<R>> liftTry(CheckedFunction1<? super T1, ? extends R> partialFunction) { return t1 -> Try.of(() -> partialFunction.apply(t1)); }
/** * Returns a composed function that first applies this CheckedFunction5 to the given argument and then applies * {@linkplain CheckedFunction1} {@code after} to the result. * * @param <V> return type of after * @param after the function applied after this * @return a function composed of this and after * @throws NullPointerException if after is null */ default <V> CheckedFunction5<T1, T2, T3, T4, T5, V> andThen(CheckedFunction1<? super R, ? extends V> after) { Objects.requireNonNull(after, "after is null"); return (t1, t2, t3, t4, t5) -> after.apply(apply(t1, t2, t3, t4, t5)); }
/** * Returns a composed function that first applies this CheckedFunction0 to the given argument and then applies * {@linkplain CheckedFunction1} {@code after} to the result. * * @param <V> return type of after * @param after the function applied after this * @return a function composed of this and after * @throws NullPointerException if after is null */ default <V> CheckedFunction0<V> andThen(CheckedFunction1<? super R, ? extends V> after) { Objects.requireNonNull(after, "after is null"); return () -> after.apply(apply()); }
/** * Returns a composed function that first applies this CheckedFunction7 to the given argument and then applies * {@linkplain CheckedFunction1} {@code after} to the result. * * @param <V> return type of after * @param after the function applied after this * @return a function composed of this and after * @throws NullPointerException if after is null */ default <V> CheckedFunction7<T1, T2, T3, T4, T5, T6, T7, V> andThen(CheckedFunction1<? super R, ? extends V> after) { Objects.requireNonNull(after, "after is null"); return (t1, t2, t3, t4, t5, t6, t7) -> after.apply(apply(t1, t2, t3, t4, t5, t6, t7)); }
/** * Returns a composed function that first applies this CheckedFunction2 to the given argument and then applies * {@linkplain CheckedFunction1} {@code after} to the result. * * @param <V> return type of after * @param after the function applied after this * @return a function composed of this and after * @throws NullPointerException if after is null */ default <V> CheckedFunction2<T1, T2, V> andThen(CheckedFunction1<? super R, ? extends V> after) { Objects.requireNonNull(after, "after is null"); return (t1, t2) -> after.apply(apply(t1, t2)); }
/** * Returns a composed function that first applies this CheckedFunction8 to the given argument and then applies * {@linkplain CheckedFunction1} {@code after} to the result. * * @param <V> return type of after * @param after the function applied after this * @return a function composed of this and after * @throws NullPointerException if after is null */ default <V> CheckedFunction8<T1, T2, T3, T4, T5, T6, T7, T8, V> andThen(CheckedFunction1<? super R, ? extends V> after) { Objects.requireNonNull(after, "after is null"); return (t1, t2, t3, t4, t5, t6, t7, t8) -> after.apply(apply(t1, t2, t3, t4, t5, t6, t7, t8)); }
/** * Returns a composed function that first applies this CheckedFunction6 to the given argument and then applies * {@linkplain CheckedFunction1} {@code after} to the result. * * @param <V> return type of after * @param after the function applied after this * @return a function composed of this and after * @throws NullPointerException if after is null */ default <V> CheckedFunction6<T1, T2, T3, T4, T5, T6, V> andThen(CheckedFunction1<? super R, ? extends V> after) { Objects.requireNonNull(after, "after is null"); return (t1, t2, t3, t4, t5, t6) -> after.apply(apply(t1, t2, t3, t4, t5, t6)); }
/** * Returns a composed function that first applies this CheckedFunction3 to the given argument and then applies * {@linkplain CheckedFunction1} {@code after} to the result. * * @param <V> return type of after * @param after the function applied after this * @return a function composed of this and after * @throws NullPointerException if after is null */ default <V> CheckedFunction3<T1, T2, T3, V> andThen(CheckedFunction1<? super R, ? extends V> after) { Objects.requireNonNull(after, "after is null"); return (t1, t2, t3) -> after.apply(apply(t1, t2, t3)); }
/** * Returns a checkable property that checks values of the 1 variables of this {@code ForAll} quantor. * * @param predicate A 1-ary predicate * @return a new {@code Property1} of 1 variables. */ public Property1<T1> suchThat(CheckedFunction1<T1, Boolean> predicate) { final CheckedFunction1<T1, Condition> proposition = (t1) -> new Condition(true, predicate.apply(t1)); return new Property1<>(name, a1, proposition); } }
/** * Lifts the given {@code partialFunction} into a total function that returns an {@code Option} result. * * @param partialFunction a function that is not defined for all values of the domain (e.g. by throwing) * @param <R> return type * @param <T1> 1st argument * @return a function that applies arguments to the given {@code partialFunction} and returns {@code Some(result)} * if the function is defined for the given arguments, and {@code None} otherwise. */ @SuppressWarnings("RedundantTypeArguments") static <T1, R> Function1<T1, Option<R>> lift(CheckedFunction1<? super T1, ? extends R> partialFunction) { return t1 -> Try.<R>of(() -> partialFunction.apply(t1)).toOption(); }
@Test public void testWithRateLimiter() throws Throwable { final RateLimiter rateLimiter = spy(RateLimiter.ofDefaults("test")); final FeignDecorators testSubject = FeignDecorators.builder().withRateLimiter(rateLimiter).build(); final Object result = testSubject.decorate(args -> args[0], null, null, null).apply(new Object[] {"test01"}); assertThat(result) .describedAs("Returned result is correct") .isEqualTo("test01"); verify(rateLimiter, times(1)).getPermission(any()); } }
@Test public void testWithNothing() throws Throwable { final FeignDecorators testSubject = FeignDecorators.builder().build(); final Object result = testSubject.decorate(args -> args[0], null, null, null).apply(new Object[] {"test01"}); assertThat(result) .describedAs("Returned result is correct") .isEqualTo("test01"); }
@Test public void testWithCircuitBreaker() throws Throwable { final CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("test"); final CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics(); final FeignDecorators testSubject = FeignDecorators.builder().withCircuitBreaker(circuitBreaker).build(); final Object result = testSubject.decorate(args -> args[0], null, null, null).apply(new Object[] {"test01"}); assertThat(result) .describedAs("Returned result is correct") .isEqualTo("test01"); assertThat(metrics.getNumberOfSuccessfulCalls()) .describedAs("Successful Calls") .isEqualTo(1); }
@Test public void shouldDecorateCheckedFunctionAndReturnWithSuccess() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); BDDMockito.given(helloWorldService.returnHelloWorldWithNameWithException("Tom")).willReturn("Hello world Tom"); // When String result = Bulkhead.decorateCheckedFunction(bulkhead, helloWorldService::returnHelloWorldWithNameWithException) .apply("Tom"); // Then assertThat(result).isEqualTo("Hello world Tom"); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); BDDMockito.then(helloWorldService).should(times(1)).returnHelloWorldWithNameWithException("Tom"); }
@Test public void shouldConsumeOnCacheMissEvent() throws Throwable { // Given the cache does not contain the key given(cache.get("testKey")).willReturn(null); Cache<String, String> cacheContext = Cache.of(cache); cacheContext.getEventPublisher().onCacheMiss(event -> logger.info(event.getEventType().toString())); CheckedFunction1<String, String> cachedFunction = Cache.decorateCheckedSupplier(cacheContext, () -> "Hello world"); String value = cachedFunction.apply("testKey"); assertThat(value).isEqualTo("Hello world"); then(logger).should(times(1)).info("CACHE_MISS"); }
@Test public void shouldConsumeOnCacheHitEvent() throws Throwable { // Given the cache does not contain the key given(cache.get("testKey")).willReturn("Hello world"); Cache<String, String> cacheContext = Cache.of(cache); cacheContext.getEventPublisher().onCacheHit(event -> logger.info(event.getEventType().toString())); CheckedFunction1<String, String> cachedFunction = Cache.decorateCheckedSupplier(cacheContext, () -> "Hello world"); String value = cachedFunction.apply("testKey"); assertThat(value).isEqualTo("Hello world"); then(logger).should(times(1)).info("CACHE_HIT"); }
@Test public void shouldConsumeOnErrorEvent() throws Throwable { // Given the cache does not contain the key given(cache.get("testKey")).willThrow(new WebServiceException("BLA")); Cache<String, String> cacheContext = Cache.of(cache); cacheContext.getEventPublisher().onError(event -> logger.info(event.getEventType().toString())); CheckedFunction1<String, String> cachedFunction = Cache.decorateCheckedSupplier(cacheContext, () -> "Hello world"); String value = cachedFunction.apply("testKey"); assertThat(value).isEqualTo("Hello world"); then(logger).should(times(1)).info("ERROR"); }