private FSM.State<BaseClientState, BaseClientData> connectionTimedOut(final Object event, final BaseClientData data) { data.getSessionSender().ifPresent(sender -> { final DittoRuntimeException error = ConnectionFailedException.newBuilder(connectionId()) .dittoHeaders(data.getSessionHeaders()) .build(); sender.tell(new Status.Failure(error), getSelf()); }); cleanupResourcesForConnection(); cleanupFurtherResourcesOnConnectionTimeout(stateName()); return goTo(UNKNOWN).using(data.resetSession() .setConnectionStatus(ConnectionStatus.FAILED) .setConnectionStatusDetails("Connection timed out at " + Instant.now() + " while " + stateName())); }
private FSM.State<BaseClientState, BaseClientData> connectionTimedOut(final Object event, final BaseClientData data) { data.getSessionSender().ifPresent(sender -> { final DittoRuntimeException error = ConnectionFailedException.newBuilder(connectionId()) .dittoHeaders(data.getSessionHeaders()) .build(); sender.tell(new Status.Failure(error), getSelf()); }); cleanupResourcesForConnection(); cleanupFurtherResourcesOnConnectionTimeout(stateName()); return goTo(UNKNOWN).using(data.resetSession() .setConnectionStatus(ConnectionStatus.FAILED) .setConnectionStatusDetails("Connection timed out at " + Instant.now() + " while " + stateName())); }
/** * Creates the handler for messages in testing state. * Overwrite and extend by additional matchers. * * @return an FSM function builder */ protected FSMStateFunctionBuilder<BaseClientState, BaseClientData> inTestingState() { return matchEvent(Status.Status.class, (e, d) -> Objects.equals(getSender(), getSelf()), (status, data) -> { final Status.Status answerToPublish = getStatusToReport(status); data.getSessionSender().ifPresent(sender -> sender.tell(answerToPublish, getSelf())); return stop(); }) .eventEquals(StateTimeout(), BaseClientData.class, (stats, data) -> { log.info("test timed out."); data.getSessionSender().ifPresent(sender -> { final DittoRuntimeException error = ConnectionFailedException.newBuilder(connectionId()) .description(String.format("Failed to open requested connection within <%d> seconds!", TEST_CONNECTION_TIMEOUT)) .dittoHeaders(data.getSessionHeaders()) .build(); sender.tell(new Status.Failure(error), getSelf()); }); return stop(); }); }
/** * Creates the handler for messages in testing state. * Overwrite and extend by additional matchers. * * @return an FSM function builder */ protected FSMStateFunctionBuilder<BaseClientState, BaseClientData> inTestingState() { return matchEvent(Status.Status.class, (e, d) -> Objects.equals(getSender(), getSelf()), (status, data) -> { final Status.Status answerToPublish = getStatusToReport(status); data.getSessionSender().ifPresent(sender -> sender.tell(answerToPublish, getSelf())); return stop(); }) .eventEquals(StateTimeout(), BaseClientData.class, (stats, data) -> { log.info("test timed out."); data.getSessionSender().ifPresent(sender -> { final DittoRuntimeException error = ConnectionFailedException.newBuilder(connectionId()) .description(String.format("Failed to open requested connection within <%d> seconds!", TEST_CONNECTION_TIMEOUT)) .dittoHeaders(data.getSessionHeaders()) .build(); sender.tell(new Status.Failure(error), getSelf()); }); return stop(); }); }
/** * Start MQTT publisher and subscribers, expect "Status.Success" from each of them, then send "ClientConnected" to * self. * * @param connection connection of the publisher and subscribers. * @param dryRun if set to true, exchange no message between the broker and the Ditto cluster. */ private void connectClient(final Connection connection, final boolean dryRun) { final MqttConnectionFactory factory = connectionFactoryCreator.apply(connection, stateData().getSessionHeaders()); // start publisher startMqttPublisher(factory, dryRun); // start consumers if (isConsuming()) { // start message mapping processor actor early so that consumer streams can be run final Either<DittoRuntimeException, ActorRef> messageMappingProcessor = startMessageMappingProcessor(); if (messageMappingProcessor.isLeft()) { final DittoRuntimeException e = messageMappingProcessor.left().get(); log.warning("failed to start mapping processor due to {}", e); } else { final ActorRef mappingActor = messageMappingProcessor.right().get(); // start new KillSwitch for the next batch of consumers refreshConsumerKillSwitch(KillSwitches.shared("consumerKillSwitch")); connection().getSources().forEach(source -> startMqttConsumers(factory, mappingActor, source, dryRun)); } } else { log.info("Not starting consumption because there is no source."); } }
/** * Start MQTT publisher and subscribers, expect "Status.Success" from each of them, then send "ClientConnected" to * self. * * @param connection connection of the publisher and subscribers. * @param dryRun if set to true, exchange no message between the broker and the Ditto cluster. */ private void connectClient(final Connection connection, final boolean dryRun) { final MqttConnectionFactory factory = connectionFactoryCreator.apply(connection, stateData().getSessionHeaders()); // start publisher startMqttPublisher(factory, dryRun); // start consumers if (isConsuming()) { // start message mapping processor actor early so that consumer streams can be run final Either<DittoRuntimeException, ActorRef> messageMappingProcessor = startMessageMappingProcessor(); if (messageMappingProcessor.isLeft()) { final DittoRuntimeException e = messageMappingProcessor.left().get(); log.warning("failed to start mapping processor due to {}", e); } else { final ActorRef mappingActor = messageMappingProcessor.right().get(); // start new KillSwitch for the next batch of consumers refreshConsumerKillSwitch(KillSwitches.shared("consumerKillSwitch")); connection().getSources().forEach(source -> startMqttConsumers(factory, mappingActor, source, dryRun)); } } else { log.info("Not starting consumption because there is no source."); } }
/** * Add meaningful message to status for reporting. * * @param status status to report. * @return status with meaningful message. */ private Status.Status getStatusToReport(final Status.Status status) { final Status.Status answerToPublish; if (status instanceof Status.Failure) { final Status.Failure failure = (Status.Failure) status; log.info("test failed: <{}>", failure.cause()); if (!(failure.cause() instanceof DittoRuntimeException)) { final DittoRuntimeException error = ConnectionFailedException.newBuilder(connectionId()) .description(describeEventualCause(failure.cause())) .dittoHeaders(stateData().getSessionHeaders()) .build(); answerToPublish = new Status.Failure(error); } else { answerToPublish = status; } } else { answerToPublish = status; } return answerToPublish; }
/** * Add meaningful message to status for reporting. * * @param status status to report. * @return status with meaningful message. */ private Status.Status getStatusToReport(final Status.Status status) { final Status.Status answerToPublish; if (status instanceof Status.Failure) { final Status.Failure failure = (Status.Failure) status; log.info("test failed: <{}>", failure.cause()); if (!(failure.cause() instanceof DittoRuntimeException)) { final DittoRuntimeException error = ConnectionFailedException.newBuilder(connectionId()) .description(describeEventualCause(failure.cause())) .dittoHeaders(stateData().getSessionHeaders()) .build(); answerToPublish = new Status.Failure(error); } else { answerToPublish = status; } } else { answerToPublish = status; } return answerToPublish; }