kalix-jvm-sdk
kalix-jvm-sdk copied to clipboard
Accept multiple Topic subscriptions for different request message types
The protocol first allows one method per message type from a topic, but the annotation based one doesn't, will render all methods to accept any which will fail validation:
An action like this:
@Subscribe.EventSourcedEntity(value = DigitalTwinEntity.class,ignoreUnknown = true)
@Publish.Stream(id = "dt-output")
public class OutputTopicPublisherAction extends Action {
@Publish.Topic("output")
public Effect<Model.AlertTriggeredMessage> onAlertTriggeredEvent(Model.AlertTriggeredEvent event){
return effects().reply(new Model.AlertTriggeredMessage(event.dtId(),event.metricValue(),event.timestamp()));
}
@Publish.Topic("output")
public Effect<Model.AlertCanceledMessage> onAlertCanceledEvent(Model.AlertCanceledEvent event){
return effects().reply(new Model.AlertCanceledMessage(event.dtId(),event.timestamp()));
}
}
Will give an error like this
2023-03-01 12:39:58,063 ERROR kalix.javasdk.impl.DiscoveryImpl - Error reported from Kalix system: KLX-00424 Multiple direct eventing methods accepting the same type of message not allowed. Overlapping methods: [com.example.digitaltwin.OutputTopicPublisherAction.KalixSyntheticMethodOnESDigitaltwin,com.example.digitaltwin.OutputTopicPublisherAction.OnAlertCanceledEvent,com.example.digitaltwin.OutputTopicPublisherAction.OnAlertTriggeredEvent] accept [Any]
The annotation based SDK should probably map them to a single gRPC method and do the routing based on deserialised message type to the actual methods once the message reaches the SDK.
Shall we better call this issue something like? ' Accept multiple Topic publications for different message types?
Would this also cover publishing to multiple topics? Example:
@Subscribe.EventSourcedEntity(value = DigitalTwinEntity.class,ignoreUnknown = true)
public class OutputTopicPublisherAction extends Action {
@Publish.Topic("alert-triggered-output")
public Effect<Model.AlertTriggeredMessage> onAlertTriggeredEvent(Model.AlertTriggeredEvent event){
return effects().reply(new Model.AlertTriggeredMessage(event.dtId(),event.metricValue(),event.timestamp()));
}
@Publish.Topic("alert-canceled-output")
public Effect<Model.AlertCanceledMessage> onAlertCanceledEvent(Model.AlertCanceledEvent event){
return effects().reply(new Model.AlertCanceledMessage(event.dtId(),event.timestamp()));
}
}
Would this also cover publishing to multiple topics? Example:
@Subscribe.EventSourcedEntity(value = DigitalTwinEntity.class,ignoreUnknown = true) public class OutputTopicPublisherAction extends Action { @Publish.Topic("alert-triggered-output") public Effect<Model.AlertTriggeredMessage> onAlertTriggeredEvent(Model.AlertTriggeredEvent event){ return effects().reply(new Model.AlertTriggeredMessage(event.dtId(),event.metricValue(),event.timestamp())); } @Publish.Topic("alert-canceled-output") public Effect<Model.AlertCanceledMessage> onAlertCanceledEvent(Model.AlertCanceledEvent event){ return effects().reply(new Model.AlertCanceledMessage(event.dtId(),event.timestamp())); } }
Is that something that works out of the box for Protobuf SDKs? I guess so. For each unique topic target, we have a different projection.
So, in principle that should already work for the Java SDK as we will have two projections each delivering events to a different method in the action.