@Override public Mono<I> initialResult() { return delegate.initialResult(); }
@Override public Mono<QueryResponseMessage<I>> initialResult() { return delegate.initialResult().map(serializer::deserialize); }
private void getInitialResult(SubscriptionQuery query) { String subscriptionId = query.getSubscriptionIdentifier(); subscriptions.get(subscriptionId).initialResult().subscribe( i -> publisher.publish(serializer.serialize(i, subscriptionId)), e -> logger.debug("Error in initial result for subscription id: {}", subscriptionId) ); }
@Override public <Q, I, U> SubscriptionQueryResult<I, U> subscriptionQuery(String queryName, Q query, ResponseType<I> initialResponseType, ResponseType<U> updateResponseType, SubscriptionQueryBackpressure backpressure, int updateBufferSize) { SubscriptionQueryMessage<Q, I, U> subscriptionQueryMessage = new GenericSubscriptionQueryMessage<>(query, queryName, initialResponseType, updateResponseType); SubscriptionQueryResult<QueryResponseMessage<I>, SubscriptionQueryUpdateMessage<U>> result = queryBus .subscriptionQuery(processInterceptors(subscriptionQueryMessage), backpressure, updateBufferSize); return new DefaultSubscriptionQueryResult<>( result.initialResult() .filter(initialResult -> Objects.nonNull(initialResult.getPayload())) .map(Message::getPayload) .onErrorMap(e -> e instanceof IllegalPayloadAccessException ? e.getCause() : e), result.updates() .filter(update -> Objects.nonNull(update.getPayload())) .map(SubscriptionQueryUpdateMessage::getPayload), result ); }
/** * Delegates handling of initial result and incremental updates to the provided consumers. Subscription to the * incremental updates is done after the initial result is retrieved and its consumer is invoked. If anything goes * wrong during invoking or consuming initial result or incremental updates, subscription is cancelled. * * @param initialResultConsumer The consumer to be invoked when the initial result is retrieved * @param updateConsumer The consumer to be invoked when incremental updates are emitted */ default void handle(Consumer<? super I> initialResultConsumer, Consumer<? super U> updateConsumer) { initialResult().subscribe(initialResult -> { try { initialResultConsumer.accept(initialResult); updates().subscribe(updateConsumer::accept); } catch (Exception e) { cancel(); } }, t -> cancel()); } }
@Override public Mono<I> initialResult() { return delegate.initialResult(); }
@Override public Mono<QueryResponseMessage<I>> initialResult() { return delegate.initialResult().map(serializer::deserialize); }
private void getInitialResult(SubscriptionQuery query) { String subscriptionId = query.getSubscriptionIdentifier(); subscriptions.get(subscriptionId).initialResult().subscribe( i -> publisher.publish(serializer.serialize(i, subscriptionId)), e -> logger.debug("Error in initial result for subscription id: {}", subscriptionId) ); }
@GetMapping(value = "/rooms/{roomId}/messages/subscribe", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<ChatMessage> subscribeRoomMessages(@PathVariable String roomId) { RoomMessagesQuery query = new RoomMessagesQuery(roomId); SubscriptionQueryResult<List<ChatMessage>, ChatMessage> result; result = gateway.subscriptionQuery(query, multipleInstancesOf(ChatMessage.class), instanceOf(ChatMessage.class)); /* If you only want to send new messages to the client, you could simply do: return result.updates(); However, in our implementation we want to provide both existing messages and new ones, so we combine the initial result and the updates in a single flux. */ Flux<ChatMessage> initialResult = result.initialResult().flatMapMany(Flux::fromIterable); return Flux.concat(initialResult, result.updates()); }
/** * Delegates handling of initial result and incremental updates to the provided consumers. Subscription to the * incremental updates is done after the initial result is retrieved and its consumer is invoked. If anything goes * wrong during invoking or consuming initial result or incremental updates, subscription is cancelled. * * @param initialResultConsumer The consumer to be invoked when the initial result is retrieved * @param updateConsumer The consumer to be invoked when incremental updates are emitted */ default void handle(Consumer<? super I> initialResultConsumer, Consumer<? super U> updateConsumer) { initialResult().subscribe(initialResult -> { try { initialResultConsumer.accept(initialResult); updates().subscribe(updateConsumer::accept); } catch (Exception e) { cancel(); } }, t -> cancel()); } }
@GetMapping("/subscribe/order-book/{orderBookId}") public Flux<ServerSentEvent<OrderBookView>> subscribeToOrderBook(@PathVariable String orderBookId) { SubscriptionQueryResult<OrderBookView, OrderBookView> subscription = queryGateway .subscriptionQuery(new OrderBookByIdQuery(new OrderBookId(orderBookId)), ResponseTypes.instanceOf(OrderBookView.class), ResponseTypes.instanceOf(OrderBookView.class)); return subscription.initialResult().concatWith(subscription.updates()) .map(ob -> ServerSentEvent.builder(ob).build()); }
/** * Delegates handling of initial result and incremental updates to the provided consumers. Subscription to the * incremental updates is done after the initial result is retrieved and its consumer is invoked. If anything goes * wrong during invoking or consuming initial result or incremental updates, subscription is cancelled. * * @param initialResultConsumer The consumer to be invoked when the initial result is retrieved * @param updateConsumer The consumer to be invoked when incremental updates are emitted */ default void handle(Consumer<? super I> initialResultConsumer, Consumer<? super U> updateConsumer) { initialResult().subscribe(initialResult -> { try { initialResultConsumer.accept(initialResult); updates().subscribe(updateConsumer::accept); } catch (Exception e) { cancel(); } }, t -> cancel()); } }
@Override public <Q, I, U> SubscriptionQueryResult<I, U> subscriptionQuery(String queryName, Q query, ResponseType<I> initialResponseType, ResponseType<U> updateResponseType, SubscriptionQueryBackpressure backpressure, int updateBufferSize) { SubscriptionQueryMessage<Q, I, U> subscriptionQueryMessage = new GenericSubscriptionQueryMessage<>(query, queryName, initialResponseType, updateResponseType); SubscriptionQueryResult<QueryResponseMessage<I>, SubscriptionQueryUpdateMessage<U>> result = queryBus .subscriptionQuery(processInterceptors(subscriptionQueryMessage), backpressure, updateBufferSize); return new DefaultSubscriptionQueryResult<>( result.initialResult() .filter(initialResult -> Objects.nonNull(initialResult.getPayload())) .map(QueryResponseMessage::getPayload), result.updates() .filter(update -> Objects.nonNull(update.getPayload())) .map(SubscriptionQueryUpdateMessage::getPayload), result ); }
@Override public <Q, I, U> SubscriptionQueryResult<I, U> subscriptionQuery(String queryName, Q query, ResponseType<I> initialResponseType, ResponseType<U> updateResponseType, SubscriptionQueryBackpressure backpressure, int updateBufferSize) { SubscriptionQueryMessage<Q, I, U> subscriptionQueryMessage = new GenericSubscriptionQueryMessage<>(query, queryName, initialResponseType, updateResponseType); SubscriptionQueryResult<QueryResponseMessage<I>, SubscriptionQueryUpdateMessage<U>> result = queryBus .subscriptionQuery(processInterceptors(subscriptionQueryMessage), backpressure, updateBufferSize); return new DefaultSubscriptionQueryResult<>( result.initialResult() .filter(initialResult -> Objects.nonNull(initialResult.getPayload())) .map(Message::getPayload) .onErrorMap(e -> e instanceof IllegalPayloadAccessException ? e.getCause() : e), result.updates() .filter(update -> Objects.nonNull(update.getPayload())) .map(SubscriptionQueryUpdateMessage::getPayload), result ); }
@Override @Synchronized protected int sizeInBackEnd(Query<CardSummary, Void> query) { if (countQueryResult != null) { countQueryResult.cancel(); countQueryResult = null; } CountCardSummariesQuery countCardSummariesQuery = new CountCardSummariesQuery(filter); log.trace("submitting {}", countCardSummariesQuery); countQueryResult = queryGateway.subscriptionQuery(countCardSummariesQuery, ResponseTypes.instanceOf(CountCardSummariesResponse.class), ResponseTypes.instanceOf(CountChangedUpdate.class)); /* When the count changes (new giftcards issued), the UI has to do an entirely new query (this is * how the Vaadin grid works). When we're bulk issuing, it doesn't make sense to do that on every single * issue event. Therefore, we buffer the updates for 250 milliseconds using reactor, and do the new * query at most once per 250ms. */ countQueryResult.updates().buffer(Duration.ofMillis(250)).subscribe( countChanged -> { log.trace("processing query update for {}: {}", countCardSummariesQuery, countChanged); /* This won't do, would lead to immediate new queries, looping a few times. */ // fireEvent(new DataChangeEvent(this)); executorService.execute(() -> fireEvent(new DataChangeEvent<>(this))); }); return countQueryResult.initialResult().block().getCount(); }
return fetchQueryResult.initialResult().block().stream();