reactor.util.context.Context Java Examples

The following examples show how to use reactor.util.context.Context. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Operators.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
/**
 * Find the {@link OnNextFailureStrategy} to apply to the calling operator (which could be a local
 * error mode defined in the {@link Context}) and apply it.
 *
 * @param error The error.
 * @param context The most significant {@link Context} in which to look for an {@link OnNextFailureStrategy}.
 * @param subscriptionForCancel The {@link Subscription} that should be cancelled if the
 * strategy is terminal. Null to ignore (for poll, use {@link #onNextPollError(Object, Throwable, Context)}
 * rather than passing null).
 * @param <T> The type of the value causing the error.
 * @return a {@link Throwable} to propagate through onError if the strategy is
 * terminal and cancelled the subscription, null if not.
 */
public static <T> Throwable onNextInnerError(Throwable error, Context context, Subscription subscriptionForCancel) {
	error = unwrapOnNextError(error);
	OnNextFailureStrategy strategy = onNextErrorStrategy(context);
	if (strategy.test(error, null)) {
		//some strategies could still return an exception, eg. if the consumer throws
		Throwable t = strategy.process(error, null, context);
		if (t != null) {
			subscriptionForCancel.cancel();
		}
		return t;
	}
	else {
		return error;
	}
}
 
Example #2
Source File: OperatorsTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void discardQueueWithClearContinuesOnExtractionError() {
	AtomicInteger discardedCount = new AtomicInteger();
	Context hookContext = Operators.discardLocalAdapter(Integer.class, i -> {
		if (i == 3) throw new IllegalStateException("boom");
		discardedCount.incrementAndGet();
	}).apply(Context.empty());

	Queue<List<Integer>> q = new ArrayBlockingQueue<>(5);
	q.add(Collections.singletonList(1));
	q.add(Collections.singletonList(2));
	q.add(Arrays.asList(3, 30));
	q.add(Collections.singletonList(4));
	q.add(Collections.singletonList(5));

	Operators.onDiscardQueueWithClear(q, hookContext, o -> {
		List<Integer> l = o;
		if (l.size() == 2) throw new IllegalStateException("boom in extraction");
		return l.stream();
	});

	assertThat(discardedCount).hasValue(4);
}
 
Example #3
Source File: WingtipsSpringWebfluxUtilsTest.java    From wingtips with Apache License 2.0 6 votes vote down vote up
@DataProvider(value = {
    "true",
    "false"
})
@Test
public void tracingStateFromContext_works_as_expected(boolean contextHasTracingState) {
    // given
    TracingState tracingStateMock = mock(TracingState.class);
    Context context = (contextHasTracingState)
                      ? Context.of(TracingState.class, tracingStateMock)
                      : Context.empty();

    TracingState expectedResult = (contextHasTracingState) ? tracingStateMock : null;

    // when
    TracingState result = WingtipsSpringWebfluxUtils.tracingStateFromContext(context);

    // then
    assertThat(result).isEqualTo(expectedResult);
}
 
Example #4
Source File: OnNextFailureStrategyTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void resumeWithFatal() {
	AtomicReference<Throwable> error = new AtomicReference<>();
	AtomicReference<Object> value = new AtomicReference<>();

	OnNextFailureStrategy strategy = OnNextFailureStrategy.resume(
			(t, v) -> {
				error.set(t);
				value.set(v);
			});

	String data = "foo";
	Throwable exception = new NoSuchMethodError("foo");

	assertThat(strategy.test(exception, data)).isTrue();

	assertThatExceptionOfType(NoSuchMethodError.class)
			.isThrownBy(() -> strategy.process(exception, data, Context.empty()));

	assertThat(error.get()).isNull();
	assertThat(value.get()).isNull();
}
 
Example #5
Source File: OnNextFailureStrategy.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Override
@Nullable
public Throwable process(Throwable error, @Nullable Object value, Context context) {
	if (errorPredicate == null) {
		Exceptions.throwIfFatal(error);
	}
	else if (!errorPredicate.test(error)) {
		Exceptions.throwIfFatal(error);
		return error;
	}
	try {
		errorConsumer.accept(error, value);
		return null;
	}
	catch (Throwable e) {
		return Exceptions.addSuppressed(e, error);
	}
}
 
