forked from quarkusio/quarkus-quickstarts
-
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.
quarkusio#1411: Add more practical example for module micrometer-quic…
…kstart
- Loading branch information
Showing
3 changed files
with
207 additions
and
1 deletion.
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
121 changes: 121 additions & 0 deletions
121
micrometer-quickstart/src/main/java/org/acme/micrometer/TemperatureResource.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,121 @@ | ||
package org.acme.micrometer; | ||
|
||
import java.util.LinkedList; | ||
|
||
import jakarta.ws.rs.GET; | ||
import jakarta.ws.rs.Path; | ||
import jakarta.ws.rs.Produces; | ||
import jakarta.ws.rs.PathParam; | ||
|
||
import io.micrometer.core.instrument.MeterRegistry; | ||
import io.micrometer.core.instrument.Tags; | ||
import io.micrometer.core.instrument.Timer; | ||
import io.micrometer.core.instrument.DistributionSummary; | ||
|
||
/** | ||
* REST API for monitoring and recording temperature readings. | ||
*/ | ||
@Path("/temperature") | ||
@Produces("text/plain") | ||
public class TemperatureResource { | ||
|
||
private final MeterRegistry registry; | ||
private LinkedList<Double> temperatures = new LinkedList<>(); | ||
|
||
DistributionSummary temperatureSummary; | ||
|
||
/** | ||
* Constructs a TemperatureResource. | ||
* Initializes the monitoring tools for temperatures. | ||
* | ||
* @param registry MeterRegistry for recording metrics. | ||
*/ | ||
public TemperatureResource(MeterRegistry registry) { | ||
this.registry = registry; | ||
// Summary to record temperature readings and their distribution. | ||
temperatureSummary = registry.summary("temperature.readings", Tags.of("unit", "celsius")); | ||
// Gauge to monitor the size of the temperature list in real-time. | ||
registry.gaugeCollectionSize("temperature.list.size", Tags.empty(), temperatures); | ||
} | ||
|
||
/** | ||
* Adds a temperature reading to the recorded list and updates the summary metric. | ||
* | ||
* @param temp The temperature to add. | ||
* @return A message confirming the addition of the temperature. | ||
*/ | ||
@GET | ||
@Path("/add/{temp}") | ||
public String addTemperature(@PathParam("temp") double temp) { | ||
temperatures.add(temp); | ||
temperatureSummary.record(temp); | ||
return "Temperature added: " + temp; | ||
} | ||
|
||
/** | ||
* Calculates the average of all recorded temperatures. | ||
* Uses a timer to measure the time taken to perform this calculation. | ||
* | ||
* @return The average temperature or a message if no temperatures are recorded. | ||
*/ | ||
@GET | ||
@Path("/average") | ||
public String calculateAverage() { | ||
Timer timer = registry.timer("temperature.calculation.average"); | ||
return timer.record(() -> { | ||
if (temperatures.isEmpty()) { | ||
return "No temperatures recorded."; | ||
} | ||
double sum = 0; | ||
for (Double t : temperatures) { | ||
sum += t; | ||
} | ||
double average = sum / temperatures.size(); | ||
return "Average temperature: " + average + " Celsius"; | ||
}); | ||
} | ||
|
||
/** | ||
* Finds the maximum temperature from the recorded list. | ||
* Measurement is timed for performance analysis. | ||
* | ||
* @return The maximum temperature or a message if no temperatures are recorded. | ||
*/ | ||
@GET | ||
@Path("/max") | ||
public String findMaxTemperature() { | ||
Timer timer = registry.timer("temperature.calculation.max"); | ||
return timer.record(() -> { | ||
return temperatures.stream() | ||
.max(Double::compare) | ||
.map(maxTemp -> "Maximum temperature: " + maxTemp + " Celsius") | ||
.orElse("No temperatures recorded."); | ||
}); | ||
} | ||
|
||
/** | ||
* Finds the minimum temperature from the recorded list. | ||
* Measurement is timed for performance analysis. | ||
* | ||
* @return The minimum temperature or a message if no temperatures are recorded. | ||
*/ | ||
@GET | ||
@Path("/min") | ||
public String findMinTemperature() { | ||
Timer timer = registry.timer("temperature.calculation.min"); | ||
return timer.record(() -> { | ||
return temperatures.stream() | ||
.min(Double::compare) | ||
.map(minTemp -> "Minimum temperature: " + minTemp + " Celsius") | ||
.orElse("No temperatures recorded."); | ||
}); | ||
} | ||
|
||
// New endpoint to reset the temperatures list | ||
@GET | ||
@Path("/reset") | ||
public String resetTemperatures() { | ||
temperatures.clear(); | ||
return "Temperatures reset successfully."; | ||
} | ||
} |
85 changes: 85 additions & 0 deletions
85
micrometer-quickstart/src/test/java/org/acme/micrometer/TemperatureResourceTest.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,85 @@ | ||
package org.acme.micrometer; | ||
|
||
import static io.restassured.RestAssured.get; | ||
import static io.restassured.RestAssured.when; | ||
import static org.hamcrest.CoreMatchers.containsString; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import io.quarkus.test.junit.QuarkusTest; | ||
import io.restassured.http.Header; | ||
|
||
/** | ||
* Test class for TemperatureResource using REST-assured. | ||
*/ | ||
@QuarkusTest | ||
public class TemperatureResourceTest { | ||
|
||
@BeforeEach | ||
void resetTemperatures() { | ||
get("/temperature/reset").then().assertThat().statusCode(200); | ||
} | ||
|
||
@Test | ||
void testAddTemperature() { | ||
when().get("/temperature/add/20.5").then().statusCode(200) | ||
.body(containsString("Temperature added: 20.5")); | ||
when().get("/temperature/add/22.3").then().statusCode(200) | ||
.body(containsString("Temperature added: 22.3")); | ||
} | ||
|
||
@Test | ||
void testAverageTemperature() { | ||
// Add temperatures first | ||
get("/temperature/add/20.5"); | ||
get("/temperature/add/22.3"); | ||
get("/temperature/add/25.1"); | ||
|
||
// Check the average calculation | ||
when().get("/temperature/average").then().statusCode(200) | ||
.body(containsString("Average temperature: 22.633333333333333 Celsius")); | ||
} | ||
|
||
@Test | ||
void testMaxTemperature() { | ||
// Add temperatures first | ||
get("/temperature/add/20.5"); | ||
get("/temperature/add/22.3"); | ||
get("/temperature/add/25.1"); | ||
|
||
// Check the maximum temperature calculation | ||
when().get("/temperature/max").then().statusCode(200) | ||
.body(containsString("Maximum temperature: 25.1 Celsius")); | ||
} | ||
|
||
@Test | ||
void testMinTemperature() { | ||
// Add temperatures first | ||
get("/temperature/add/20.5"); | ||
get("/temperature/add/22.3"); | ||
get("/temperature/add/25.1"); | ||
|
||
// Check the minimum temperature calculation | ||
when().get("/temperature/min").then().statusCode(200) | ||
.body(containsString("Minimum temperature: 20.5 Celsius")); | ||
} | ||
|
||
@Test | ||
void testTemperatureMetrics() { | ||
// Trigger endpoints to populate metrics | ||
get("/temperature/add/20.5"); | ||
get("/temperature/add/22.3"); | ||
get("/temperature/add/25.1"); | ||
get("/temperature/average"); | ||
get("/temperature/max"); | ||
get("/temperature/min"); | ||
|
||
// Check metrics for recorded operations | ||
when().get("/q/metrics").then().statusCode(200) | ||
.body(containsString("temperature_readings_sum")) | ||
.body(containsString("temperature_readings_count 3.0")) | ||
.body(containsString("temperature_calculation_average_seconds_count 1.0")) | ||
.body(containsString("temperature_calculation_max_seconds_count 1.0")) | ||
.body(containsString("temperature_calculation_min_seconds_count 1.0")); | ||
} | ||
} |