Java Code Examples for org.apache.kafka.common.utils.MockTime

The following examples show how to use org.apache.kafka.common.utils.MockTime. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
/**
 * Setup the test.
 */
@BeforeClass
public static void setup() {
    final long startTime = 500L;
    MOCK_TIME = new MockTime(0, startTime, TimeUnit.NANOSECONDS.convert(startTime, TimeUnit.MILLISECONDS));
    KafkaCruiseControl mockKafkaCruiseControl = EasyMock.mock(KafkaCruiseControl.class);
    Properties props = KafkaCruiseControlUnitTestUtils.getKafkaCruiseControlProperties();
    KafkaCruiseControlConfig kafkaCruiseControlConfig = new KafkaCruiseControlConfig(props);
    EasyMock.expect(mockKafkaCruiseControl.config()).andReturn(kafkaCruiseControlConfig).anyTimes();
    EasyMock.replay(mockKafkaCruiseControl);
    Map<Integer, Long> failedBrokers = new HashMap<>();
    failedBrokers.put(1, 200L);
    failedBrokers.put(2, 400L);
    Map<String, Object> parameterConfigOverrides = new HashMap<>(4);
    parameterConfigOverrides.put(KAFKA_CRUISE_CONTROL_OBJECT_CONFIG, mockKafkaCruiseControl);
    parameterConfigOverrides.put(ANOMALY_DETECTION_TIME_MS_OBJECT_CONFIG, 200L);
    parameterConfigOverrides.put(FAILED_BROKERS_OBJECT_CONFIG, failedBrokers);
    parameterConfigOverrides.put(BROKER_FAILURES_FIXABLE_CONFIG, true);
    FAILURES = kafkaCruiseControlConfig.getConfiguredInstance(AnomalyDetectorConfig.BROKER_FAILURES_CLASS_CONFIG,
                                                              BrokerFailures.class,
                                                              parameterConfigOverrides);
}
 
Example 2
private TestContext prepareRequests(boolean expectSessionInvalidation, int numRequests) {
  Time time = new MockTime();
  List<HttpServletRequest> requests = new ArrayList<>(numRequests);
  List<HttpSession> sessions = new ArrayList<>();
  for (int i = 0; i < numRequests; i++) {
    HttpServletRequest request = EasyMock.mock(HttpServletRequest.class);
    HttpSession session = EasyMock.mock(HttpSession.class);
    requests.add(request);
    sessions.add(session);
    EasyMock.expect(request.getSession()).andReturn(session).anyTimes();
    EasyMock.expect(request.getSession(false)).andReturn(session).anyTimes();
    EasyMock.expect(request.getMethod()).andReturn(GET_METHOD).anyTimes();
    EasyMock.expect(request.getRequestURI()).andReturn("/test").anyTimes();
    EasyMock.expect(request.getParameterMap()).andReturn(Collections.emptyMap()).anyTimes();
    EasyMock.expect(session.getLastAccessedTime()).andReturn(time.milliseconds()).anyTimes();
    if (expectSessionInvalidation) {
      session.invalidate();
      EasyMock.expectLastCall().once();
    }
  }
  EasyMock.replay(requests.toArray());
  EasyMock.replay(sessions.toArray());
  return new TestContext(requests, time);
}
 
Example 3
Source Project: kareldb   Source File: KarelDbCoordinatorTest.java    License: Apache License 2.0 4 votes vote down vote up
@Before
public void setup() {
    this.time = new MockTime();
    this.metadata = new Metadata(0, Long.MAX_VALUE, new LogContext(), new ClusterResourceListeners());
    this.client = new MockClient(time, new MockClient.MockMetadataUpdater() {
        @Override
        public List<Node> fetchNodes() {
            return cluster.nodes();
        }

        @Override
        public boolean isUpdateNeeded() {
            return false;
        }

        @Override
        public void update(Time time, MockClient.MetadataUpdate update) {
            throw new UnsupportedOperationException();
        }
    });

    LogContext logContext = new LogContext();
    this.consumerClient = new ConsumerNetworkClient(logContext, client, metadata, time, 100, 1000, Integer.MAX_VALUE);
    this.metrics = new Metrics(time);
    this.rebalanceListener = new MockRebalanceListener();

    this.coordinator = new KarelDbCoordinator(
        logContext,
        consumerClient,
        groupId,
        rebalanceTimeoutMs,
        sessionTimeoutMs,
        heartbeatIntervalMs,
        metrics,
        "kdb-" + groupId,
        time,
        retryBackoffMs,
        LEADER_INFO,
        rebalanceListener
    );
}
 
