feat: template for all endpoints

This commit is contained in:
js0ny 2025-11-21 12:10:08 +00:00
parent 44d510ddd4
commit a6916ba5da
9 changed files with 132 additions and 40 deletions

View file

@ -9,5 +9,4 @@ public class IlpCourseworkApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(IlpCourseworkApplication.class, args); SpringApplication.run(IlpCourseworkApplication.class, args);
} }
} }

View file

@ -1,30 +1,35 @@
package io.github.js0ny.ilp_coursework.controller; package io.github.js0ny.ilp_coursework.controller;
import io.github.js0ny.ilp_coursework.data.AttrComparatorDto;
import io.github.js0ny.ilp_coursework.data.DeliveryPathDto;
import io.github.js0ny.ilp_coursework.data.DroneDto;
import io.github.js0ny.ilp_coursework.data.DronePathDto;
import io.github.js0ny.ilp_coursework.data.MedDispathRecDto;
import io.github.js0ny.ilp_coursework.service.DroneInfoService;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; 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 org.springframework.web.client.RestTemplate;
import java.util.Arrays;
/** /**
* Main Rest Controller for the ILP Coursework 2 application. * Main Rest Controller for the ILP Coursework 2 application.
* <p> * <p>
* This class handles incoming HTTP requests for the API under {@code /api/v1} path (defined in CW2) * This class handles incoming HTTP requests for the API under {@code /api/v1}
* path (defined in CW2)
* The business logic is delegated to {@link DroneInfoService} * The business logic is delegated to {@link DroneInfoService}
*/ */
@RestController @RestController
@RequestMapping("/api/v1") @RequestMapping("/api/v1")
public class DroneController { public class DroneController {
private final DroneInfoService droneService; private final DroneInfoService droneService;
private final RestTemplate restTemplate = new RestTemplate(); private final RestTemplate restTemplate = new RestTemplate();
/** /**
* Constructor of the {@code DroneController} with the business logic dependency {@code DroneInfoService} * Constructor of the {@code DroneController} with the business logic dependency
* {@code DroneInfoService}
* <p> * <p>
* We handle the {@code baseUrl} here. Use a predefined URL if the environment variable {@code ILP_ENDPOINT} * We handle the {@code baseUrl} here. Use a predefined URL if the environment
* variable {@code ILP_ENDPOINT}
* is not given. * is not given.
* *
* @param droneService The service component that contains all business logic * @param droneService The service component that contains all business logic
@ -34,9 +39,11 @@ public class DroneController {
} }
/** /**
* Handles GET requests to retrieve an array of drones (identified by id) that has the capability of cooling * Handles GET requests to retrieve an array of drones (identified by id) that
* has the capability of cooling
* *
* @param state The path variable that indicates the return should have or not have the capability * @param state The path variable that indicates the return should have or not
* have the capability
* @return An array of drone id with cooling capability. * @return An array of drone id with cooling capability.
*/ */
@GetMapping("/dronesWithCooling/{state}") @GetMapping("/dronesWithCooling/{state}")
@ -44,6 +51,13 @@ public class DroneController {
return droneService.dronesWithCooling(state); return droneService.dronesWithCooling(state);
} }
/**
* Handles GET requests to retrieve the drone detail identified by id
*
* @param id The id of the drone to be queried.
* @return 200 with {@link DroneDto}-style json if success, 404 if {@code id}
* not found, 400 otherwise
*/
@GetMapping("/droneDetails/{id}") @GetMapping("/droneDetails/{id}")
public ResponseEntity<DroneDto> getDroneDetail(@PathVariable String id) { public ResponseEntity<DroneDto> getDroneDetail(@PathVariable String id) {
try { try {
@ -54,9 +68,31 @@ public class DroneController {
} }
} }
@PostMapping("queryAvailableDrones") @GetMapping("/queryAsPath/{attrName}/{attrVal}")
public int queryAvailableDrones() { public int[] getIdByAttrMap(
return 1; @PathVariable String attrName,
@PathVariable String attrVal) {
return droneService.dronesWithAttribute(attrName, attrVal);
}
@PostMapping("/query")
public int[] getIdByAttrMapPost(@RequestBody AttrComparatorDto[] attrComparators) {
return new int[] {};
}
@PostMapping("/queryAvailableDrones")
public int[] queryAvailableDrones(@RequestBody MedDispathRecDto[] records) {
return new int[] {};
}
@PostMapping("/calcDeliveryPath")
public DeliveryPathDto calculateDeliveryPath(@RequestBody MedDispathRecDto[] record) {
return new DeliveryPathDto(0.0f, 0, new DronePathDto[] {});
}
@PostMapping("/calcDeliveryPathAsGeoJson")
public String calculateDeliveryPathAsGeoJson(@RequestBody MedDispathRecDto[] record) {
return "{}";
} }
} }

View file

@ -0,0 +1,4 @@
package io.github.js0ny.ilp_coursework.data;
public record AttrComparatorDto(String attribute, String operator, String value) {
}

View file

@ -0,0 +1,4 @@
package io.github.js0ny.ilp_coursework.data;
public enum AttrOperator {
}

View file