Example #6
Source File: Operators.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
/**
 * Return a wrapped {@link RejectedExecutionException} which can be thrown by the
 * operator. This exception denotes that an execution was rejected by a
 * {@link reactor.core.scheduler.Scheduler}, notably when it was already disposed.
 * <p>
 * Wrapping is done by calling both {@link Exceptions#failWithRejected(Throwable)} and
 * {@link #onOperatorError(Subscription, Throwable, Object, Context)} (with the passed
 * {@link Subscription}).
 *
 * @param original the original execution error
 * @param subscription the subscription to pass to onOperatorError.
 * @param suppressed a Throwable to be suppressed by the {@link RejectedExecutionException} (or null if not relevant)
 * @param dataSignal a value to be passed to {@link #onOperatorError(Subscription, Throwable, Object, Context)} (or null if not relevant)
 * @param context a context that might hold a local error consumer
 */
public static RuntimeException onRejectedExecution(Throwable original,
		@Nullable Subscription subscription,
		@Nullable Throwable suppressed,
		@Nullable Object dataSignal,
		Context context) {
	//we "cheat" to apply the special key for onRejectedExecution in onOperatorError
	if (context.hasKey(Hooks.KEY_ON_REJECTED_EXECUTION)) {
		context = context.put(Hooks.KEY_ON_OPERATOR_ERROR, context.get(Hooks.KEY_ON_REJECTED_EXECUTION));
	}

	//don't create REE if original is a reactor-produced REE (not including singletons)
	RejectedExecutionException ree = Exceptions.failWithRejected(original);
	if (suppressed != null) {
		ree.addSuppressed(suppressed);
	}
	if (dataSignal != null) {
		return Exceptions.propagate(Operators.onOperatorError(subscription, ree,
				dataSignal, context));
	}
	return Exceptions.propagate(Operators.onOperatorError(subscription, ree, context));
}
 
Example #7
Source File: ReconnectMono.java    From rsocket-java with Apache License 2.0 6 votes vote down vote up
@Override
public void onError(Throwable t) {
  final Subscription s = this.s;

  if (s == Operators.cancelledSubscription()
      || S.getAndSet(this, Operators.cancelledSubscription())
          == Operators.cancelledSubscription()) {
    this.doFinally();
    Operators.onErrorDropped(t, Context.empty());
    return;
  }

  this.doFinally();
  // terminate upstream which means retryBackoff has exhausted
  this.parent.terminate(t);
}
 
Example #8
Source File: StepVerifierAssertionsTests.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void assertOperatorErrorsNotSatisfying() {
	Throwable err1 = new IllegalStateException("boom1");
	Throwable err2 = new IllegalStateException("boom2");
	Throwable err3 = new IllegalStateException("boom3");
	try {
		StepVerifier.create(Flux.from(s -> {
			s.onSubscribe(Operators.emptySubscription());
			s.onError(err1);
			Operators.onOperatorError(err2, Context.empty());
			Operators.onOperatorError(err3, Context.empty());
		}).buffer(1))
		            .expectError()
		            .verifyThenAssertThat()
		            .hasOperatorErrorsSatisfying(c -> assertThat(c).hasSize(3));
		fail("expected an AssertionError");
	}
	catch (AssertionError ae) {
		assertThat(ae).hasMessageStartingWith("\nExpected size:<3> but was:<2> in:\n")
		              .hasMessageContaining("boom2")
		              .hasMessageContaining("boom3");
	}
}
 
Example #9
Source File: TracingClientResponseMono.java    From java-spring-web with Apache License 2.0 6 votes vote down vote up
@Override
public void subscribe(final CoreSubscriber<? super ClientResponse> subscriber) {
    final Context context = subscriber.currentContext();
    final Span parentSpan = context.<Span>getOrEmpty(Span.class).orElseGet(tracer::activeSpan);

    final Span span = tracer.buildSpan(request.method().toString())
            .asChildOf(parentSpan)
            .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
            .start();

    try (final Scope scope = tracer.scopeManager().activate(span)) {
        final ClientRequest.Builder requestBuilder = ClientRequest.from(request);
        requestBuilder.headers(httpHeaders ->
                tracer.inject(span.context(), Format.Builtin.HTTP_HEADERS, new HttpHeadersCarrier(httpHeaders)));
        final ClientRequest mutatedRequest = requestBuilder.build();

        next.exchange(mutatedRequest).subscribe(
                new TracingClientResponseSubscriber(subscriber, mutatedRequest, context, span, spanDecorators)
        );
    }
}
 
