@Override public CommandSubscriber create() { return new CommandSubscriber(delegateActor, backpressureQueueSize, eventStream); } });
private CommandSubscriber(final ActorRef delegateActor, final int backpressureQueueSize, final EventStream eventStream) { this.delegateActor = delegateActor; this.backpressureQueueSize = backpressureQueueSize; eventStream.subscribe(getSelf(), ResponsePublished.class); }
if (isResponseExpected(signal)) { outstandingCommandCorrelationIds.add(correlationId); if (outstandingCommandCorrelationIds.size() > backpressureQueueSize) { delegateActor.tell(signal, getSelf()); } else { logger.warning("Got a Signal <{}> without correlationId, NOT accepting/forwarding it: {}", .match(ResponsePublished.class, responded -> outstandingCommandCorrelationIds.remove(responded.getCorrelationId())) .match(DittoRuntimeException.class, cre -> handleDittoRuntimeException(delegateActor, cre)) .match(RuntimeException.class, jre -> handleDittoRuntimeException(delegateActor, new DittoJsonException(jre))) .match(ActorSubscriberMessage.OnNext.class, onComplete -> logger.warning("Got unknown element in 'OnNext'")) .matchEquals(ActorSubscriberMessage.onCompleteInstance(), onComplete -> { logger.info("Stream completed, stopping myself.."); getContext().stop(getSelf()); }) .match(ActorSubscriberMessage.OnError.class, onError -> { final Throwable cause = onError.cause(); if (cause instanceof DittoRuntimeException) { handleDittoRuntimeException(delegateActor, (DittoRuntimeException) cause); } else if (cause instanceof RuntimeException) { handleDittoRuntimeException(delegateActor, new DittoJsonException((RuntimeException) cause)); } else { logger.warning("Got 'OnError': {} {}", cause.getClass().getName(), cause.getMessage());
private void handleDittoRuntimeException(final ActorRef delegateActor, final DittoRuntimeException cre) { LogUtil.enhanceLogWithCorrelationId(logger, cre.getDittoHeaders().getCorrelationId()); logger.info("Got 'DittoRuntimeException': {} {}", cre.getClass().getName(), cre.getMessage()); cre.getDittoHeaders().getCorrelationId().ifPresent(outstandingCommandCorrelationIds::remove); if (cre.getDittoHeaders().isResponseRequired()) { delegateActor.forward(cre, getContext()); } else { logger.debug("Requester did not require response (via DittoHeader '{}') - not sending one", DittoHeaderDefinition.RESPONSE_REQUIRED); } }
private Sink<Message, NotUsed> createSink(final Integer version, final String connectionCorrelationId, final AuthorizationContext connectionAuthContext, final DittoHeaders additionalHeaders, final ProtocolAdapter adapter) { return Flow.<Message>create() .filter(Message::isText) .map(Message::asTextMessage) .map(textMsg -> { if (textMsg.isStrict()) { return Source.single(textMsg.getStrictText()); } else { return textMsg.getStreamedText(); } }) .flatMapConcat(textMsg -> textMsg.<String>fold("", (str1, str2) -> str1 + str2)) .via(Flow.fromFunction(result -> { LogUtil.logWithCorrelationId(LOGGER, connectionCorrelationId, logger -> logger.debug("Received incoming WebSocket message: {}", result)); return result; })) .withAttributes(Attributes.createLogLevels(Logging.DebugLevel(), Logging.DebugLevel(), Logging.WarningLevel())) .filter(strictText -> processProtocolMessage(connectionAuthContext, connectionCorrelationId, strictText)) .map(buildSignal(version, connectionCorrelationId, connectionAuthContext, additionalHeaders, adapter)) .to(Sink.actorSubscriber( CommandSubscriber.props(streamingActor, subscriberBackpressureQueueSize, eventStream))); }
/** * Creates Akka configuration object Props for this CommandSubscriber. * * @param delegateActor the ActorRef of the Actor to which to forward {@link Command}s. * @param backpressureQueueSize the max queue size of how many inflight commands a single producer can have. * @param eventStream used to subscribe to {@link ResponsePublished} events * @return the Akka configuration Props object. */ public static Props props(final ActorRef delegateActor, final int backpressureQueueSize, final EventStream eventStream) { return Props.create(CommandSubscriber.class, new Creator<CommandSubscriber>() { private static final long serialVersionUID = 1L; @Override public CommandSubscriber create() { return new CommandSubscriber(delegateActor, backpressureQueueSize, eventStream); } }); }