Skip to content

Commit

Permalink
Change GET /solve/ to GET /solution/
Browse files Browse the repository at this point in the history
  • Loading branch information
Elscrux committed Oct 26, 2023
1 parent 3732016 commit fd1fa45
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 48 deletions.
88 changes: 88 additions & 0 deletions src/main/java/edu/kit/provideq/toolbox/api/SolutionRouter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package edu.kit.provideq.toolbox.api;

import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder;
import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder;
import static org.springdoc.webflux.core.fn.SpringdocRouteBuilder.route;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;

import edu.kit.provideq.toolbox.MetaSolverProvider;
import edu.kit.provideq.toolbox.Solution;
import edu.kit.provideq.toolbox.meta.MetaSolver;
import edu.kit.provideq.toolbox.meta.ProblemType;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import org.springdoc.core.fn.builders.operation.Builder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ResponseStatusException;
import reactor.core.publisher.Mono;

/**
* This router handles getting the status of an existing solve request to
* the GET {@code /solution/{problemIndex}} endpoints.
* Requests are validated and relayed to the corresponding {@link MetaSolver}.
*/
@Configuration
@EnableWebFlux
public class SolutionRouter {
private final MetaSolverProvider metaSolverProvider;

public SolutionRouter(MetaSolverProvider metaSolverProvider) {
this.metaSolverProvider = metaSolverProvider;
}

@Bean
RouterFunction<ServerResponse> getSolutionRoutes() {
return metaSolverProvider.getMetaSolvers().stream()
.map(this::defineSolutionRouteForMetaSolver)
.reduce(RouterFunction::and)
.orElseThrow(); // we should always have at least one route or the toolbox is useless
}

private RouterFunction<ServerResponse> defineSolutionRouteForMetaSolver(
MetaSolver<?, ?, ?> metaSolver) {
var problemType = metaSolver.getProblemType();
return route().GET(
getSolutionRouteForProblemType(problemType),
accept(APPLICATION_JSON),
req -> handleSolutionRouteForMetaSolver(metaSolver, req),
ops -> handleSolversRouteDocumentation(ops, problemType)
).build();
}

private void handleSolversRouteDocumentation(Builder ops, ProblemType problemType) {
ops
.operationId(getSolutionRouteForProblemType(problemType))
.tag(problemType.getId())
.parameter(parameterBuilder().in(ParameterIn.QUERY).name("id"))
.response(responseBuilder()
.responseCode(String.valueOf(HttpStatus.OK.value()))
.implementation(Solution.class))
.response(responseBuilder()
.responseCode(String.valueOf(HttpStatus.NOT_FOUND.value())));
}

private Mono<ServerResponse> handleSolutionRouteForMetaSolver(
MetaSolver<?, ?, ?> metaSolver, ServerRequest req) {
var solution = req.queryParam("id")
.map(Long::parseLong)
.map(solutionId -> metaSolver.getSolutionManager().getSolution(solutionId))
.map(Solution::toStringSolution)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND,
"Could not find a solution for this problem with this solution id!"));

return ok().body(Mono.just(solution), new ParameterizedTypeReference<>() {
});
}

private String getSolutionRouteForProblemType(ProblemType type) {
return "/solution/" + type.getId();
}
}
48 changes: 0 additions & 48 deletions src/main/java/edu/kit/provideq/toolbox/api/SolveRouter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder;
import static org.springdoc.core.fn.builders.arrayschema.Builder.arraySchemaBuilder;
import static org.springdoc.core.fn.builders.content.Builder.contentBuilder;
import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder;
import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder;
import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder;
import static org.springdoc.webflux.core.fn.SpringdocRouteBuilder.route;
Expand All @@ -21,7 +20,6 @@
import edu.kit.provideq.toolbox.meta.ProblemSolver;
import edu.kit.provideq.toolbox.meta.ProblemType;
import edu.kit.provideq.toolbox.meta.SubRoutineDefinition;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.springdoc.core.fn.builders.operation.Builder;
Expand All @@ -36,7 +34,6 @@
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebInputException;
import reactor.core.publisher.Mono;

Expand Down Expand Up @@ -93,47 +90,6 @@ private <ProblemT> void validate(SolveRequest<ProblemT> request) {
}
}

@Bean
RouterFunction<ServerResponse> getSolutionRoutes() {
return metaSolverProvider.getMetaSolvers().stream()
.map(this::defineSolutionRouteForMetaSolver)
.reduce(RouterFunction::and)
.orElseThrow(); // we should always have at least one route or the toolbox is useless
}

private RouterFunction<ServerResponse> defineSolutionRouteForMetaSolver(
MetaSolver<?, ?, ?> metaSolver) {
var problemType = metaSolver.getProblemType();
return route().GET(
// FIXME this is intentionally SOLVE instead of SOLUTION to avoid breaking things
// but maybe we should switch the name at some point
getSolveRouteForProblemType(problemType),
accept(APPLICATION_JSON),
req -> handleSolutionRouteForMetaSolver(metaSolver, req),
ops -> ops
.operationId(getSolutionRouteForProblemType(problemType))
.tag(problemType.getId())
.parameter(parameterBuilder().in(ParameterIn.QUERY).name("id"))
.response(responseBuilder()
.responseCode(String.valueOf(HttpStatus.OK.value()))
.implementation(Solution.class)
)
).build();
}

private Mono<ServerResponse> handleSolutionRouteForMetaSolver(MetaSolver<?, ?, ?> metaSolver,
ServerRequest req) {
var solution = req.queryParam("id")
.map(Long::parseLong)
.map(solutionId -> metaSolver.getSolutionManager().getSolution(solutionId))
.map(Solution::toStringSolution)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND,
"Could not find a solution for this problem with this solution id!"));

return ok().body(Mono.just(solution), new ParameterizedTypeReference<>() {
});
}

private void handleRouteDocumentation(MetaSolver<?, ?, ?> metaSolver, Builder ops) {
var problemType = metaSolver.getProblemType();
ops
Expand Down Expand Up @@ -262,8 +218,4 @@ private org.springdoc.core.fn.builders.content.Builder getRequestContent(
private String getSolveRouteForProblemType(ProblemType type) {
return "/solve/" + type.getId();
}

private String getSolutionRouteForProblemType(ProblemType type) {
return "/solution/" + type.getId();
}
}

0 comments on commit fd1fa45

Please sign in to comment.