Example #10
Source File: StepVerifierAssertionsTests.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void assertOperatorErrorsNotMatching() {
	Throwable err1 = new IllegalStateException("boom1");
	Throwable err2 = new IllegalStateException("boom2");
	Throwable err3 = new IllegalStateException("boom3");
	try {
		StepVerifier.create(Flux.from(s -> {
			s.onSubscribe(Operators.emptySubscription());
			s.onError(err1);
			Operators.onOperatorError(err2, Context.empty());
			Operators.onOperatorError(err3, Context.empty());
		}).buffer(1))
		            .expectError()
		            .verifyThenAssertThat()
		            .hasOperatorErrorsMatching(c -> c.size() == 3);
		fail("expected an AssertionError");
	}
	catch (AssertionError ae) {
		assertThat(ae).hasMessageStartingWith("Expected collection of operator errors matching the" +
				" given predicate, did not match: <[[")
		              .hasMessageContaining("boom2")
		              .hasMessageContaining("boom3");
	}
}
 
Example #11
Source File: FluxDeferWithContext.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Override
public void subscribe(CoreSubscriber<? super T> actual) {
	Publisher<? extends T> p;

	Context ctx = actual.currentContext();
	try {
		p = Objects.requireNonNull(supplier.apply(ctx),
				"The Publisher returned by the supplier is null");
	}
	catch (Throwable e) {
		Operators.error(actual, Operators.onOperatorError(e, ctx));
		return;
	}

	from(p).subscribe(actual);
}
 
Example #12
Source File: MonoDeferWithContext.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Override
public void subscribe(CoreSubscriber<? super T> actual) {
	Mono<? extends T> p;

	Context ctx = actual.currentContext();
	try {
		p = Objects.requireNonNull(supplier.apply(ctx),
				"The Mono returned by the supplier is null");
	}
	catch (Throwable e) {
		Operators.error(actual, Operators.onOperatorError(e, ctx));
		return;
	}

	p.subscribe(actual);
}
 
Example #13
Source File: FluxConcatMapTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void discardOnNextQueueReject() {
	List<Object> discarded = new ArrayList<>();
	AssertSubscriber<Object> discardSubscriber = new AssertSubscriber<>(
			Context.of(Hooks.KEY_ON_DISCARD, (Consumer<?>) discarded::add));

	final CoreSubscriber<Object> subscriber =
			FluxConcatMap.subscriber(discardSubscriber,
					Mono::just,
					Queues.get(0),
					1,
					FluxConcatMap.ErrorMode.IMMEDIATE);
	subscriber.onSubscribe(Operators.emptySubscription());

	subscriber.onNext(1);

	assertThat(discarded).containsExactly(1);
}
 
Example #14
Source File: DefaultContextExpectationsTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void notContainsOnlyOfContextContent() throws Exception {
	Context expected = Context.of("foo", "bar", "other", "stuff");

	assertContextExpectationFails(s -> s.subscriberContext(Context.of("foo", "bar", "foobar", "baz")),
			e -> e.containsOnly(expected))
			.withMessage("Expected Context Context2{foo=bar, foobar=baz} to contain " +
					"same values as Context2{foo=bar, other=stuff}, but they differ in content");
}
 
Example #15
Source File: SignalLogger.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Nullable
@Override
public Consumer<? super Context> onCurrentContextCall() {
	if ((options & CONTEXT_PARENT) == CONTEXT_PARENT && (
			(level == Level.FINE && log.isDebugEnabled())
					|| (level == Level.FINEST && log.isTraceEnabled()))) {
		return c -> log(SignalType.CURRENT_CONTEXT, c);
	}
	return null;
}
 
Example #16
Source File: ReactiveContextTest.java    From Hands-On-Reactive-Programming-in-Spring-5 with MIT License 5 votes vote down vote up
void print(String id, Context context) {
    System.out.println(id + " {");
    System.out.print("  ");
    System.out.println(context);
    System.out.println("}");
    System.out.println();
}
 
Example #17
Source File: FluxDeferTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void deferFluxWithContext() {
	Flux<Integer> source = Flux
			.deferWithContext(ctx -> {
				AtomicInteger i = ctx.get("i");
				return Mono.just(i.incrementAndGet());
			})
			.subscriberContext(Context.of(
					"i", new AtomicInteger()
			));

	Assert.assertEquals(source.blockFirst().intValue(), 1);
	Assert.assertEquals(source.blockFirst().intValue(), 2);
	Assert.assertEquals(source.blockFirst().intValue(), 3);
}
 
Example #18
Source File: ReactorDemo10Test.java    From reactive-streams-in-java with Apache License 2.0 5 votes vote down vote up
@Test
public void testStepVerifier_Context_Right() {
    var flux = Flux.just(1);

    var stringFlux = flux.flatMap(i ->
            Mono.subscriberContext().map(ctx -> i + " pid: " + ctx.getOrDefault("pid", 0)));

    StepVerifier.create(stringFlux.subscriberContext(Context.of("pid", 123)))
            .expectNext("1 pid: 123")
            .verifyComplete();
}
 
