From 2b9b668a2f87118ca0681c4cb585354c119e45b0 Mon Sep 17 00:00:00 2001 From: js0ny Date: Tue, 18 Nov 2025 13:14:06 +0000 Subject: [PATCH] test: /actuator/health endpoint --- .gitignore | 4 +- Makefile | 2 +- flake.nix | 2 + .../controller/DroneController.java | 54 +++++++++++++++++++ .../data/DroneCapabilityDto.java | 12 +++++ .../js0ny/ilp_coursework/data/DroneDto.java | 10 ++++ .../service/DroneInfoService.java | 8 +++ .../service/DroneInfoServices.java | 2 - .../ilp_coursework/ActuatorHealthTest.java | 36 +++++++++++++ 9 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 src/main/java/io/github/js0ny/ilp_coursework/data/DroneCapabilityDto.java create mode 100644 src/main/java/io/github/js0ny/ilp_coursework/data/DroneDto.java create mode 100644 src/main/java/io/github/js0ny/ilp_coursework/service/DroneInfoService.java delete mode 100644 src/main/java/io/github/js0ny/ilp_coursework/service/DroneInfoServices.java create mode 100644 src/test/java/io/github/js0ny/ilp_coursework/ActuatorHealthTest.java diff --git a/.gitignore b/.gitignore index b8830e9..a8e65fd 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,6 @@ out/ ### VS Code ### .vscode/ -*.tar \ No newline at end of file +*.tar +.direnv/ +.envrc \ No newline at end of file diff --git a/Makefile b/Makefile index 10a987c..947e3eb 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # --- Variables --- IMAGE_NAME := ilp-coursework -IMAGE_TAG := 0.1 +IMAGE_TAG := 0.2 FULL_IMAGE_NAME := ${IMAGE_NAME}:${IMAGE_TAG} CONTAINER_NAME := ilp-coursework-app SUBMISSION_FILE := ilp_submission_image.tar diff --git a/flake.nix b/flake.nix index 55c7aaf..773eb61 100644 --- a/flake.nix +++ b/flake.nix @@ -20,7 +20,9 @@ in { default = pkgs.mkShell { buildInputs = with pkgs; [ + vscode-langservers-extracted jdt-language-server + jless jdk21 gradle httpie diff --git a/src/main/java/io/github/js0ny/ilp_coursework/controller/DroneController.java b/src/main/java/io/github/js0ny/ilp_coursework/controller/DroneController.java index e69de29..e535b7f 100644 --- a/src/main/java/io/github/js0ny/ilp_coursework/controller/DroneController.java +++ b/src/main/java/io/github/js0ny/ilp_coursework/controller/DroneController.java @@ -0,0 +1,54 @@ +package io.github.js0ny.ilp_coursework.controller; + +import org.springframework.web.bind.annotation.*; + +import io.github.js0ny.ilp_coursework.service.DroneInfoService; +import io.github.js0ny.ilp_coursework.data.DroneDto; +import org.springframework.web.client.RestTemplate; + +import java.util.Arrays; + +@RestController +@RequestMapping("/api/v1") +public class DroneController { + private final DroneInfoService droneService; + private final String baseUrl; + private final RestTemplate restTemplate = new RestTemplate(); + + public DroneController(DroneInfoService droneService) { + this.droneService = droneService; + String baseUrl = System.getenv("ILP_ENDPOINT"); + if (baseUrl == null || baseUrl.isBlank()) { + this.baseUrl = "https://ilp-rest-2025-bvh6e9hschfagrgy.ukwest-01.azurewebsites.net/"; + } else { + if (!baseUrl.endsWith("/")) { + baseUrl += "/"; + } + this.baseUrl = baseUrl; + } + } + + @GetMapping("/dronesWithCooling/{state}") + + public int[] getDronesWithCoolingAbility(@PathVariable boolean state) { + + String droneUrl = baseUrl + "drones"; + + DroneDto[] drones = restTemplate.getForObject(droneUrl, DroneDto[].class); + + if (drones == null) { + return new int[]{}; + } + + return Arrays.stream(drones). + filter(drone -> drone.capability().cooling() == state). + mapToInt(drone -> Integer.parseInt(String.valueOf(drone.id()))). + toArray(); + } + + @PostMapping("queryAvailableDrones") + public int queryAvailableDrones() { + return 1; + } + +} diff --git a/src/main/java/io/github/js0ny/ilp_coursework/data/DroneCapabilityDto.java b/src/main/java/io/github/js0ny/ilp_coursework/data/DroneCapabilityDto.java new file mode 100644 index 0000000..6f7d824 --- /dev/null +++ b/src/main/java/io/github/js0ny/ilp_coursework/data/DroneCapabilityDto.java @@ -0,0 +1,12 @@ +package io.github.js0ny.ilp_coursework.data; + +public record DroneCapabilityDto( + boolean cooling, + boolean heating, + float capacity, + int maxMoves, + float costPerMove, + float costInitial, + float costFinal) { + +} diff --git a/src/main/java/io/github/js0ny/ilp_coursework/data/DroneDto.java b/src/main/java/io/github/js0ny/ilp_coursework/data/DroneDto.java new file mode 100644 index 0000000..8282573 --- /dev/null +++ b/src/main/java/io/github/js0ny/ilp_coursework/data/DroneDto.java @@ -0,0 +1,10 @@ +package io.github.js0ny.ilp_coursework.data; + +/** + * Represents the data transfer object for a drone, gained from the endpoints + */ +public record DroneDto( + String name, + int id, + DroneCapabilityDto capability) { +} diff --git a/src/main/java/io/github/js0ny/ilp_coursework/service/DroneInfoService.java b/src/main/java/io/github/js0ny/ilp_coursework/service/DroneInfoService.java new file mode 100644 index 0000000..9ac70eb --- /dev/null +++ b/src/main/java/io/github/js0ny/ilp_coursework/service/DroneInfoService.java @@ -0,0 +1,8 @@ +package io.github.js0ny.ilp_coursework.service; + +import org.springframework.stereotype.Service; + +@Service +public class DroneInfoService { + +} diff --git a/src/main/java/io/github/js0ny/ilp_coursework/service/DroneInfoServices.java b/src/main/java/io/github/js0ny/ilp_coursework/service/DroneInfoServices.java deleted file mode 100644 index f58f807..0000000 --- a/src/main/java/io/github/js0ny/ilp_coursework/service/DroneInfoServices.java +++ /dev/null @@ -1,2 +0,0 @@ -package io.github.js0ny.ilp_coursework.service; - diff --git a/src/test/java/io/github/js0ny/ilp_coursework/ActuatorHealthTest.java b/src/test/java/io/github/js0ny/ilp_coursework/ActuatorHealthTest.java new file mode 100644 index 0000000..a00efc2 --- /dev/null +++ b/src/test/java/io/github/js0ny/ilp_coursework/ActuatorHealthTest.java @@ -0,0 +1,36 @@ +package io.github.js0ny.ilp_coursework; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@AutoConfigureMockMvc +public class ActuatorHealthTest { + + @Autowired + private MockMvc mockMvc; + + @Test + @DisplayName("GET /actuator/health -> 200 OK") + void getActuator_shouldReturn200AndON() throws Exception { + String endpoint = "/actuator/health"; + String expected = """ + { + "status": "UP" + } + """; + var mock = mockMvc.perform(get(endpoint)); + mock.andDo(print()); + mock.andExpect(status().isOk()); + mock.andExpect(content().json(expected)); + } +}