Example 4
private MockTime getMockTime() {
  return new MockTime(0, 100L, TimeUnit.NANOSECONDS.convert(100L, TimeUnit.MILLISECONDS));
}
 
Example 5
@Test
public void testOnBrokerFailure() {
  final long failureTime1 = 200L;
  final long failureTime2 = 400L;
  final long startTime = 500L;
  KafkaCruiseControl mockKafkaCruiseControl = EasyMock.mock(KafkaCruiseControl.class);
  Properties props = KafkaCruiseControlUnitTestUtils.getKafkaCruiseControlProperties();
  KafkaCruiseControlConfig kafkaCruiseControlConfig = new KafkaCruiseControlConfig(props);
  EasyMock.expect(mockKafkaCruiseControl.config()).andReturn(kafkaCruiseControlConfig).atLeastOnce();
  EasyMock.replay(mockKafkaCruiseControl);
  Time mockTime = new MockTime(0, startTime, TimeUnit.NANOSECONDS.convert(startTime, TimeUnit.MILLISECONDS));
  TestingBrokerFailureAutoFixNotifier anomalyNotifier = new TestingBrokerFailureAutoFixNotifier(mockTime);
  anomalyNotifier.configure(Collections.singletonMap(SelfHealingNotifier.SELF_HEALING_BROKER_FAILURE_ENABLED_CONFIG, "true"));

  Map<Integer, Long> failedBrokers = new HashMap<>();
  failedBrokers.put(1, failureTime1);
  failedBrokers.put(2, failureTime2);
  Map<String, Object> parameterConfigOverrides = new HashMap<>(4);
  parameterConfigOverrides.put(KAFKA_CRUISE_CONTROL_OBJECT_CONFIG, mockKafkaCruiseControl);
  parameterConfigOverrides.put(FAILED_BROKERS_OBJECT_CONFIG, failedBrokers);
  parameterConfigOverrides.put(ANOMALY_DETECTION_TIME_MS_OBJECT_CONFIG, failureTime1);
  parameterConfigOverrides.put(BROKER_FAILURES_FIXABLE_CONFIG, true);

  AnomalyNotificationResult result = anomalyNotifier.onBrokerFailure(
      kafkaCruiseControlConfig.getConfiguredInstance(AnomalyDetectorConfig.BROKER_FAILURES_CLASS_CONFIG,
                                                     BrokerFailures.class,
                                                     parameterConfigOverrides));
  assertEquals(AnomalyNotificationResult.Action.CHECK, result.action());
  assertEquals(SelfHealingNotifier.DEFAULT_ALERT_THRESHOLD_MS + failureTime1 - mockTime.milliseconds(),
               result.delay());
  assertFalse(anomalyNotifier._alertCalled.get(KafkaAnomalyType.BROKER_FAILURE));

  // Sleep to 1 ms before alert.
  mockTime.sleep(result.delay() - 1);
  result = anomalyNotifier.onBrokerFailure(
      kafkaCruiseControlConfig.getConfiguredInstance(AnomalyDetectorConfig.BROKER_FAILURES_CLASS_CONFIG,
                                                     BrokerFailures.class,
                                                     parameterConfigOverrides));
  assertEquals(AnomalyNotificationResult.Action.CHECK, result.action());
  assertEquals(1, result.delay());
  assertFalse(anomalyNotifier._alertCalled.get(KafkaAnomalyType.BROKER_FAILURE));

  // Sleep 1 ms
  mockTime.sleep(1);
  anomalyNotifier.resetAlert(KafkaAnomalyType.BROKER_FAILURE);
  result = anomalyNotifier.onBrokerFailure(
      kafkaCruiseControlConfig.getConfiguredInstance(AnomalyDetectorConfig.BROKER_FAILURES_CLASS_CONFIG,
                                                     BrokerFailures.class,
                                                     parameterConfigOverrides));
  assertEquals(AnomalyNotificationResult.Action.CHECK, result.action());
  assertEquals(SelfHealingNotifier.DEFAULT_AUTO_FIX_THRESHOLD_MS + failureTime1 - mockTime.milliseconds(),
               result.delay());
  assertTrue(anomalyNotifier._alertCalled.get(KafkaAnomalyType.BROKER_FAILURE));

  // Sleep to 1 ms before alert.
  mockTime.sleep(result.delay() - 1);
  anomalyNotifier.resetAlert(KafkaAnomalyType.BROKER_FAILURE);
  result = anomalyNotifier.onBrokerFailure(
      kafkaCruiseControlConfig.getConfiguredInstance(AnomalyDetectorConfig.BROKER_FAILURES_CLASS_CONFIG,
                                                     BrokerFailures.class,
                                                     parameterConfigOverrides));
  assertEquals(AnomalyNotificationResult.Action.CHECK, result.action());
  assertEquals(1, result.delay());
  assertFalse(anomalyNotifier._alertCalled.get(KafkaAnomalyType.BROKER_FAILURE));
  assertFalse(anomalyNotifier._autoFixTriggered.get(KafkaAnomalyType.BROKER_FAILURE));

  // Sleep 1 ms
  mockTime.sleep(1);
  anomalyNotifier.resetAlert(KafkaAnomalyType.BROKER_FAILURE);
  result = anomalyNotifier.onBrokerFailure(
      kafkaCruiseControlConfig.getConfiguredInstance(AnomalyDetectorConfig.BROKER_FAILURES_CLASS_CONFIG,
                                                     BrokerFailures.class,
                                                     parameterConfigOverrides));
  assertEquals(AnomalyNotificationResult.Action.FIX, result.action());
  assertEquals(-1L, result.delay());
  assertTrue(anomalyNotifier._alertCalled.get(KafkaAnomalyType.BROKER_FAILURE));
  assertTrue(anomalyNotifier._autoFixTriggered.get(KafkaAnomalyType.BROKER_FAILURE));
  assertFalse(anomalyNotifier._alertCalled.get(KafkaAnomalyType.GOAL_VIOLATION));
  assertFalse(anomalyNotifier._alertCalled.get(KafkaAnomalyType.METRIC_ANOMALY));
  assertFalse(anomalyNotifier._alertCalled.get(KafkaAnomalyType.DISK_FAILURE));
  assertFalse(anomalyNotifier._alertCalled.get(KafkaAnomalyType.TOPIC_ANOMALY));
}
 