@ -0,0 +1,7 @@
package io.github.js0ny.ilp_coursework.data;
public record DeliveryPathDto(
float totalCost,
int totalMoves,
DronePathDto[] dronePaths) {
}

View file

@ -0,0 +1,4 @@
package io.github.js0ny.ilp_coursework.data;
public record DronePathDto() {
}

View file

@ -0,0 +1,11 @@
package io.github.js0ny.ilp_coursework.data;
import java.time.LocalDate;
import java.time.LocalTime;
public record MedDispathRecDto(
int id,
LocalDate date,
LocalTime time,
MedRequirementDto requirements) {
}

View file

@ -0,0 +1,8 @@
package io.github.js0ny.ilp_coursework.data;
public record MedRequirementDto(
float capacity,
boolean cooling,
boolean heating,
float maxCost
) {}

View file

@ -1,14 +1,10 @@
package io.github.js0ny.ilp_coursework.service; package io.github.js0ny.ilp_coursework.service;
import io.github.js0ny.ilp_coursework.data.DroneDto; import io.github.js0ny.ilp_coursework.data.DroneDto;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriBuilder;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI; import java.net.URI;
import java.util.Arrays; import java.util.Arrays;
import java.util.stream.Stream; import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service @Service
public class DroneInfoService { public class DroneInfoService {
@ -22,7 +18,6 @@ public class DroneInfoService {
* Constructor, handles the base url here. * Constructor, handles the base url here.
*/ */
public DroneInfoService() { public DroneInfoService() {
String baseUrl = System.getenv("ILP_ENDPOINT"); String baseUrl = System.getenv("ILP_ENDPOINT");
if (baseUrl == null || baseUrl.isBlank()) { if (baseUrl == null || baseUrl.isBlank()) {
this.baseUrl = "https://ilp-rest-2025-bvh6e9hschfagrgy.ukwest-01.azurewebsites.net/"; this.baseUrl = "https://ilp-rest-2025-bvh6e9hschfagrgy.ukwest-01.azurewebsites.net/";
@ -39,21 +34,23 @@ public class DroneInfoService {
* Return an array of ids of drones with/without cooling capability * Return an array of ids of drones with/without cooling capability
* *
* @param state determines the capability filtering * @param state determines the capability filtering
* @return if {@code state} is true, return ids of drones with cooling capability, else without cooling * @return if {@code state} is true, return ids of drones with cooling
* capability, else without cooling
*/ */
public int[] dronesWithCooling(boolean state) { public int[] dronesWithCooling(boolean state) {
URI droneUrl = URI.create(baseUrl).resolve(dronesEndpoint); URI droneUrl = URI.create(baseUrl).resolve(dronesEndpoint);
DroneDto[] drones = restTemplate.getForObject(
DroneDto[] drones = restTemplate.getForObject(droneUrl, DroneDto[].class); droneUrl,
DroneDto[].class);
if (drones == null) { if (drones == null) {
return new int[] {}; return new int[] {};
} }
return Arrays.stream(drones). return Arrays.stream(drones)
filter(drone -> drone.capability().cooling() == state). .filter(drone -> drone.capability().cooling() == state)
mapToInt(drone -> Integer.parseInt(drone.id())). .mapToInt(drone -> Integer.parseInt(drone.id()))
toArray(); .toArray();
} }
/** /**
@ -61,14 +58,17 @@ public class DroneInfoService {
* *
* @param id The id of the drone * @param id The id of the drone
* @return drone json body of given id * @return drone json body of given id
* @throws NullPointerException when cannot fetch available drones from remote * @throws NullPointerException when cannot fetch available drones from
* @throws IllegalArgumentException when drone with given {@code id} cannot be found * remote
* @throws IllegalArgumentException when drone with given {@code id} cannot be
* found
* this should lead to a 404 * this should lead to a 404
*/ */
public DroneDto droneDetail(String id) { public DroneDto droneDetail(String id) {
String droneUrl = baseUrl + dronesEndpoint; URI droneUrl = URI.create(baseUrl).resolve(dronesEndpoint);
DroneDto[] drones = restTemplate.getForObject(
DroneDto[] drones = restTemplate.getForObject(droneUrl, DroneDto[].class); droneUrl,
DroneDto[].class);
if (drones == null) { if (drones == null) {
throw new NullPointerException("drone cannot be found"); throw new NullPointerException("drone cannot be found");
@ -80,8 +80,27 @@ public class DroneInfoService {
} }
} }
throw new IllegalArgumentException("drone with that ID cannot be found"); throw new IllegalArgumentException(
"drone with that ID cannot be found");
} }
/**
* Return an array of ids of drones with a given attribute name and value
*
* @param attrName the attribute name to filter on
* @param attrVal the attribute value to filter on
* @return array of drone ids matching the attribute name and value
*/
public int[] dronesWithAttribute(String attrName, String attrVal) {
URI droneUrl = URI.create(baseUrl).resolve(dronesEndpoint);
DroneDto[] drones = restTemplate.getForObject(
droneUrl,
DroneDto[].class
);
// TODO: Logic unimplemented
return new int[] {};
}
public int[] dronesMatchesRequirements()
} }