Java Code Examples for reactor.core.publisher.Flux#flatMap()

The following examples show how to use reactor.core.publisher.Flux#flatMap() . These examples are extracted from open source projects. 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 Project: reactor-core   File: GuideTests.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void introFutureHellReactorVersion() {
	Flux<String> ids = ifhrIds(); // <1>

	Flux<String> combinations =
			ids.flatMap(id -> { // <2>
				Mono<String> nameTask = ifhrName(id); // <3>
				Mono<Integer> statTask = ifhrStat(id); // <4>

				return nameTask.zipWith(statTask, // <5>
						(name, stat) -> "Name " + name + " has stats " + stat);
			});

	Mono<List<String>> result = combinations.collectList(); // <6>

	List<String> results = result.block(); // <7>
	assertThat(results).containsExactly( // <8>
			"Name NameJoe has stats 103",
			"Name NameBart has stats 104",
			"Name NameHenry has stats 105",
			"Name NameNicole has stats 106",
			"Name NameABSLAJNFOAJNFOANFANSF has stats 121"
	);
}
 
Example 2
Source Project: cyclops   File: Fluxs.java    License: Apache License 2.0 6 votes vote down vote up
public static  <T,R> Flux<R> tailRec(T initial, Function<? super T, ? extends Flux<? extends Either<T, R>>> fn) {
    Flux<Either<T, R>> next = Flux.just(Either.left(initial));

    boolean newValue[] = {true};
    for(;;){

        next = next.flatMap(e -> e.fold(s -> {
                    newValue[0]=true;
                    return fn.apply(s); },
                p -> {
                    newValue[0]=false;
                    return Flux.just(e);
                }));
        if(!newValue[0])
            break;

    }

    return next.filter(Either::isRight).map(e->e.orElse(null));
}
 
Example 3
Source Project: Moss   File: AbstractEventHandlerTest.java    License: Apache License 2.0 5 votes vote down vote up
@Override
protected Publisher<Void> handle(Flux<InstanceRegisteredEvent> publisher) {
    return publisher.flatMap(event -> {
        if (event.equals(errorEvent)) {
            throw (new IllegalStateException("Error"));
        } else {
            log.info("Event {}", event);
            sink.next(event);
            return Mono.empty();
        }
    });
}
 
Example 4
@Override
public Publisher<? extends Result> execute() {
  if (this.statementType == StatementType.DDL) {
    return this.client
        .executeDdl(
            this.config.getFullyQualifiedDatabaseName(),
            Collections.singletonList(this.sql),
            this.config.getDdlOperationTimeout(),
            this.config.getDdlOperationPollInterval())
        .map(operation -> new SpannerResult(Flux.empty(), Mono.just(0)));
  } else if (this.statementType == StatementType.DML && !this.ctx.isTransactionPartitionedDml()) {

    List<ExecuteBatchDmlRequest.Statement> dmlStatements =
        this.statementBindings.getBindings().stream()
            .map(struct ->
                ExecuteBatchDmlRequest.Statement.newBuilder()
                    .setSql(this.sql)
                    .setParams(struct)
                    .putAllParamTypes(this.statementBindings.getTypes())
                    .build())
            .collect(Collectors.toList());

    return this.client.executeBatchDml(this.ctx, dmlStatements)
        .map(partialResultSet -> Math.toIntExact(partialResultSet.getStats().getRowCountExact()))
        .map(rowCount -> new SpannerResult(Flux.empty(), Mono.just(rowCount)));
  }

  Flux<Struct> structFlux = Flux.fromIterable(this.statementBindings.getBindings());
  return structFlux.flatMap(this::runStreamingSql);
}
 