Example 6
@Test
public void testSelfHealingDisabled() {
  final long startTime = 500L;
  Time mockTime = new MockTime(startTime);
  KafkaCruiseControl mockKafkaCruiseControl = EasyMock.mock(KafkaCruiseControl.class);
  Properties props = KafkaCruiseControlUnitTestUtils.getKafkaCruiseControlProperties();
  KafkaCruiseControlConfig kafkaCruiseControlConfig = new KafkaCruiseControlConfig(props);
  EasyMock.expect(mockKafkaCruiseControl.config()).andReturn(kafkaCruiseControlConfig).atLeastOnce();
  EasyMock.replay(mockKafkaCruiseControl);
  TestingBrokerFailureAutoFixNotifier anomalyNotifier = new TestingBrokerFailureAutoFixNotifier(mockTime);

  Map<String, String> selfHealingExplicitlyDisabled = new HashMap<>(4);
  selfHealingExplicitlyDisabled.put(SelfHealingNotifier.SELF_HEALING_BROKER_FAILURE_ENABLED_CONFIG, "false");
  selfHealingExplicitlyDisabled.put(SelfHealingNotifier.SELF_HEALING_GOAL_VIOLATION_ENABLED_CONFIG, "false");
  selfHealingExplicitlyDisabled.put(SelfHealingNotifier.SELF_HEALING_METRIC_ANOMALY_ENABLED_CONFIG, "false");
  selfHealingExplicitlyDisabled.put(SelfHealingNotifier.SELF_HEALING_DISK_FAILURE_ENABLED_CONFIG, "false");
  selfHealingExplicitlyDisabled.put(SelfHealingNotifier.SELF_HEALING_TOPIC_ANOMALY_ENABLED_CONFIG, "false");
  // Set to verify the overriding of specific config over general config
  selfHealingExplicitlyDisabled.put(SelfHealingNotifier.SELF_HEALING_ENABLED_CONFIG, "true");
  anomalyNotifier.configure(selfHealingExplicitlyDisabled);

  // (1) Test broker failure anomaly can be detected by notifier.
  final long failureTime1 = 200L;
  final long failureTime2 = 400L;
  Map<Integer, Long> failedBrokers = new HashMap<>();
  failedBrokers.put(1, failureTime1);
  failedBrokers.put(2, failureTime2);
  final long anomalyDetectionTime = 200L;
  final BrokerEntity brokerWithMetricAnomaly = new BrokerEntity("local", 1);

  mockTime.sleep(SelfHealingNotifier.DEFAULT_AUTO_FIX_THRESHOLD_MS + failureTime1);
  anomalyNotifier.resetAlert(KafkaAnomalyType.BROKER_FAILURE);
  Map<String, Object> parameterConfigOverrides = new HashMap<>(9);
  parameterConfigOverrides.put(KAFKA_CRUISE_CONTROL_OBJECT_CONFIG, mockKafkaCruiseControl);
  parameterConfigOverrides.put(FAILED_BROKERS_OBJECT_CONFIG, failedBrokers);
  parameterConfigOverrides.put(BROKER_FAILURES_FIXABLE_CONFIG, true);
  parameterConfigOverrides.put(ANOMALY_DETECTION_TIME_MS_OBJECT_CONFIG, anomalyDetectionTime);
  parameterConfigOverrides.put(METRIC_ANOMALY_FIXABLE_OBJECT_CONFIG, false);
  parameterConfigOverrides.put(METRIC_ANOMALY_BROKER_ENTITIES_OBJECT_CONFIG,
                               Collections.singletonMap(brokerWithMetricAnomaly, anomalyDetectionTime));
  parameterConfigOverrides.put(FAILED_DISKS_OBJECT_CONFIG,
                               Collections.singletonMap(1, Collections.singletonMap(BAD_LOGDIR, failureTime1)));
  parameterConfigOverrides.put(SELF_HEALING_TARGET_TOPIC_REPLICATION_FACTOR_CONFIG, SELF_HEALING_TARGET_REPLICATION_FACTOR);
  parameterConfigOverrides.put(BAD_TOPICS_BY_REPLICATION_FACTOR_CONFIG,
                               Collections.singletonMap(SELF_HEALING_TARGET_REPLICATION_FACTOR,
                                                        Collections.singleton(TOPIC_REPLICATION_FACTOR_ANOMALY_ENTRY)));
  AnomalyNotificationResult result = anomalyNotifier.onBrokerFailure(
      kafkaCruiseControlConfig.getConfiguredInstance(AnomalyDetectorConfig.BROKER_FAILURES_CLASS_CONFIG,
                                                     BrokerFailures.class,
                                                     parameterConfigOverrides));
  assertEquals(AnomalyNotificationResult.Action.IGNORE, result.action());
  assertTrue(anomalyNotifier._alertCalled.get(KafkaAnomalyType.BROKER_FAILURE));
  assertFalse(anomalyNotifier._autoFixTriggered.get(KafkaAnomalyType.BROKER_FAILURE));

  // (2) Test goal violation anomaly can be detected by notifier.
  anomalyNotifier.resetAlert(KafkaAnomalyType.GOAL_VIOLATION);
  result = anomalyNotifier.onGoalViolation(
      kafkaCruiseControlConfig.getConfiguredInstance(AnomalyDetectorConfig.GOAL_VIOLATIONS_CLASS_CONFIG,
                                                     GoalViolations.class,
                                                     parameterConfigOverrides));
  assertEquals(AnomalyNotificationResult.Action.IGNORE, result.action());
  assertTrue(anomalyNotifier._alertCalled.get(KafkaAnomalyType.GOAL_VIOLATION));
  assertFalse(anomalyNotifier._autoFixTriggered.get(KafkaAnomalyType.GOAL_VIOLATION));

  // (3) Test metric anomaly can be detected by notifier.
  anomalyNotifier.resetAlert(KafkaAnomalyType.METRIC_ANOMALY);
  result = anomalyNotifier.onMetricAnomaly(kafkaCruiseControlConfig.getConfiguredInstance(AnomalyDetectorConfig.METRIC_ANOMALY_CLASS_CONFIG,
                                                                                          KafkaMetricAnomaly.class,
                                                                                          parameterConfigOverrides));
  assertEquals(AnomalyNotificationResult.Action.IGNORE, result.action());
  assertTrue(anomalyNotifier._alertCalled.get(KafkaAnomalyType.METRIC_ANOMALY));
  assertFalse(anomalyNotifier._autoFixTriggered.get(KafkaAnomalyType.METRIC_ANOMALY));

  // (4) Test disk failure anomaly can be detected by notifier.
  anomalyNotifier.resetAlert(KafkaAnomalyType.DISK_FAILURE);
  result = anomalyNotifier.onDiskFailure(kafkaCruiseControlConfig.getConfiguredInstance(AnomalyDetectorConfig.DISK_FAILURES_CLASS_CONFIG,
                                                                                        DiskFailures.class,
                                                                                        parameterConfigOverrides));
  assertEquals(AnomalyNotificationResult.Action.IGNORE, result.action());
  assertTrue(anomalyNotifier._alertCalled.get(KafkaAnomalyType.DISK_FAILURE));
  assertFalse(anomalyNotifier._autoFixTriggered.get(KafkaAnomalyType.DISK_FAILURE));

  // (5) Test topic anomaly can be detected by notifier.
  anomalyNotifier.resetAlert(KafkaAnomalyType.TOPIC_ANOMALY);
  TopicReplicationFactorAnomaly topicReplicationFactorAnomaly = new TopicReplicationFactorAnomaly();
  topicReplicationFactorAnomaly.configure(parameterConfigOverrides);
  result = anomalyNotifier.onTopicAnomaly(topicReplicationFactorAnomaly);
  assertEquals(AnomalyNotificationResult.Action.IGNORE, result.action());
  assertTrue(anomalyNotifier._alertCalled.get(KafkaAnomalyType.TOPIC_ANOMALY));
  assertFalse(anomalyNotifier._autoFixTriggered.get(KafkaAnomalyType.TOPIC_ANOMALY));
}
 
