use of org.eclipse.ditto.internal.utils.pubsub.StreamingType in project ditto by eclipse.
the class StreamingSessionActor method createOutgoingSignalBehavior.
private Receive createOutgoingSignalBehavior() {
final PartialFunction<Object, Object> setCorrelationIdAndStartAckForwarder = new PFBuilder<>().match(Signal.class, this::startAckForwarder).match(DittoRuntimeException.class, x -> x).build();
final Receive publishSignal = ReceiveBuilder.create().match(SubscriptionEvent.class, signal -> {
logger.debug("Got SubscriptionEvent in <{}> session, publishing: {}", type, signal);
eventAndResponsePublisher.offer(SessionedJsonifiable.subscription(signal));
}).match(CommandResponse.class, this::publishResponseOrError).match(DittoRuntimeException.class, this::publishResponseOrError).match(Signal.class, this::isSameOrigin, signal -> logger.withCorrelationId(signal).debug("Got Signal of type <{}> in <{}> session, but this was issued by " + " this connection itself, not publishing", signal.getType(), type)).match(Signal.class, signal -> {
// check if this session is "allowed" to receive the Signal
final var streamingType = determineStreamingType(signal);
@Nullable final var session = streamingSessions.get(streamingType);
if (null != session && isSessionAllowedToReceiveSignal(signal, session, streamingType)) {
final ThreadSafeDittoLoggingAdapter l = logger.withCorrelationId(signal);
l.info("Publishing Signal of type <{}> in <{}> session", signal.getType(), type);
l.debug("Publishing Signal of type <{}> in <{}> session: {}", type, signal.getType(), signal);
final DittoHeaders sessionHeaders = DittoHeaders.newBuilder().authorizationContext(authorizationContext).schemaVersion(jsonSchemaVersion).build();
final var sessionedJsonifiable = SessionedJsonifiable.signal(signal, sessionHeaders, session);
eventAndResponsePublisher.offer(sessionedJsonifiable);
}
}).matchEquals(Done.getInstance(), done -> {
/* already done, nothing to publish */
}).build();
return addPreprocessors(List.of(setCorrelationIdAndStartAckForwarder), publishSignal);
}
use of org.eclipse.ditto.internal.utils.pubsub.StreamingType in project ditto by eclipse.
the class OutboundMappingProcessorActor method splitTargetsByExtraFields.
/**
* Split the targets of an outbound signal into 2 parts: those without extra fields and those with.
*
* @param outboundSignal The outbound signal.
* @return A pair of lists. The first list contains targets without matching extra fields.
* The second list contains targets together with their extra fields matching the outbound signal.
*/
private static Pair<List<Target>, List<Pair<Target, FilteredTopic>>> splitTargetsByExtraFields(final OutboundSignal outboundSignal) {
final Optional<StreamingType> streamingTypeOptional = StreamingType.fromSignal(outboundSignal.getSource());
if (streamingTypeOptional.isPresent()) {
// Find targets with a matching topic with extra fields
final StreamingType streamingType = streamingTypeOptional.get();
final List<Target> targetsWithoutExtraFields = new ArrayList<>(outboundSignal.getTargets().size());
final List<Pair<Target, FilteredTopic>> targetsWithExtraFields = new ArrayList<>(outboundSignal.getTargets().size());
for (final Target target : outboundSignal.getTargets()) {
final Optional<FilteredTopic> matchingExtraFields = target.getTopics().stream().filter(filteredTopic -> filteredTopic.getExtraFields().isPresent() && streamingType == StreamingType.fromTopic(filteredTopic.getTopic().getPubSubTopic())).findAny();
if (matchingExtraFields.isPresent()) {
targetsWithExtraFields.add(Pair.create(target, matchingExtraFields.get()));
} else {
targetsWithoutExtraFields.add(target);
}
}
return Pair.create(targetsWithoutExtraFields, targetsWithExtraFields);
} else {
// The outbound signal has no streaming type: Do not attach extra fields.
return Pair.create(outboundSignal.getTargets(), Collections.emptyList());
}
}
use of org.eclipse.ditto.internal.utils.pubsub.StreamingType in project ditto by eclipse.
the class ProtocolMessageExtractor method getStartStreaming.
private StartStreaming getStartStreaming(final ProtocolMessageType protocolMessageType, final String protocolMsg) {
final StreamingType streamingType = protocolMessageType.getStreamingTypeOrThrow();
final Map<String, String> params = determineParams(protocolMsg);
return StartStreaming.getBuilder(streamingType, connectionCorrelationId, connectionAuthContext).withNamespaces(getNamespaces(params.get(PARAM_NAMESPACES))).withFilter(params.get(PARAM_FILTER)).withExtraFields(getExtraFields(params.get(PARAM_EXTRA_FIELDS))).withCorrelationId(params.get(DittoHeaderDefinition.CORRELATION_ID.getKey())).build();
}
use of org.eclipse.ditto.internal.utils.pubsub.StreamingType in project ditto by eclipse.
the class WebSocketRoute method streamingAckToString.
private static String streamingAckToString(final StreamingAck streamingAck) {
final StreamingType streamingType = streamingAck.getStreamingType();
final boolean subscribed = streamingAck.isSubscribed();
final String protocolMessage;
switch(streamingType) {
case EVENTS:
protocolMessage = subscribed ? ProtocolMessageType.START_SEND_EVENTS.toString() : ProtocolMessageType.STOP_SEND_EVENTS.toString();
break;
case MESSAGES:
protocolMessage = subscribed ? ProtocolMessageType.START_SEND_MESSAGES.toString() : ProtocolMessageType.STOP_SEND_MESSAGES.toString();
break;
case LIVE_COMMANDS:
protocolMessage = subscribed ? ProtocolMessageType.START_SEND_LIVE_COMMANDS.toString() : ProtocolMessageType.STOP_SEND_LIVE_COMMANDS.toString();
break;
case LIVE_EVENTS:
protocolMessage = subscribed ? ProtocolMessageType.START_SEND_LIVE_EVENTS.toString() : ProtocolMessageType.STOP_SEND_LIVE_EVENTS.toString();
break;
case POLICY_ANNOUNCEMENTS:
protocolMessage = subscribed ? ProtocolMessageType.START_SEND_POLICY_ANNOUNCEMENTS.toString() : ProtocolMessageType.STOP_SEND_POLICY_ANNOUNCEMENTS.toString();
break;
default:
throw new IllegalArgumentException("Unknown streamingType: " + streamingType);
}
return protocolMessage + PROTOCOL_CMD_ACK_SUFFIX;
}
use of org.eclipse.ditto.internal.utils.pubsub.StreamingType in project ditto by eclipse.
the class StreamingSessionActor method createPubSubBehavior.
private Receive createPubSubBehavior() {
return ReceiveBuilder.create().match(StartStreaming.class, startStreaming -> {
authorizationContext = startStreaming.getAuthorizationContext();
Criteria criteria;
try {
criteria = startStreaming.getFilter().map(f -> parseCriteria(f, DittoHeaders.newBuilder().correlationId(startStreaming.getCorrelationId().orElse(startStreaming.getConnectionCorrelationId())).build())).orElse(null);
} catch (final DittoRuntimeException e) {
logger.info("Got 'DittoRuntimeException' <{}> session during 'StartStreaming' processing:" + " {}: <{}>", type, e.getClass().getSimpleName(), e.getMessage());
eventAndResponsePublisher.offer(SessionedJsonifiable.error(e));
return;
}
final var session = StreamingSession.of(startStreaming.getNamespaces(), criteria, startStreaming.getExtraFields().orElse(null), getSelf(), logger);
streamingSessions.put(startStreaming.getStreamingType(), session);
logger.debug("Got 'StartStreaming' message in <{}> session, subscribing for <{}> in Cluster ...", type, startStreaming.getStreamingType().name());
outstandingSubscriptionAcks.add(startStreaming.getStreamingType());
// In Cluster: Subscribe
final var subscribeConfirmation = new ConfirmSubscription(startStreaming.getStreamingType());
final Collection<StreamingType> currentStreamingTypes = streamingSessions.keySet();
dittoProtocolSub.subscribe(currentStreamingTypes, authorizationContext.getAuthorizationSubjectIds(), getSelf()).whenComplete((ack, throwable) -> {
if (null == throwable) {
logger.debug("subscription to Ditto pubsub succeeded");
getSelf().tell(subscribeConfirmation, getSelf());
} else {
logger.error(throwable, "subscription to Ditto pubsub failed: {}", throwable.getMessage());
final var dittoRuntimeException = DittoRuntimeException.asDittoRuntimeException(throwable, cause -> GatewayInternalErrorException.newBuilder().dittoHeaders(DittoHeaders.newBuilder().correlationId(startStreaming.getConnectionCorrelationId()).build()).cause(cause).build());
eventAndResponsePublisher.offer(SessionedJsonifiable.error(dittoRuntimeException));
terminateWebsocketStream();
}
});
}).match(StopStreaming.class, stopStreaming -> {
logger.debug("Got 'StopStreaming' message in <{}> session, unsubscribing from <{}> in Cluster ...", type, stopStreaming.getStreamingType().name());
streamingSessions.remove(stopStreaming.getStreamingType());
// In Cluster: Unsubscribe
final var unsubscribeConfirmation = new ConfirmUnsubscription(stopStreaming.getStreamingType());
final Collection<StreamingType> currentStreamingTypes = streamingSessions.keySet();
switch(stopStreaming.getStreamingType()) {
case EVENTS:
dittoProtocolSub.removeTwinSubscriber(getSelf(), authorizationContext.getAuthorizationSubjectIds()).thenAccept(ack -> getSelf().tell(unsubscribeConfirmation, getSelf()));
break;
case POLICY_ANNOUNCEMENTS:
dittoProtocolSub.removePolicyAnnouncementSubscriber(getSelf(), authorizationContext.getAuthorizationSubjectIds()).thenAccept(ack -> getSelf().tell(unsubscribeConfirmation, getSelf()));
break;
case LIVE_COMMANDS:
case LIVE_EVENTS:
case MESSAGES:
default:
dittoProtocolSub.updateLiveSubscriptions(currentStreamingTypes, authorizationContext.getAuthorizationSubjectIds(), getSelf()).thenAccept(ack -> getSelf().tell(unsubscribeConfirmation, getSelf()));
}
}).match(ConfirmSubscription.class, msg -> confirmSubscription(msg.getStreamingType())).match(ConfirmUnsubscription.class, msg -> confirmUnsubscription(msg.getStreamingType())).build();
}
Aggregations