Example #19
Source File: ReactorDemo10Test.java    From reactive-streams-in-java with Apache License 2.0 5 votes vote down vote up
@Test
public void testStepVerifier_Context_Wrong() {
    var flux = Flux.just(1).subscriberContext(Context.of("pid", 123));

    var stringFlux = flux.flatMap(i ->
                    Mono.subscriberContext().map(ctx -> i + " pid: " + ctx.getOrDefault("pid", 0)));

    StepVerifier.create(stringFlux)
            .expectNext("1 pid: 0")
            .verifyComplete();
}
 
Example #20
Source File: DefaultRSocketClient.java    From rsocket-java with Apache License 2.0 5 votes vote down vote up
@Override
public Context put(Object key, Object value) {
  return this.actual
      .currentContext()
      .put(ON_DISCARD_KEY, DISCARD_ELEMENTS_CONSUMER)
      .put(key, value);
}
 
Example #21
Source File: OperatorsTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void onOperatorErrorLocal() {
	BiFunction<Throwable, Object, Throwable> localHook = (e, v) ->
			new IllegalStateException("boom_" + v, e);
	Context c = Context.of(Hooks.KEY_ON_OPERATOR_ERROR, localHook);

	IllegalArgumentException failure = new IllegalArgumentException("foo");

	final Throwable throwable = Operators.onOperatorError(null, failure,
			"foo", c);

	assertThat(throwable).isInstanceOf(IllegalStateException.class)
	                     .hasMessage("boom_foo")
	                     .hasCause(failure);
}
 
Example #22
Source File: ImmutableSignal.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
ImmutableSignal(Context context, SignalType type, @Nullable T value, @Nullable Throwable e, @Nullable Subscription subscription) {
	this.context = context;
	this.value = value;
	this.subscription = subscription;
	this.throwable = e;
	this.type = type;
}
 
Example #23
Source File: DefaultRSocketClient.java    From rsocket-java with Apache License 2.0 5 votes vote down vote up
@Override
public Context delete(Object key) {
  return this.actual
      .currentContext()
      .put(ON_DISCARD_KEY, DISCARD_ELEMENTS_CONSUMER)
      .delete(key);
}
 
Example #24
Source File: OperatorsTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void discardIteratorStopsOnIterationError() {
	List<Integer> elements = Arrays.asList(1, 2, 3, 4, 5);
	Iterator<Integer> trueIterator = elements.iterator();
	Iterator<Integer> failingIterator = new Iterator<Integer>() {
		@Override
		public boolean hasNext() {
			return trueIterator.hasNext();
		}

		@Override
		public Integer next() {
			Integer n = trueIterator.next();
			if (n >= 3) throw new IllegalStateException("Iterator boom");
			return n;
		}
	};
	AtomicInteger discardedCount = new AtomicInteger();
	Context hookContext = Operators.discardLocalAdapter(Integer.class, i -> {
		if (i == 3) throw new IllegalStateException("boom");
		discardedCount.incrementAndGet();
	}).apply(Context.empty());

	Operators.onDiscardMultiple(failingIterator, true, hookContext);

	assertThat(discardedCount).hasValue(2);
}
 
Example #25
Source File: MonoCacheTimeTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void contextFromFirstSubscriberCached() {
	AtomicInteger contextFillCount = new AtomicInteger();
	VirtualTimeScheduler vts = VirtualTimeScheduler.create();
	Mono<Context> cached = Mono.subscriberContext()
	                           .as(m -> new MonoCacheTime<>(m, Duration.ofMillis(500), vts))
	                           .subscriberContext(ctx -> ctx.put("a", "GOOD" + contextFillCount.incrementAndGet()));

	//at first pass, the context is captured
	String cacheMiss = cached.map(x -> x.getOrDefault("a", "BAD")).block();
	assertThat(cacheMiss).as("cacheMiss").isEqualTo("GOOD1");
	assertThat(contextFillCount).as("cacheMiss").hasValue(1);

	//at second subscribe, the Context fill attempt is still done, but ultimately ignored since Mono.subscriberContext() result is cached
	String cacheHit = cached.map(x -> x.getOrDefault("a", "BAD")).block();
	assertThat(cacheHit).as("cacheHit").isEqualTo("GOOD1"); //value from the cache
	assertThat(contextFillCount).as("cacheHit").hasValue(2); //function was still invoked

	vts.advanceTimeBy(Duration.ofMillis(501));

	//at third subscribe, after the expiration delay, function is called for the 3rd time, but this time the resulting context is cached
	String cacheExpired = cached.map(x -> x.getOrDefault("a", "BAD")).block();
	assertThat(cacheExpired).as("cacheExpired").isEqualTo("GOOD3");
	assertThat(contextFillCount).as("cacheExpired").hasValue(3);

	//at fourth subscribe, function is called but ignored, the cached context is visible
	String cachePostExpired = cached.map(x -> x.getOrDefault("a", "BAD")).block();
	assertThat(cachePostExpired).as("cachePostExpired").isEqualTo("GOOD3");
	assertThat(contextFillCount).as("cachePostExpired").hasValue(4);

	vts.dispose();
}
 
