Implement review remarks
This commit is contained in:
parent
f28cfaaa66
commit
c55e5dbed2
@ -2,9 +2,8 @@ package com.deviceinsight.kafka.health;
|
|||||||
|
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
|
|
||||||
import com.deviceinsight.kafka.health.cache.CacheService;
|
import com.github.benmanes.caffeine.cache.Cache;
|
||||||
import com.deviceinsight.kafka.health.cache.CaffeineCacheServiceImpl;
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import org.apache.kafka.clients.consumer.Consumer;
|
import org.apache.kafka.clients.consumer.Consumer;
|
||||||
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||||
@ -35,6 +34,7 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
@ -44,8 +44,7 @@ import javax.annotation.PreDestroy;
|
|||||||
|
|
||||||
public class KafkaConsumingHealthIndicator extends AbstractHealthIndicator {
|
public class KafkaConsumingHealthIndicator extends AbstractHealthIndicator {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(
|
private static final Logger logger = LoggerFactory.getLogger(KafkaConsumingHealthIndicator.class);
|
||||||
com.deviceinsight.kafka.health.KafkaConsumingHealthIndicator.class);
|
|
||||||
private static final String CONSUMER_GROUP_PREFIX = "health-check-";
|
private static final String CONSUMER_GROUP_PREFIX = "health-check-";
|
||||||
|
|
||||||
private final Consumer<String, String> consumer;
|
private final Consumer<String, String> consumer;
|
||||||
@ -59,7 +58,7 @@ public class KafkaConsumingHealthIndicator extends AbstractHealthIndicator {
|
|||||||
|
|
||||||
private final ExecutorService executor;
|
private final ExecutorService executor;
|
||||||
private final AtomicBoolean running;
|
private final AtomicBoolean running;
|
||||||
private final CacheService<String> cacheService;
|
private final Cache<String, String> cache;
|
||||||
|
|
||||||
private KafkaCommunicationResult kafkaCommunicationResult;
|
private KafkaCommunicationResult kafkaCommunicationResult;
|
||||||
|
|
||||||
@ -83,9 +82,13 @@ public class KafkaConsumingHealthIndicator extends AbstractHealthIndicator {
|
|||||||
|
|
||||||
this.executor = Executors.newFixedThreadPool(2);
|
this.executor = Executors.newFixedThreadPool(2);
|
||||||
this.running = new AtomicBoolean(true);
|
this.running = new AtomicBoolean(true);
|
||||||
this.cacheService = new CaffeineCacheServiceImpl(calculateCacheExpiration(sendReceiveTimeoutMs));
|
this.cache = Caffeine.newBuilder()
|
||||||
|
.expireAfterWrite(calculateCacheExpiration(sendReceiveTimeoutMs), TimeUnit.MILLISECONDS)
|
||||||
|
.recordStats()
|
||||||
|
.build();
|
||||||
|
|
||||||
this.kafkaCommunicationResult = KafkaCommunicationResult.failure(topic, new RejectedExecutionException("Kafka Health Check is starting."));
|
this.kafkaCommunicationResult = KafkaCommunicationResult.failure(topic,
|
||||||
|
new RejectedExecutionException("Kafka Health Check is starting."));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
@ -102,7 +105,7 @@ public class KafkaConsumingHealthIndicator extends AbstractHealthIndicator {
|
|||||||
while (running.get()) {
|
while (running.get()) {
|
||||||
if (messageNotReceived()) {
|
if (messageNotReceived()) {
|
||||||
this.kafkaCommunicationResult = KafkaCommunicationResult.failure(topic,
|
this.kafkaCommunicationResult = KafkaCommunicationResult.failure(topic,
|
||||||
new RejectedExecutionException("Ignore health check, already running..."));
|
new RejectedExecutionException("No message received."));
|
||||||
} else {
|
} else {
|
||||||
this.kafkaCommunicationResult = KafkaCommunicationResult.success(topic);
|
this.kafkaCommunicationResult = KafkaCommunicationResult.success(topic);
|
||||||
}
|
}
|
||||||
@ -161,31 +164,21 @@ public class KafkaConsumingHealthIndicator extends AbstractHealthIndicator {
|
|||||||
|
|
||||||
private void sendMessage() {
|
private void sendMessage() {
|
||||||
|
|
||||||
Future<Void> sendReceiveTask = null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
sendKafkaMessage();
|
||||||
sendReceiveTask = executor.submit(() -> {
|
|
||||||
sendKafkaMessage();
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
sendReceiveTask.get(sendReceiveTimeoutMs, MILLISECONDS);
|
|
||||||
this.kafkaCommunicationResult = KafkaCommunicationResult.success(topic);
|
|
||||||
|
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
logger.warn("Kafka health check execution failed.", e);
|
logger.warn("Kafka health check execution failed.", e);
|
||||||
this.kafkaCommunicationResult = KafkaCommunicationResult.failure(topic, e);
|
this.kafkaCommunicationResult = KafkaCommunicationResult.failure(topic, e);
|
||||||
} catch (TimeoutException | InterruptedException e) {
|
} catch (TimeoutException | InterruptedException e) {
|
||||||
logger.warn("Kafka health check timed out.", e);
|
logger.warn("Kafka health check timed out.", e);
|
||||||
sendReceiveTask.cancel(true);
|
|
||||||
this.kafkaCommunicationResult = KafkaCommunicationResult.failure(topic, e);
|
this.kafkaCommunicationResult = KafkaCommunicationResult.failure(topic, e);
|
||||||
} catch (RejectedExecutionException e) {
|
} catch (RejectedExecutionException e) {
|
||||||
logger.debug("Ignore health check, already running...");
|
logger.debug("Ignore health check, already running...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendKafkaMessage() throws Exception {
|
private void sendKafkaMessage() throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
|
|
||||||
String message = UUID.randomUUID().toString();
|
String message = UUID.randomUUID().toString();
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
@ -193,7 +186,7 @@ public class KafkaConsumingHealthIndicator extends AbstractHealthIndicator {
|
|||||||
logger.debug("Send health check message = {}", message);
|
logger.debug("Send health check message = {}", message);
|
||||||
|
|
||||||
producer.send(new ProducerRecord<>(topic, message, message)).get(sendReceiveTimeoutMs, MILLISECONDS);
|
producer.send(new ProducerRecord<>(topic, message, message)).get(sendReceiveTimeoutMs, MILLISECONDS);
|
||||||
cacheService.write(message);
|
cache.put(message, message);
|
||||||
|
|
||||||
logger.debug("Kafka health check succeeded. took= {} msec", System.currentTimeMillis() - startTime);
|
logger.debug("Kafka health check succeeded. took= {} msec", System.currentTimeMillis() - startTime);
|
||||||
}
|
}
|
||||||
@ -201,7 +194,7 @@ public class KafkaConsumingHealthIndicator extends AbstractHealthIndicator {
|
|||||||
private boolean messageNotReceived() {
|
private boolean messageNotReceived() {
|
||||||
|
|
||||||
return StreamSupport.stream(consumer.poll(Duration.ofMillis(pollTimeoutMs)).spliterator(), false)
|
return StreamSupport.stream(consumer.poll(Duration.ofMillis(pollTimeoutMs)).spliterator(), false)
|
||||||
.noneMatch(msg -> cacheService.get(msg.key()) == null);
|
.noneMatch(msg -> cache.getIfPresent(msg.key()) == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
package com.deviceinsight.kafka.health.cache;
|
|
||||||
|
|
||||||
public interface CacheService<T> {
|
|
||||||
|
|
||||||
void write(T entry);
|
|
||||||
|
|
||||||
T get(T entry);
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package com.deviceinsight.kafka.health.cache;
|
|
||||||
|
|
||||||
import com.github.benmanes.caffeine.cache.Cache;
|
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class CaffeineCacheServiceImpl implements CacheService<String> {
|
|
||||||
|
|
||||||
private final Cache<String, String> cache;
|
|
||||||
|
|
||||||
public CaffeineCacheServiceImpl(long expireAfterWrite) {
|
|
||||||
this.cache = Caffeine.newBuilder()
|
|
||||||
.expireAfterWrite(expireAfterWrite, TimeUnit.MILLISECONDS)
|
|
||||||
.recordStats()
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(String entry) {
|
|
||||||
this.cache.put(entry, entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String get(String entry) {
|
|
||||||
return this.cache.getIfPresent(entry);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user