package io.muoncore.protocol.event.server; import io.muoncore.Discovery; import io.muoncore.channel.Channel; import io.muoncore.channel.ChannelConnection; import io.muoncore.channel.Channels; import io.muoncore.codec.Codecs; import io.muoncore.descriptors.ProtocolDescriptor; import io.muoncore.descriptors.SchemaDescriptor; import io.muoncore.message.MuonInboundMessage; import io.muoncore.message.MuonMessageBuilder; import io.muoncore.message.MuonOutboundMessage; import io.muoncore.protocol.ServerProtocolStack; import io.muoncore.protocol.event.Event; import io.muoncore.protocol.event.EventCodec; import io.muoncore.protocol.event.EventProtocolMessages; import io.muoncore.protocol.event.client.EventResult; import reactor.Environment; import reactor.core.Dispatcher; import reactor.core.config.DispatcherType; import java.util.Collections; import java.util.Map; /** * Server side of the event protocol */ public class EventServerProtocolStack implements ServerProtocolStack { private final ChannelConnection.ChannelFunction<EventWrapper>handler; private Codecs codecs; private Discovery discovery; private Dispatcher dispatcher = Environment.newDispatcher("EVENTDISPATCH", 10000, 5, DispatcherType.MPSC); public EventServerProtocolStack(ChannelConnection.ChannelFunction<EventWrapper> handler, Codecs codecs, Discovery discovery) { this.codecs = codecs; this.handler = handler; this.discovery = discovery; } @Override @SuppressWarnings("unchecked") public ChannelConnection<MuonInboundMessage, MuonOutboundMessage> createChannel() { Channel<MuonOutboundMessage, MuonInboundMessage> api2 = Channels.channel("eventserver", "transport"); api2.left().receive( message -> { if (message == null || message.getPayload() == null) { System.out.println("Null received from the channel " + message); return; } Map data = codecs.decode(message.getPayload(), message.getContentType(), Map.class); Event ev = EventCodec.getEventFromMap(data, codecs); Channel<EventResult, EventWrapper> evserver = Channels.channel("eventserverapp", "wrapper"); EventWrapper wrapper = new EventWrapper(ev, evserver.left()); evserver.right().receive( eventResult -> { Codecs.EncodingResult result = codecs.encode(eventResult, discovery.getCodecsForService(message.getSourceServiceName())); MuonOutboundMessage msg = MuonMessageBuilder.fromService(message.getTargetServiceName()) .toService(message.getSourceServiceName()) .protocol(EventProtocolMessages.PROTOCOL) .step(EventProtocolMessages.EVENT_RESULT) .contentType(result.getContentType()) .payload(result.getPayload()).build(); dispatcher.dispatch(msg, api2.left()::send, Throwable::printStackTrace); }); dispatcher.dispatch(wrapper, handler::apply, Throwable::printStackTrace); }); return api2.right(); } @Override public ProtocolDescriptor getProtocolDescriptor() { return new ProtocolDescriptor( EventProtocolMessages.PROTOCOL, "Event Sink Protocol", "Provides a discoverable sink for events to flow into without needing explicit service endpoints", Collections.emptyList()); } @Override public Map<String, SchemaDescriptor> getSchemasFor(String endpoint) { return Collections.emptyMap(); } }