Example 5
@PostMapping(value = "/files", produces = { MediaType.APPLICATION_JSON_VALUE}, consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
@Operation(summary = "files")
public Flux<Void> handleFileUpload(
		@RequestPart("files") @Parameter(description = "files",
				content = @Content(mediaType = MediaType.APPLICATION_OCTET_STREAM_VALUE))
				Flux<FilePart> filePartFux) throws IOException {
	File tmp = File.createTempFile("tmp", "");
	return filePartFux.flatMap(filePart -> {
		Path path = Paths.get(tmp.toString() + filePart.filename());
		System.out.println(path);
		return filePart.transferTo(path);
	});
}
 
Example 6
private Flux<?> decodePartValues(Flux<Part> parts, MethodParameter elementType, BindingContext bindingContext,
		ServerWebExchange exchange, boolean isRequired) {

	return parts.flatMap(part -> {
		ServerHttpRequest partRequest = new PartServerHttpRequest(exchange.getRequest(), part);
		ServerWebExchange partExchange = exchange.mutate().request(partRequest).build();
		if (logger.isDebugEnabled()) {
			logger.debug(exchange.getLogPrefix() + "Decoding part '" + part.name() + "'");
		}
		return readBody(elementType, isRequired, bindingContext, partExchange);
	});
}
 
Example 7
/**
 * Tokenize the given {@code Flux<DataBuffer>} into {@code Flux<TokenBuffer>}.
 * @param dataBuffers the source data buffers
 * @param jsonFactory the factory to use
 * @param tokenizeArrayElements if {@code true} and the "top level" JSON
 * object is an array, each element is returned individually, immediately
 * after it is received.
 * @return the result token buffers
 */
public static Flux<TokenBuffer> tokenize(Flux<DataBuffer> dataBuffers, JsonFactory jsonFactory,
		boolean tokenizeArrayElements) {

	try {
		JsonParser parser = jsonFactory.createNonBlockingByteArrayParser();
		Jackson2Tokenizer tokenizer = new Jackson2Tokenizer(parser, tokenizeArrayElements);
		return dataBuffers.flatMap(tokenizer::tokenize, Flux::error, tokenizer::endOfInput);
	}
	catch (IOException ex) {
		return Flux.error(ex);
	}
}
 
Example 8
@Test
public void chessboard() throws Exception {
	//given
	final Flux<Integer> rows = Flux.range(1, 8);
	final Flux<String> cols = Flux.just("a", "b", "c", "d", "e", "f", "g", "h");

	//when
	final Flux<String> allFields = rows.flatMap(row -> cols.map(col -> col + row));

	//then
	final List<String> fields = allFields.collectList().block();
	assertThat(fields)
			.hasSize(8 * 8)
			.contains("a1", "a2", "b1", "b2", "h1", "h8");
}
 
Example 9
@Test
public void testStepVerifier_Context_Wrong() {
    Flux<Integer> flux = Flux.just(1).subscriberContext(Context.of("pid", 123));

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

    StepVerifier.create(stringFlux)
            .expectNext("1 pid: 0")
            .verifyComplete();
}
 
Example 10
@Test
public void testStepVerifier_Context_Right() {
    Flux<Integer> flux = Flux.just(1);

    Flux<String> 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 11
Source Project: semagrow   File: EvaluationStrategyImpl.java    License: Apache License 2.0 5 votes vote down vote up
public Flux<BindingSet> evaluateReactorInternal(Group expr, BindingSet bindings)
        throws QueryEvaluationException
{
    Set<String> groupByBindings = expr.getGroupBindingNames();

    Flux<BindingSet> s = evaluateReactorInternal(expr.getArg(), bindings);

    Flux<GroupedFlux<BindingSet, BindingSet>> g = s.groupBy((b) -> bindingSetOps.project(groupByBindings, b, bindings));

    //return g.flatMap((gs) -> Streams.just(gs.key()));
    return g.flatMap((gs) -> aggregate(gs, expr, bindings));
}
 
Example 12
@Override
protected Publisher<Void> handle(Flux<InstanceEvent> publisher) {
	return publisher.flatMap(this::sendNotifications);
}
 
Example 13
public Flux<Map<String, Object>> doSubscribe(MessageGateway gateway) {
    Set<String> topics = new HashSet<>();

    List<Object> binds = new ArrayList<>();

    for (DeviceAlarmRule.Trigger trigger : rule.getTriggers()) {
        String topic = trigger.getType().getTopic(rule.getProductId(), rule.getDeviceId(), trigger.getModelId());
        topics.add(topic);
        binds.addAll(trigger.toFilterBinds());
    }
    List<Subscription> subscriptions = topics.stream().map(Subscription::new).collect(Collectors.toList());

    ReactorQLContext context = ReactorQLContext
        .ofDatasource(ignore ->
            gateway
                .subscribe(subscriptions, "device_alarm:" + rule.getId(), false)
                .flatMap(msg -> Mono.justOrEmpty(DeviceMessageUtils.convert(msg).map(DeviceMessage::toJson)))
                .doOnNext(json -> {
                    if (StringUtils.hasText(rule.getDeviceName())) {
                        json.putIfAbsent("deviceName", rule.getDeviceName());
                    }
                    if (StringUtils.hasText(rule.getProductName())) {
                        json.putIfAbsent("productName", rule.getProductName());
                    }
                    json.put("productId", rule.getProductId());
                    json.put("alarmId", rule.getId());
                    json.put("alarmName", rule.getName());
                })
        );

    binds.forEach(context::bind);

    Flux<Map<String, Object>> resultFlux = (ql == null ? ql = createQL(rule) : ql)
        .start(context)
        .map(ReactorQLRecord::asMap);

    DeviceAlarmRule.ShakeLimit shakeLimit;
    if ((shakeLimit = rule.getShakeLimit()) != null
        && shakeLimit.isEnabled()
        && shakeLimit.getTime() > 0) {
        int thresholdNumber = shakeLimit.getThreshold();
        //打开时间窗口
        Flux<Flux<Map<String, Object>>> window = resultFlux.window(Duration.ofSeconds(shakeLimit.getTime()));

        Function<Flux<Tuple2<Long, Map<String, Object>>>, Publisher<Tuple2<Long, Map<String, Object>>>> mapper =
            shakeLimit.isAlarmFirst()
                ?
                group -> group
                    .takeUntil(tp -> tp.getT1() >= thresholdNumber)
                    .take(1)
                    .singleOrEmpty()
                :
                group -> group.takeLast(1).singleOrEmpty();

        resultFlux = window
            .flatMap(group -> group
                .index((index, data) -> Tuples.of(index + 1, data))
                .transform(mapper)
                .filter(tp -> tp.getT1() >= thresholdNumber) //超过阈值告警
                .map(tp2 -> {
                    tp2.getT2().put("totalAlarms", tp2.getT1());
                    return tp2.getT2();
                }));
    }

    return resultFlux
        .flatMap(map -> {
            map.put("productId", rule.getProductId());
            map.put("alarmId", rule.getId());
            map.put("alarmName", rule.getName());
            if (StringUtils.hasText(rule.getDeviceName())) {
                map.putIfAbsent("deviceName", rule.getDeviceName());
            }
            if (StringUtils.hasText(rule.getProductName())) {
                map.putIfAbsent("productName", rule.getProductName());
            }
            if (StringUtils.hasText(rule.getDeviceId())) {
                map.putIfAbsent("deviceId", rule.getDeviceId());
            }
            if (!map.containsKey("deviceName")) {
                map.putIfAbsent("deviceName", map.get("deviceId"));
            }
            if (!map.containsKey("productName")) {
                map.putIfAbsent("productName", map.get("productId"));
            }
            if (log.isDebugEnabled()) {
                log.debug("发生设备告警:{}", map);
            }
            // 推送告警信息到消息网关中
            // /rule-engine/device/alarm/{productId}/{deviceId}/{ruleId}
            return gateway
                .publish(String.format(
                    "/rule-engine/device/alarm/%s/%s/%s",
                    rule.getProductId(), map.get("deviceId"), rule.getId()
                ), map, true)
                .then(Mono.just(map));
        });
}
 
Example 14
Source Project: cyclops   File: Fluxs.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Perform a For Comprehension over a Flux, accepting 3 generating functions.
 * This results in a four level nested internal iteration over the provided Publishers.
 *
 *  <pre>
  * {@code
  *
  *   import static cyclops.companion.reactor.Fluxs.forEach4;
  *
      forEach4(Flux.range(1,10),
              a-> ReactiveSeq.iterate(a,i->i+1).limit(10),
              (a,b) -> Maybe.<Integer>of(a+b),
              (a,b,c) -> Mono.<Integer>just(a+b+c),
              Tuple::tuple)
 *
 * }
 * </pre>
 *
 * @param value1 top level Flux
 * @param value2 Nested publisher
 * @param value3 Nested publisher
 * @param value4 Nested publisher
 * @param yieldingFunction  Generates a result per combination
 * @return Flux with an element per combination of nested publishers generated by the yielding function
 */
public static <T1, T2, T3, R1, R2, R3, R> Flux<R> forEach4(Flux<? extends T1> value1,
                                                           Function<? super T1, ? extends Publisher<R1>> value2,
        BiFunction<? super T1, ? super R1, ? extends Publisher<R2>> value3,
        Function3<? super T1, ? super R1, ? super R2, ? extends Publisher<R3>> value4,
        Function4<? super T1, ? super R1, ? super R2, ? super R3, ? extends R> yieldingFunction) {


    return value1.flatMap(in -> {

        Flux<R1> a = Flux.from(value2.apply(in));
        return a.flatMap(ina -> {
            Flux<R2> b = Flux.from(value3.apply(in,ina));
            return b.flatMap(inb -> {
                Flux<R3> c = Flux.from(value4.apply(in,ina,inb));
                return c.map(in2 -> yieldingFunction.apply(in, ina, inb, in2));
            });

        });

    });


}
 
Example 15
Source Project: cyclops   File: Fluxs.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Perform a For Comprehension over a Flux, accepting 3 generating functions.
 * This results in a four level nested internal iteration over the provided Publishers.
 * <pre>
 * {@code
 *
 *  import static cyclops.companion.reactor.Fluxs.forEach4;
 *
 *  forEach4(Flux.range(1,10),
                        a-> ReactiveSeq.iterate(a,i->i+1).limit(10),
                        (a,b) -> Maybe.<Integer>just(a+b),
                        (a,b,c) -> Mono.<Integer>just(a+b+c),
                        (a,b,c,d) -> a+b+c+d <100,
                        Tuple::tuple);
 *
 * }
 * </pre>
 *
 * @param value1 top level Flux
 * @param value2 Nested publisher
 * @param value3 Nested publisher
 * @param value4 Nested publisher
 * @param filterFunction A filtering function, keeps values where the predicate holds
 * @param yieldingFunction Generates a result per combination
 * @return Flux with an element per combination of nested publishers generated by the yielding function
 */
public static <T1, T2, T3, R1, R2, R3, R> Flux<R> forEach4(Flux<? extends T1> value1,
        Function<? super T1, ? extends Publisher<R1>> value2,
        BiFunction<? super T1, ? super R1, ? extends Publisher<R2>> value3,
        Function3<? super T1, ? super R1, ? super R2, ? extends Publisher<R3>> value4,
        Function4<? super T1, ? super R1, ? super R2, ? super R3, Boolean> filterFunction,
        Function4<? super T1, ? super R1, ? super R2, ? super R3, ? extends R> yieldingFunction) {

    return value1.flatMap(in -> {

        Flux<R1> a = Flux.from(value2.apply(in));
        return a.flatMap(ina -> {
            Flux<R2> b = Flux.from(value3.apply(in,ina));
            return b.flatMap(inb -> {
                Flux<R3> c = Flux.from(value4.apply(in,ina,inb));
                return c.filter(in2->filterFunction.apply(in,ina,inb,in2))
                        .map(in2 -> yieldingFunction.apply(in, ina, inb, in2));
            });

        });

    });
}
 
Example 16
Source Project: cyclops   File: Fluxs.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Perform a For Comprehension over a Flux, accepting 2 generating functions.
 * This results in a three level nested internal iteration over the provided Publishers.
 *
 * <pre>
 * {@code
 *
 * import static cyclops.companion.reactor.Fluxs.forEach;
 *
 * forEach(Flux.range(1,10),
                        a-> ReactiveSeq.iterate(a,i->i+1).limit(10),
                        (a,b) -> Maybe.<Integer>of(a+b),
                        Tuple::tuple);
 *
 * }
 * </pre>
 *
 *
 * @param value1 top level Flux
 * @param value2 Nested publisher
 * @param value3 Nested publisher
 * @param yieldingFunction Generates a result per combination
 * @return Flux with an element per combination of nested publishers generated by the yielding function
 */
public static <T1, T2, R1, R2, R> Flux<R> forEach3(Flux<? extends T1> value1,
        Function<? super T1, ? extends Publisher<R1>> value2,
        BiFunction<? super T1, ? super R1, ? extends Publisher<R2>> value3,
        Function3<? super T1, ? super R1, ? super R2, ? extends R> yieldingFunction) {

    return value1.flatMap(in -> {

        Flux<R1> a = Flux.from(value2.apply(in));
        return a.flatMap(ina -> {
            Flux<R2> b = Flux.from(value3.apply(in, ina));
            return b.map(in2 -> yieldingFunction.apply(in, ina, in2));
        });


    });

}
 
Example 17
Source Project: cyclops   File: Fluxs.java    License: Apache License 2.0 4 votes vote down vote up
/**
     * Perform a For Comprehension over a Flux, accepting 2 generating functions.
     * This results in a three level nested internal iteration over the provided Publishers.
     * <pre>
     * {@code
     *
     * import static cyclops.companion.reactor.Fluxs.forEach;
     *
     * forEach(Flux.range(1,10),
                   a-> ReactiveSeq.iterate(a,i->i+1).limit(10),
                   (a,b) -> Maybe.<Integer>of(a+b),
                   (a,b,c) ->a+b+c<10,
                   Tuple::tuple).toListX();
     * }
     * </pre>
     *
     * @param value1 top level Flux
     * @param value2 Nested publisher
     * @param value3 Nested publisher
     * @param filterFunction A filtering function, keeps values where the predicate holds
     * @param yieldingFunction Generates a result per combination
     * @return
     */
public static <T1, T2, R1, R2, R> Flux<R> forEach3(Flux<? extends T1> value1,
        Function<? super T1, ? extends Publisher<R1>> value2,
        BiFunction<? super T1, ? super R1, ? extends Publisher<R2>> value3,
        Function3<? super T1, ? super R1, ? super R2, Boolean> filterFunction,
        Function3<? super T1, ? super R1, ? super R2, ? extends R> yieldingFunction) {

    return value1.flatMap(in -> {

        Flux<R1> a = Flux.from(value2.apply(in));
        return a.flatMap(ina -> {
            Flux<R2> b = Flux.from(value3.apply(in,ina));
            return b.filter(in2->filterFunction.apply(in,ina,in2))
                    .map(in2 -> yieldingFunction.apply(in, ina, in2));
        });



    });

}
 
Example 18
Source Project: cyclops   File: Fluxs.java    License: Apache License 2.0 3 votes vote down vote up
public static <T> Flux<Mono<T>> sequence(final Publisher<? extends Flux<T>> fts) {

        Flux<Mono<T>> identity = Flux.just();

        BiFunction<Flux<Mono<T>>,Flux<T>,Flux<Mono<T>>> combineToStream = (acc,next) ->Flux.merge(acc,next.map(Mono::just));


        Flux<Flux<Mono<T>>> x = Flux.from(fts).reduce(identity, combineToStream).flatMapMany(Flux::just);
        return x.flatMap(i->i);
    }
 
Example 19
Source Project: java-technology-stack   File: Jaxb2XmlDecoder.java    License: MIT License 2 votes vote down vote up
/**
 * Split a flux of {@link XMLEvent XMLEvents} into a flux of XMLEvent lists, one list
 * for each branch of the tree that starts with the given qualified name.
 * That is, given the XMLEvents shown {@linkplain XmlEventDecoder here},
 * and the {@code desiredName} "{@code child}", this method returns a flux
 * of two lists, each of which containing the events of a particular branch
 * of the tree that starts with "{@code child}".
 * <ol>
 * <li>The first list, dealing with the first branch of the tree:
 * <ol>
 * <li>{@link javax.xml.stream.events.StartElement} {@code child}</li>
 * <li>{@link javax.xml.stream.events.Characters} {@code foo}</li>
 * <li>{@link javax.xml.stream.events.EndElement} {@code child}</li>
 * </ol>
 * <li>The second list, dealing with the second branch of the tree:
 * <ol>
 * <li>{@link javax.xml.stream.events.StartElement} {@code child}</li>
 * <li>{@link javax.xml.stream.events.Characters} {@code bar}</li>
 * <li>{@link javax.xml.stream.events.EndElement} {@code child}</li>
 * </ol>
 * </li>
 * </ol>
 */
Flux<List<XMLEvent>> split(Flux<XMLEvent> xmlEventFlux, QName desiredName) {
	return xmlEventFlux.flatMap(new SplitFunction(desiredName));
}
 
Example 20
Source Project: cyclops   File: Fluxs.java    License: Apache License 2.0 1 votes vote down vote up
/**
 * Perform a For Comprehension over a Flux, accepting an additonal generating function.
 * This results in a two level nested internal iteration over the provided Publishers.
 *
 * <pre>
 * {@code
 *
 *  import static cyclops.companion.reactor.Fluxs.forEach;
 *  forEach(Flux.range(1, 10), i -> Flux.range(i, 10), Tuple::tuple)
          .subscribe(System.out::println);

   //(1, 1)
     (1, 2)
     (1, 3)
     (1, 4)
     ...
 *
 * }</pre>
 *
 * @param value1 top level Flux
 * @param value2 Nested publisher
 * @param yieldingFunction Generates a result per combination
 * @return
 */
public static <T, R1, R> Flux<R> forEach(Flux<? extends T> value1, Function<? super T, Flux<R1>> value2,
        BiFunction<? super T, ? super R1, ? extends R> yieldingFunction) {

    return value1.flatMap(in -> {

        Flux<R1> a = Flux.from(value2.apply(in));
        return a.map(in2 -> yieldingFunction.apply(in,  in2));
    });

}