payloadtyperouter直接发送到变压器中,中间没有通道?

s4n0splo  于 2021-07-23  发布在  Java
关注(0)|答案(1)|浏览(271)

我需要一个 PayloadTypeRouter 并希望将路由消息直接发送到 Transformer , Filter 或者 ServiceActivator . 所有这些都应该配置kotlin dsl(或javadsl)。
目前,代码中一个好看的部分如下所示:

@Bean
    fun routeAzureC2DMessage() = integrationFlow {
        channel(IoTHubChannelNames.IOTHUB_TO_DEVICE_CHANNEL)
        route<IotHubC2DRequestMessage<IotHubC2DRequest>> {
            when (it.payload) {
                is IotHubDesiredPropertyUpdate -> IoTHubChannelNames.DESIRED_PROPERTY_UPDATE
                is IotHubMessageToDevice -> IoTHubChannelNames.MESSAGE_TO_DEVICE
            }
        }
    }

然后继续(路线的一侧)

@Bean
    fun processMessageToDevice() = integrationFlow {
        channel(IoTHubChannelNames.MESSAGE_TO_DEVICE)
        filter(StructureFilter())
        transform(MessageTransformer())
        channel(SharedChannelNames.CLOUD2DEVICE)
    }

我想摆脱不必要的频道 IoTHubChannelNames.MESSAGE_TO_DEVICE . 我尝试了几种方法,在项目的另一部分我发现了类似的东西(javadsl)

IntegrationFlows
            .from(channelName)
            .route({ message: IotHubMessage -> message.javaClass }) { router: RouterSpec<Class<*>?, MethodInvokingRouter?> ->
                router
                    .subFlowMapping(DeviceToCloudMessage::class.java) {
                        it.handle(gateway, "handleD2CMessage")
                    }
                    .subFlowMapping(DeviceTwinUpdateMessage::class.java) {
                        it.handle(gateway, "handleDeviceTwinReportedProperty")
                    }
            }
            .get()

subFlowMapping 只有这样才能摆脱中间的通道?我想要一个解决方案,我仍然可以使用 when (it.payload) 然后可以返回一个新的 integrationFlow 或者其他形式的流定义。

mzmfm0qo

mzmfm0qo1#

目前唯一的解决方案是通过api:

inline fun <reified P, T> route(
        crossinline function: (P) -> T,
        crossinline configurer: KotlinRouterSpec<T, MethodInvokingRouter>.() -> Unit) {

你在问什么 when(...) is 语法目前不受支持。
请随意提出关于这个问题的gh问题,并尽可能详细地分享从kotlin的Angular 来看这是什么,以及如何在SpringIntegrationDSL中使用它。
更新
另一方面,目前kotlin的支持也不错:

route<Int, Boolean>({ it % 2 == 0 }) {
                subFlowMapping(true) { handle<Int> { p, _ -> p * 2 } }
                subFlowMapping(false) { handle<Int> { p, _ -> p * 3 } }
            }

所以,我们的论点 route() 方法是 when() 以及 subFlowMapping()is-> 输出为 integrationFlow 生成器结果。所以,也许我们不会去追查Kotlin when() 除非我们输了,否则不会给我们太多的好处 subFlowMapping 赞成 -> 操作员。。。
更新2
经过更多的思考和寻找一个可能的解决方案,我不得不收回我的要求 when() -种类特征请求。
主要问题是 IntegrationFlow 在使用之前,必须在应用程序上下文中预先注册它的所有配置。你在问什么 when() 在原来的路由器功能不是什么框架可以检测和处理你。这一职能不是对产生的结果负责的框架的一部分。
好吧,我们可以查一下 IntegrationFlow return决定如何调用,但不能保证从该函数返回的流是一个注册的bean。当我们真正注册它并尝试在这样一个函数中使用它时,它与我们目前所拥有的从该函数返回的通道以及它们在某个流bean中的Map没有什么区别。
我们可以注册 IntegrationFlow 如bean中自动设计的一些这样的指令 subFlowMapping() . 无论如何,在配置阶段,它只做一次。但当最终用户代码在运行时返回流时,这样做并不太好。最好返回通道或其他一些键,其中我们有一个现有流的Map。
我个人更喜欢不要忽视 MessageChannel 当我需要在不同的流之间分配逻辑时,抽象和使用它。当单个流中的代码是线性的并且表示单个逻辑工作单元时,它看起来更干净。但是,其他流可以在其他逻辑中重用。我只需要指向那些来自其他地方的流输入通道!
然而,我的主要观点是:我们必须登记和 IntegrationFlow 在我们向它发送信息之前。

相关问题