forked from quarkus-qe/quarkus-test-suite
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add test for DLQ metric counting (quarkus-qe#1960)
* Add test for DLQ metric counting
- Loading branch information
Showing
5 changed files
with
125 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
...-kafka/src/main/java/io/quarkus/ts/micrometer/prometheus/kafka/UndeliverableConsumer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package io.quarkus.ts.micrometer.prometheus.kafka; | ||
|
||
import java.util.concurrent.CompletionStage; | ||
|
||
import org.eclipse.microprofile.reactive.messaging.Acknowledgment; | ||
import org.eclipse.microprofile.reactive.messaging.Incoming; | ||
import org.eclipse.microprofile.reactive.messaging.Message; | ||
|
||
public class UndeliverableConsumer { | ||
@Incoming(Channels.CHANNEL_UNDELIVERABLE_TARGET) | ||
@Acknowledgment(Acknowledgment.Strategy.MANUAL) | ||
public CompletionStage<Void> consume(Message<String> message) { | ||
return message.nack(new IllegalArgumentException("Can't invoke this")); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
...-kafka/src/main/java/io/quarkus/ts/micrometer/prometheus/kafka/UndeliverableProducer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package io.quarkus.ts.micrometer.prometheus.kafka; | ||
|
||
import jakarta.ws.rs.GET; | ||
import jakarta.ws.rs.Path; | ||
|
||
import org.eclipse.microprofile.reactive.messaging.Channel; | ||
import org.eclipse.microprofile.reactive.messaging.Emitter; | ||
|
||
@Path("/undeliverable") | ||
public class UndeliverableProducer { | ||
@Channel(Channels.CHANNEL_UNDELIVERABLE_SOURCE) | ||
Emitter<String> dataEmitter; | ||
|
||
@GET | ||
public void sendData() { | ||
dataEmitter.send("random data"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
...theus-kafka/src/test/java/io/quarkus/ts/micrometer/prometheus/kafka/DLQMetricCountIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package io.quarkus.ts.micrometer.prometheus.kafka; | ||
|
||
import static org.awaitility.Awaitility.await; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
import static org.junit.jupiter.api.Assertions.fail; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
import java.util.function.Predicate; | ||
|
||
import org.apache.http.HttpStatus; | ||
import org.junit.jupiter.api.Tag; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import io.quarkus.test.bootstrap.KafkaService; | ||
import io.quarkus.test.bootstrap.RestService; | ||
import io.quarkus.test.scenarios.QuarkusScenario; | ||
import io.quarkus.test.services.KafkaContainer; | ||
import io.quarkus.test.services.QuarkusApplication; | ||
|
||
/** | ||
* Test that messages send to a dead-letter-queue are counted in micrometer metrics. | ||
* See links for more details: | ||
* - https://issues.redhat.com/browse/QUARKUS-4120 | ||
* - https://github.com/smallrye/smallrye-reactive-messaging/issues/2473 | ||
*/ | ||
@QuarkusScenario | ||
@Tag("QUARKUS-4120") | ||
public class DLQMetricCountIT { | ||
private static final String DEAD_LETTER_TOPIC_NAME = "dead-letter-topic-undeliverable-target"; | ||
private static final String MESSAGES_SEND_METRIC = "kafka_producer_topic_record_send_total"; | ||
private static final String UNDELIVERABLE_ENDPOINT = "undeliverable"; | ||
private static final int NUMBER_OF_MESSAGES_SEND = 3; | ||
|
||
@KafkaContainer | ||
static final KafkaService kafka = new KafkaService(); | ||
|
||
@QuarkusApplication | ||
static RestService app = new RestService().withProperty("kafka.bootstrap.servers", kafka::getBootstrapUrl); | ||
|
||
@Test | ||
public void testDeadLetterMessagesAreCounted() { | ||
// wait for kafka to be fully loaded | ||
// if we send requests (messages) too soon, they will fail to propagate into topic | ||
kafka.logs().assertContains("Assignment received from leader kafka-consumer-undeliverable-target"); | ||
|
||
// send requests | ||
for (int i = 0; i < NUMBER_OF_MESSAGES_SEND; i++) { | ||
app.given().get(UNDELIVERABLE_ENDPOINT).then().statusCode(HttpStatus.SC_NO_CONTENT); | ||
} | ||
|
||
thenMetricIsExposedInServiceEndpoint(MESSAGES_SEND_METRIC, DEAD_LETTER_TOPIC_NAME, | ||
greaterOrEqual(NUMBER_OF_MESSAGES_SEND)); | ||
} | ||
|
||
private void thenMetricIsExposedInServiceEndpoint(String name, String key, Predicate<Double> valueMatcher) { | ||
await().ignoreExceptions().atMost(60, TimeUnit.SECONDS).untilAsserted(() -> { | ||
String response = app.given().get("/q/metrics").then() | ||
.statusCode(HttpStatus.SC_OK) | ||
.extract().asString(); | ||
|
||
for (String line : response.split("[\r\n]+")) { | ||
if (line.startsWith(name) && line.contains(key)) { | ||
Double value = extractValueFromMetric(line); | ||
assertTrue(valueMatcher.test(value), "Metric value is not expected. Found: " + value); | ||
return; | ||
} | ||
} | ||
|
||
fail("Metric " + name + " not found in " + response); | ||
}); | ||
} | ||
|
||
private Predicate<Double> greaterOrEqual(double expected) { | ||
return actual -> actual >= expected; | ||
} | ||
|
||
private Double extractValueFromMetric(String line) { | ||
return Double.parseDouble(line.substring(line.lastIndexOf(" "))); | ||
} | ||
} |