Example 7
@Test
public void testTimeoutAndForceExecutionStop() throws InterruptedException, OngoingExecutionException {
  createTopics(0);
  // The proposal tries to move the leader. We fake the replica list to be unchanged so there is no replica
  // movement, but only leader movement.
  ExecutionProposal proposal =
      new ExecutionProposal(TP1, 0, new ReplicaPlacementInfo(1),
                            Arrays.asList(new ReplicaPlacementInfo(0), new ReplicaPlacementInfo(1)),
                            Arrays.asList(new ReplicaPlacementInfo(0), new ReplicaPlacementInfo(1)));

  KafkaCruiseControlConfig configs = new KafkaCruiseControlConfig(getExecutorProperties());
  Time time = new MockTime();
  MetadataClient mockMetadataClient = EasyMock.mock(MetadataClient.class);
  // Fake the metadata to never change so the leader movement will timeout.
  Node node0 = new Node(0, "host0", 100);
  Node node1 = new Node(1, "host1", 100);
  Node[] replicas = new Node[2];
  replicas[0] = node0;
  replicas[1] = node1;
  PartitionInfo partitionInfo = new PartitionInfo(TP1.topic(), TP1.partition(), node1, replicas, replicas);
  Cluster cluster = new Cluster("id", Arrays.asList(node0, node1), Collections.singleton(partitionInfo),
                                Collections.emptySet(), Collections.emptySet());
  MetadataClient.ClusterAndGeneration clusterAndGeneration = new MetadataClient.ClusterAndGeneration(cluster, 0);
  EasyMock.expect(mockMetadataClient.refreshMetadata()).andReturn(clusterAndGeneration).anyTimes();
  EasyMock.expect(mockMetadataClient.cluster()).andReturn(clusterAndGeneration.cluster()).anyTimes();
  LoadMonitor mockLoadMonitor = getMockLoadMonitor();
  AnomalyDetector mockAnomalyDetector = getMockAnomalyDetector(RANDOM_UUID);
  UserTaskManager.UserTaskInfo mockUserTaskInfo = getMockUserTaskInfo();
  // This tests runs two consecutive executions. First one completes w/o error, but the second one with error.
  UserTaskManager mockUserTaskManager = getMockUserTaskManager(RANDOM_UUID, mockUserTaskInfo, Arrays.asList(false, true));
  EasyMock.replay(mockMetadataClient, mockLoadMonitor, mockAnomalyDetector, mockUserTaskInfo, mockUserTaskManager);

  Collection<ExecutionProposal> proposalsToExecute = Collections.singletonList(proposal);
  Executor executor = new Executor(configs, time, new MetricRegistry(), mockMetadataClient, DEMOTION_HISTORY_RETENTION_TIME_MS,
                                   REMOVAL_HISTORY_RETENTION_TIME_MS, null, mockUserTaskManager,
                                   mockAnomalyDetector);
  executor.setExecutionMode(false);
  executor.executeProposals(proposalsToExecute,
                            Collections.emptySet(),
                            null,
                            mockLoadMonitor,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            true,
                            RANDOM_UUID,
                            ExecutorTest.class::getSimpleName);
  waitUntilTrue(() -> (executor.state().state() == ExecutorState.State.LEADER_MOVEMENT_TASK_IN_PROGRESS && !executor.inExecutionTasks().isEmpty()),
                "Leader movement task did not start within the time limit",
                EXECUTION_DEADLINE_MS, EXECUTION_SHORT_CHECK_MS);

  // Sleep over ExecutorConfig#DEFAULT_LEADER_MOVEMENT_TIMEOUT_MS with some margin for inter-thread synchronization.
  time.sleep(ExecutorConfig.DEFAULT_LEADER_MOVEMENT_TIMEOUT_MS + 1L);
  // The execution should finish.
  waitUntilTrue(() -> (!executor.hasOngoingExecution() && executor.state().state() == ExecutorState.State.NO_TASK_IN_PROGRESS),
                "Proposal execution did not finish within the time limit",
                EXECUTION_DEADLINE_MS, EXECUTION_REGULAR_CHECK_MS);

  // The proposal tries to move replicas.
  proposal = new ExecutionProposal(TP1, 0, new ReplicaPlacementInfo(1),
                                   Arrays.asList(new ReplicaPlacementInfo(0), new ReplicaPlacementInfo(1)),
                                   Arrays.asList(new ReplicaPlacementInfo(1), new ReplicaPlacementInfo(0)));
  proposalsToExecute = Collections.singletonList(proposal);
  executor.executeProposals(proposalsToExecute,
                            Collections.emptySet(),
                            null,
                            mockLoadMonitor,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            true,
                            RANDOM_UUID,
                            ExecutorTest.class::getSimpleName);
  waitUntilTrue(() -> (executor.state().state() == ExecutorState.State.INTER_BROKER_REPLICA_MOVEMENT_TASK_IN_PROGRESS),
                "Inter-broker replica movement task did not start within the time limit",
                EXECUTION_DEADLINE_MS, EXECUTION_SHORT_CHECK_MS);
  // Force execution to stop.
  executor.userTriggeredStopExecution(true);
  // The execution should finish.
  waitUntilTrue(() -> (!executor.hasOngoingExecution() && executor.state().state() == ExecutorState.State.NO_TASK_IN_PROGRESS),
                "Proposal execution did not finish within the time limit",
                EXECUTION_DEADLINE_MS, EXECUTION_REGULAR_CHECK_MS);
  EasyMock.verify(mockMetadataClient, mockLoadMonitor, mockAnomalyDetector, mockUserTaskInfo, mockUserTaskManager);
}
 
