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

The following examples show how to use reactor.core.publisher.Flux#flatMap() . 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: GuideTests.java    From reactor-core with 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 File: Fluxs.java    From cyclops with 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 File: AbstractEventHandlerTest.java    From Moss with 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
Source File: SpannerStatement.java    From cloud-spanner-r2dbc with Apache License 2.0 5 votes vote down vote up
@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
Source File: HelloController.java    From springdoc-openapi with Apache License 2.0 5 votes vote down vote up
@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
Source File: RequestPartMethodArgumentResolver.java    From java-technology-stack with MIT License 5 votes vote down vote up
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
Source File: Jackson2Tokenizer.java    From java-technology-stack with MIT License 5 votes vote down vote up
/**
 * 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
Source File: R031_FlatMap.java    From reactor-workshop with GNU General Public License v3.0 5 votes vote down vote up
@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
Source File: ReactorDemoTest.java    From reactive-streams-in-java with Apache License 2.0 5 votes vote down vote up
@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
Source File: ReactorDemoTest.java    From reactive-streams-in-java with Apache License 2.0 5 votes vote down vote up
@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 File: EvaluationStrategyImpl.java    From semagrow with 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
Source File: Fluxs.java    From cyclops with 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 13
Source File: NotificationTrigger.java    From spring-boot-admin with Apache License 2.0 4 votes vote down vote up
@Override
protected Publisher<Void> handle(Flux<InstanceEvent> publisher) {
	return publisher.flatMap(this::sendNotifications);
}
 
Example 14
Source File: Fluxs.java    From cyclops with 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 15
Source File: Fluxs.java    From cyclops with 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 File: Fluxs.java    From cyclops with 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 17
Source File: DeviceAlarmTaskExecutorProvider.java    From jetlinks-community with Apache License 2.0 4 votes vote down vote up
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 18
Source File: Fluxs.java    From cyclops with 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 File: Jaxb2XmlDecoder.java    From java-technology-stack with 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 File: Fluxs.java    From cyclops with 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));
    });

}