Java 如何在SpringCloudStream中配置函数的绑定,将其输入绑定到web端点,将其输出绑定到Kafka主题
我有一个常规的javaJava 如何在SpringCloudStream中配置函数的绑定,将其输入绑定到web端点,将其输出绑定到Kafka主题,java,spring-boot,java-8,spring-cloud,functional-interface,Java,Spring Boot,Java 8,Spring Cloud,Functional Interface,我有一个常规的java函数;我正试图将其绑定: 将其输入到web端点 将其输出为卡夫卡主题 当我在web上下文中使用我的函数时,它总是将函数的结果值单独返回给web客户端。我可以这样做吗 spring.cloud.stream.bindings.input.binder=web spring.cloud.stream.bindings.output.binder=kafka 我目前甚至正在尝试将函数分为两部分: 其输入绑定到web客户端,其输出动态绑定到第二个函数(使用spring.clou
函数
;我正试图将其绑定:
函数的结果值
单独返回给web客户端。我可以这样做吗
spring.cloud.stream.bindings.input.binder=web
spring.cloud.stream.bindings.output.binder=kafka
我目前甚至正在尝试将函数
分为两部分:
- 其输入绑定到web客户端,其输出动态绑定到第二个函数(使用
)spring.cloud.stream.sendto.destination
- 另一个函数,其输出绑定到kafka绑定
spring.cloud.stream.sendto.destination
)显示在web客户端上;但是没有消息
发送到卡夫卡绑定本身。下面是我在第二种方法(2个函数)中使用的代码,希望得到一个Spring函数应用程序,将其输入绑定到web端点,并将输出绑定到kafka主题
WebToKafkaApp.java
@SpringBootApplication
public class WebToKafkaApp {
public static void main(String[] args) {
SpringApplication.run(WebToKafkaApp.class, args);
}
@Bean
public Function<String, Message<String>> webFunction() {
return payload -> createPayloadMapperToMessage("kafkaFunction").apply(payload);
}
@Bean
public Function<Flux<Message<String>>, Flux<Message<String>>> kafkaFunction() {
return flux -> flux.map(msg -> createPayloadMapperToMessage("").apply(msg.getPayload()));
}
private Function<String, Message<String>> createPayloadMapperToMessage(String destination) {
return payload -> MessageBuilder
.withPayload(payload.toUpperCase())
.setHeader("spring.cloud.stream.sendto.destination", destination)
.build();
}
}
build.gradle
plugins {
id 'org.springframework.boot' version '2.2.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "Hoxton.RELEASE")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.cloud:spring-cloud-starter-function-web'
implementation 'org.springframework.cloud:spring-cloud-starter-function-webflux'
implementation 'org.springframework.cloud:spring-cloud-stream'
implementation 'org.springframework.cloud:spring-cloud-starter-stream-kafka'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
test {
useJUnitPlatform()
}
任何帮助都将不胜感激。感谢您的发布。基本上,我强化了他的建议,即一般性地处理以下两者之间的桥梁:
供应商的自定义实现中。这样的实现公开了一个API来触发供应商发出作为参数传递的消息。这样的类将如下所示:
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import java.util.function.Supplier;
import reactor.core.publisher.EmitterProcessor;
import reactor.core.publisher.Flux;
public class StreamSupplier implements Supplier<Flux<?>> {
private static final String SPRING_CLOUD_STREAM_SENDTO_DESTINATION =
"spring.cloud.stream.sendto.destination";
public static <T> Message<?> createMessage(T payload, String destination) {
MessageBuilder<T> builder = MessageBuilder.withPayload(payload);
if (destination != null && !destination.isEmpty())
builder.setHeader(SPRING_CLOUD_STREAM_SENDTO_DESTINATION, destination);
return builder.build();
}
private String defaultDestination;
private EmitterProcessor<? super Object> processor = EmitterProcessor.create();
public StreamSupplier() {
this(null);
}
public StreamSupplier(String defaultDestination) {
this.defaultDestination = defaultDestination;
}
// SEND APIs
public <T> Message<?> sendMessage(T payload) {
return sendMessage(payload, defaultDestination);
}
public <T> Message<?> sendMessage(T payload, String destination) {
return sendBody(createMessage(payload, destination));
}
public <T> T sendBody(T body) {
processor.onNext(body);
return body;
}
/**
* Returns {@link EmitterProcessor} used internally to programmatically publish messages onto
* the output binding associated with this {@link Supplier}. Such programmatic publications
* are available through the {@code sendXXX} API methods available in this class.
*/
@Override
public Flux<?> get() {
return processor;
}
}
再次感谢您为我提供了构建此综合解决方案所需的资源
请在感谢@OlegZhurakousky为我指明了正确的方向中查看答案。我只是通过在您的细节之上构建额外的抽象级别来回答我的问题。
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import java.util.function.Supplier;
import reactor.core.publisher.EmitterProcessor;
import reactor.core.publisher.Flux;
public class StreamSupplier implements Supplier<Flux<?>> {
private static final String SPRING_CLOUD_STREAM_SENDTO_DESTINATION =
"spring.cloud.stream.sendto.destination";
public static <T> Message<?> createMessage(T payload, String destination) {
MessageBuilder<T> builder = MessageBuilder.withPayload(payload);
if (destination != null && !destination.isEmpty())
builder.setHeader(SPRING_CLOUD_STREAM_SENDTO_DESTINATION, destination);
return builder.build();
}
private String defaultDestination;
private EmitterProcessor<? super Object> processor = EmitterProcessor.create();
public StreamSupplier() {
this(null);
}
public StreamSupplier(String defaultDestination) {
this.defaultDestination = defaultDestination;
}
// SEND APIs
public <T> Message<?> sendMessage(T payload) {
return sendMessage(payload, defaultDestination);
}
public <T> Message<?> sendMessage(T payload, String destination) {
return sendBody(createMessage(payload, destination));
}
public <T> T sendBody(T body) {
processor.onNext(body);
return body;
}
/**
* Returns {@link EmitterProcessor} used internally to programmatically publish messages onto
* the output binding associated with this {@link Supplier}. Such programmatic publications
* are available through the {@code sendXXX} API methods available in this class.
*/
@Override
public Flux<?> get() {
return processor;
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import java.util.function.Function;
import java.util.function.Supplier;
import reactor.core.publisher.Flux;
@SpringBootApplication
@Controller
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class,
"--spring.cloud.function.definition=streamSupplierFunction;webToStreamFunction");
}
// Functional Web Controller
@Bean
public Function<String, String> webToStreamFunction() {
return msg -> streamSupplier().sendBody(msg);
}
// Functional Stream Supplier
@Bean
public Supplier<Flux<?>> streamSupplierFunction() {
return new StreamSupplier();
}
// DOUBLE REGISTRATION TO AVOID POLLABLE CONFIGURATION
// LIMITATION OF SPRING-CLOUD-FUNCTION
@Bean
public StreamSupplier streamSupplier() {
return (StreamSupplier) streamSupplierFunction();
}
}