Example #26
Source File: WingtipsSpringWebfluxExchangeFilterFunctionTest.java    From wingtips with Apache License 2.0 5 votes vote down vote up
@Test
public void WingtipsExchangeFilterFunctionTracingCompletionSubscriber_currentContext_returns_expected_context() {
    // given
    WingtipsExchangeFilterFunctionTracingCompletionSubscriber impl = setupSubscriberWrapper();

    // when
    Context result = impl.currentContext();

    // then
    assertThat(result).isSameAs(impl.subscriberContext);
}
 
Example #27
Source File: FluxFilterTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void discardTryOnNextPredicateFail() {
	List<Object> discarded = new ArrayList<>();
	CoreSubscriber<Integer> actual = new AssertSubscriber<>(
			Context.of(Hooks.KEY_ON_DISCARD, (Consumer<?>) discarded::add));
	FilterSubscriber<Integer> subscriber =
			new FilterSubscriber<>(actual, i -> { throw new IllegalStateException("boom"); });
	subscriber.onSubscribe(Operators.emptySubscription());

	subscriber.tryOnNext(1);

	assertThat(discarded).containsExactly(1);
}
 
Example #28
Source File: SpanSubscriber.java    From rsocket-rpc-java with Apache License 2.0 5 votes vote down vote up
SpanSubscriber(
    Subscriber<? super T> subscriber,
    Context ctx,
    Tracer tracer,
    Map<String, String> tracingMetadata,
    SpanContext spanContext,
    String name,
    Tag... tags) {
  this.subscriber = subscriber;
  this.tracer = tracer;
  this.rootSpan = null;

  Tracer.SpanBuilder spanBuilder = this.tracer.buildSpan(name).asChildOf(spanContext);
  if (tags != null && tags.length > 0) {
    for (Tag tag : tags) {
      spanBuilder.withTag(tag.getKey(), tag.getValue());
    }
  }

  this.span = spanBuilder.start();

  if (tracingMetadata != null) {
    TextMapInjectAdapter adapter = new TextMapInjectAdapter(tracingMetadata);
    tracer.inject(span.context(), Format.Builtin.TEXT_MAP, adapter);
  }

  if (log.isTraceEnabled()) {
    log.trace(
        "Created span [{}], with name [{}], child of [{}]",
        this.span,
        name,
        spanContext.toString());
  }

  this.context = ctx.put(Span.class, this.span);
}
 
Example #29
Source File: BodyFlux.java    From retrofit2-reactor-adapter with Apache License 2.0 5 votes vote down vote up
@Override public void onNext(Response<R> response) {
  if (response.isSuccessful()) {
    subscriber.onNext(response.body());
  } else {
    subscriberTerminated = true;
    Throwable t = new HttpException(response);
    try {
      subscriber.onError(t);
    } catch (Throwable inner) {
      Operators.onErrorDropped(inner, Context.empty());
    }
  }
}
 
Example #30
Source File: DefaultStepVerifierBuilder.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Override
public StepVerifier.Step<T> then() {
	return step.consumeSubscriptionWith(s -> {
		//the current subscription
		Scannable lowest = Scannable.from(s);

		//attempt to go back to the leftmost parent to check the Context from its perspective
		Context c = Flux.<Scannable>
				fromStream(lowest.parents())
				.ofType(CoreSubscriber.class)
				.takeLast(1)
				.singleOrEmpty()
				//no parent? must be a ScalaSubscription or similar source
				.switchIfEmpty(
						Mono.just(lowest)
						    //unless it is directly a CoreSubscriber, let's try to scan the leftmost, see if it has an ACTUAL
						    .map(sc -> (sc instanceof CoreSubscriber) ?
								    sc :
								    sc.scanOrDefault(Scannable.Attr.ACTUAL, Scannable.from(null)))
						    //we are ultimately only interested in CoreSubscribers' Context
						    .ofType(CoreSubscriber.class)
				)
				.map(CoreSubscriber::currentContext)
				//if it wasn't a CoreSubscriber (eg. custom or vanilla Subscriber) there won't be a Context
				.block();

		this.contextExpectations.accept(c);
	});
}