package com.dbg.cloud.acheron.routing.endpoints; import com.dbg.cloud.acheron.adminendpoints.AdminEndpoint; import com.dbg.cloud.acheron.exception.TechnicalException; import com.dbg.cloud.acheron.exception.ValidationException; import com.dbg.cloud.acheron.routing.Route; import com.dbg.cloud.acheron.routing.service.RouteService; import com.fasterxml.jackson.annotation.JsonView; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @RestController @RequestMapping("/admin/routes") @AllArgsConstructor @Slf4j final class RoutesController implements AdminEndpoint { private final RouteService routeService; @RequestMapping(value = "", method = RequestMethod.GET) public List<RouteTO> readRoutes() { try { final List<Route> routeList = routeService.getAllRoutes(); return routeList.stream().map(route -> new RouteTO(route)).collect(Collectors.toList()); } catch (final TechnicalException e) { throw new InternalServerError(); } } @RequestMapping(value = "/{routeId}", method = RequestMethod.GET) public ResponseEntity<?> readRoute(final @PathVariable String routeId) { if (routeId == null) { throw new RouteNotFoundException(routeId); } try { final Optional<Route> optionalRoute = routeService.getRoute(routeId); return ResponseEntity.ok(new RouteTO(optionalRoute.orElseThrow(() -> new RouteNotFoundException(routeId)))); } catch (final TechnicalException e) { throw new InternalServerError(); } } @RequestMapping(value = "", method = RequestMethod.POST) public ResponseEntity<?> addRoute(final @JsonView(View.Create.class) @RequestBody RouteTO route) { if (!validateRoute(route)) { return ResponseEntity.badRequest().build(); } try { return ResponseEntity .status(HttpStatus.CREATED) .body(routeService.addNewRoute(new Route.ForCreation( route.getId(), route.getHttpMethods(), route.getPath(), route.getServiceId(), route.getUrl(), route.isKeepPrefix(), route.isRetryable(), route.isOverrideSensitiveHeaders(), route.getSensitiveHeaders()))); } catch (final ValidationException e) { return ResponseEntity.badRequest().build(); } catch (final TechnicalException e) { throw new InternalServerError(); } } @RequestMapping(value = "/{routeId}", method = RequestMethod.DELETE) public ResponseEntity<?> deleteRoute(final @PathVariable String routeId) { if (routeId == null) { throw new RouteNotFoundException(routeId); } try { routeService.deleteRoute(routeId); return ResponseEntity.noContent().build(); } catch (final TechnicalException e) { throw new InternalServerError(); } } private boolean validateRoute(final RouteTO route) { return true; } @ResponseStatus(HttpStatus.NOT_FOUND) class RouteNotFoundException extends RuntimeException { public RouteNotFoundException(final String routeId) { super("Could not find route '" + routeId + "'"); } } @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) class InternalServerError extends RuntimeException { } }