Implement routes to list, get and delete execution environments
* #9 Implement routes to list, get and delete execution environments. A refactoring was required to introduce the ExecutionEnvironment interface. * Fix MR comments, linting issues and bug that lead to e2e test failure * Add e2e tests * Add unit tests
This commit is contained in:
@ -9,11 +9,16 @@ import (
|
||||
"github.com/openHPI/poseidon/internal/runner"
|
||||
"github.com/openHPI/poseidon/pkg/dto"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
executionEnvironmentIDKey = "executionEnvironmentId"
|
||||
fetchEnvironmentKey = "fetch"
|
||||
listRouteName = "list"
|
||||
getRouteName = "get"
|
||||
createOrUpdateRouteName = "createOrUpdate"
|
||||
deleteRouteName = "delete"
|
||||
)
|
||||
|
||||
var ErrMissingURLParameter = errors.New("url parameter missing")
|
||||
@ -22,10 +27,82 @@ type EnvironmentController struct {
|
||||
manager environment.Manager
|
||||
}
|
||||
|
||||
type ExecutionEnvironmentsResponse struct {
|
||||
ExecutionEnvironments []runner.ExecutionEnvironment `json:"executionEnvironments"`
|
||||
}
|
||||
|
||||
func (e *EnvironmentController) ConfigureRoutes(router *mux.Router) {
|
||||
environmentRouter := router.PathPrefix(EnvironmentsPath).Subrouter()
|
||||
environmentRouter.HandleFunc("", e.list).Methods(http.MethodGet).Name(listRouteName)
|
||||
|
||||
specificEnvironmentRouter := environmentRouter.Path(fmt.Sprintf("/{%s:[0-9]+}", executionEnvironmentIDKey)).Subrouter()
|
||||
specificEnvironmentRouter.HandleFunc("", e.get).Methods(http.MethodGet).Name(getRouteName)
|
||||
specificEnvironmentRouter.HandleFunc("", e.createOrUpdate).Methods(http.MethodPut).Name(createOrUpdateRouteName)
|
||||
specificEnvironmentRouter.HandleFunc("", e.delete).Methods(http.MethodDelete).Name(deleteRouteName)
|
||||
}
|
||||
|
||||
// list returns all information about available execution environments.
|
||||
func (e *EnvironmentController) list(writer http.ResponseWriter, request *http.Request) {
|
||||
fetch, err := parseFetchParameter(request)
|
||||
if err != nil {
|
||||
writeBadRequest(writer, err)
|
||||
return
|
||||
}
|
||||
|
||||
environments, err := e.manager.List(fetch)
|
||||
if err != nil {
|
||||
writeInternalServerError(writer, err, dto.ErrorUnknown)
|
||||
return
|
||||
}
|
||||
|
||||
sendJSON(writer, ExecutionEnvironmentsResponse{environments}, http.StatusOK)
|
||||
}
|
||||
|
||||
// get returns all information about the requested execution environment.
|
||||
func (e *EnvironmentController) get(writer http.ResponseWriter, request *http.Request) {
|
||||
environmentID, err := parseEnvironmentID(request)
|
||||
if err != nil {
|
||||
// This case is never used as the router validates the id format
|
||||
writeBadRequest(writer, err)
|
||||
return
|
||||
}
|
||||
fetch, err := parseFetchParameter(request)
|
||||
if err != nil {
|
||||
writeBadRequest(writer, err)
|
||||
return
|
||||
}
|
||||
|
||||
executionEnvironment, err := e.manager.Get(environmentID, fetch)
|
||||
if errors.Is(err, runner.ErrUnknownExecutionEnvironment) {
|
||||
writer.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
} else if err != nil {
|
||||
writeInternalServerError(writer, err, dto.ErrorUnknown)
|
||||
return
|
||||
}
|
||||
|
||||
sendJSON(writer, executionEnvironment, http.StatusOK)
|
||||
}
|
||||
|
||||
// delete removes the specified execution environment.
|
||||
func (e *EnvironmentController) delete(writer http.ResponseWriter, request *http.Request) {
|
||||
environmentID, err := parseEnvironmentID(request)
|
||||
if err != nil {
|
||||
// This case is never used as the router validates the id format
|
||||
writeBadRequest(writer, err)
|
||||
return
|
||||
}
|
||||
|
||||
found, err := e.manager.Delete(environmentID)
|
||||
if err != nil {
|
||||
writeInternalServerError(writer, err, dto.ErrorUnknown)
|
||||
return
|
||||
} else if !found {
|
||||
writer.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
writer.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// createOrUpdate creates/updates an execution environment on the executor.
|
||||
@ -35,17 +112,12 @@ func (e *EnvironmentController) createOrUpdate(writer http.ResponseWriter, reque
|
||||
writeBadRequest(writer, err)
|
||||
return
|
||||
}
|
||||
|
||||
id, ok := mux.Vars(request)[executionEnvironmentIDKey]
|
||||
if !ok {
|
||||
writeBadRequest(writer, fmt.Errorf("could not find %s: %w", executionEnvironmentIDKey, ErrMissingURLParameter))
|
||||
return
|
||||
}
|
||||
environmentID, err := runner.NewEnvironmentID(id)
|
||||
environmentID, err := parseEnvironmentID(request)
|
||||
if err != nil {
|
||||
writeBadRequest(writer, fmt.Errorf("could not update environment: %w", err))
|
||||
writeBadRequest(writer, err)
|
||||
return
|
||||
}
|
||||
|
||||
created, err := e.manager.CreateOrUpdate(environmentID, *req)
|
||||
if err != nil {
|
||||
writeInternalServerError(writer, err, dto.ErrorUnknown)
|
||||
@ -57,3 +129,26 @@ func (e *EnvironmentController) createOrUpdate(writer http.ResponseWriter, reque
|
||||
writer.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
func parseEnvironmentID(request *http.Request) (dto.EnvironmentID, error) {
|
||||
id, ok := mux.Vars(request)[executionEnvironmentIDKey]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("could not find %s: %w", executionEnvironmentIDKey, ErrMissingURLParameter)
|
||||
}
|
||||
environmentID, err := dto.NewEnvironmentID(id)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not update environment: %w", err)
|
||||
}
|
||||
return environmentID, nil
|
||||
}
|
||||
|
||||
func parseFetchParameter(request *http.Request) (fetch bool, err error) {
|
||||
fetchString := request.FormValue(fetchEnvironmentKey)
|
||||
if len(fetchString) > 0 {
|
||||
fetch, err = strconv.ParseBool(fetchString)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("could not parse fetch parameter: %w", err)
|
||||
}
|
||||
}
|
||||
return fetch, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user