Example 8
@Test
public void shouldPredictValues() throws Exception {

	// ########################################################
	// Step 1: Load Keras Model using DeepLearning4J API
	// ########################################################
	String simpleMlp = new ClassPathResource("generatedModels/Keras/simple_mlp.h5").getFile().getPath();
	System.out.println(simpleMlp.toString());

	MultiLayerNetwork model = KerasModelImport.importKerasSequentialModelAndWeights(simpleMlp);

	// Create test data which is sent from Kafka Producer into Input Topic
	List<String> inputValues = Arrays.asList("256,100");

	// ####################################################################
	// Step 2: Configure and start the Kafka Streams processor topology.
	// ####################################################################

	Properties streamsConfiguration = new Properties();
	streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG,
			"kafka-streams-tensorflow-keras-integration-test");
	streamsConfiguration.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers());

	// Configure Kafka Streams Application
	// Specify default (de)serializers for record keys and for record
	// values.
	streamsConfiguration.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
	streamsConfiguration.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());

	// In the subsequent lines we define the processing topology of the
	// Streams application.
	final StreamsBuilder builder = new StreamsBuilder();

	// Construct a `KStream` from the input topic, where
	// message values represent lines of text (for the sake of this example, we
	// ignore whatever may be stored in the message keys).
	final KStream<String, String> inputEvents = builder.stream(inputTopic);

	// ###############################################################
	// THIS IS WHERE WE DO REAL TIME MODEL INFERENCE FOR EACH EVENT
	// ###############################################################
	inputEvents.foreach((key, value) -> {

		// Transform input values (list of Strings) to expected DL4J parameters (two
		// Integer values):
		String[] valuesAsArray = value.split(",");
		INDArray input = Nd4j.create(Integer.parseInt(valuesAsArray[0]), Integer.parseInt(valuesAsArray[1]));

		// Apply the analytic model:
		output = model.output(input);
		prediction = output.toString();

	});

	// Transform message: Add prediction result
	KStream<String, Object> transformedMessage = inputEvents.mapValues(value -> "Prediction => " + prediction);

	// Send prediction result to Output Topic
	transformedMessage.to(outputTopic);

	// Start Kafka Streams Application to process new incoming messages from
	// Input Topic
	final KafkaStreams streams = new TestKafkaStreams(builder.build(), streamsConfiguration);
	streams.cleanUp();
	streams.start();
	System.out.println("Prediction Microservice is running...");
	System.out.println("Input to Kafka Topic " + inputTopic + "; Output to Kafka Topic " + outputTopic);

	// ########################################################
	// Step 3: Produce some input data to the input topic.
	// ########################################################

	Properties producerConfig = new Properties();
	producerConfig.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers());
	producerConfig.put(ProducerConfig.ACKS_CONFIG, "all");
	producerConfig.put(ProducerConfig.RETRIES_CONFIG, 0);
	producerConfig.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
	producerConfig.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
	IntegrationTestUtils.produceValuesSynchronously(inputTopic, inputValues, producerConfig, new MockTime());

	// ########################################################
	// Step 4: Verify the application's output data.
	// ########################################################

	Properties consumerConfig = new Properties();
	consumerConfig.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers());
	consumerConfig.put(ConsumerConfig.GROUP_ID_CONFIG,
			"kafka-streams-tensorflow-keras-integration-test-standard-consumer");
	consumerConfig.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
	consumerConfig.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
	consumerConfig.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
	List<KeyValue<String, String>> response = IntegrationTestUtils
			.waitUntilMinKeyValueRecordsReceived(consumerConfig, outputTopic, 1);
	streams.close();

	System.out.println("VALUE: " + response.get(0).value);

	assertThat(response).isNotNull();
	assertThat(response.get(0).value).doesNotMatch("Value => unknown");
	assertThat(response.get(0).value).contains("0.1000,    0.1000,    0.1000");
}