Skip to content

Commit

Permalink
added openapi docs for eval api
Browse files Browse the repository at this point in the history
  • Loading branch information
Taz03 committed May 22, 2024
1 parent ce2c90a commit 74d6aec
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 30 deletions.
9 changes: 7 additions & 2 deletions JShellAPI/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@ import java.time.Instant

plugins {
id 'org.springframework.boot' version '3.2.5'
id 'io.spring.dependency-management' version '1.1.5'
id 'com.google.cloud.tools.jib' version '3.4.2'
id 'io.spring.dependency-management' version '1.1.0'
id 'org.springdoc.openapi-gradle-plugin' version '1.8.0'
id 'com.google.cloud.tools.jib' version '3.3.2'
id 'com.github.johnrengelman.shadow' version '8.1.1'
}

dependencies {
implementation project(':JShellWrapper')
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'com.github.docker-java:docker-java-transport-httpclient5:3.3.6'
implementation 'com.github.docker-java:docker-java-core:3.3.6'

implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
implementation 'org.springdoc:springdoc-openapi-starter-webflux-ui:2.5.0'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
package org.togetherjava.jshellapi.rest;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;

import jakarta.validation.constraints.Pattern;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
Expand All @@ -17,16 +26,52 @@
@RequestMapping("jshell")
@RestController
public class JShellController {
private JShellSessionService service;
private StartupScriptsService startupScriptsService;
private static final String ID_REGEX = "^[a-zA-Z0-9][a-zA-Z0-9_.-]+$";

@Autowired private JShellSessionService service;
@Autowired private StartupScriptsService startupScriptsService;

@PostMapping("/eval/{id}")
@Operation(
summary = "Evaluate code in a JShell session",
description =
"Evaluate code in a JShell session, create a session from this id, or use an"
+ " existing session if this id already exists.")
@ApiResponse(
responseCode = "200",
content = {
@Content(
mediaType = "application/json",
schema = @Schema(implementation = JShellResult.class))
})
public JShellResult eval(
@PathVariable String id,
@RequestParam(required = false) StartupScriptId startupScriptId,
@RequestBody String code)
@Parameter(description = "id of the session, must follow the regex " + ID_REGEX)
@Pattern(regexp = ID_REGEX, message = "'id' doesn't match regex " + ID_REGEX)
@PathVariable
String id,
@Parameter(description = "id of the startup script to use")
@RequestParam(required = false)
StartupScriptId startupScriptId,
@io.swagger.v3.oas.annotations.parameters.RequestBody(
content = {
@Content(
mediaType = "text/plain",
examples = {
@ExampleObject(
name = "Hello world example",
value =
"System.out.println(\"Hello,"
+ " World!\");"),
@ExampleObject(
name =
"Hello world example with startup"
+ " script",
value = "println(\"Hello, World!\");")
})
})
@RequestBody
String code)
throws DockerException {
validateId(id);
return service.session(id, startupScriptId)
.eval(code)
.orElseThrow(
Expand Down Expand Up @@ -68,11 +113,12 @@ public JShellResult singleEval(

@GetMapping("/snippets/{id}")
public List<String> snippets(
@PathVariable String id, @RequestParam(required = false) boolean includeStartupScript)
@PathVariable
@Pattern(regexp = ID_REGEX, message = "'id' doesn't match regex " + ID_REGEX)
String id,
@RequestParam(required = false) boolean includeStartupScript)
throws DockerException {
validateId(id);
if (!service.hasSession(id))
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Id " + id + " not found");
checkId(id);
return service.session(id, null)
.snippets(includeStartupScript)
.orElseThrow(
Expand All @@ -82,10 +128,12 @@ public List<String> snippets(
}

@DeleteMapping("/{id}")
public void delete(@PathVariable String id) throws DockerException {
validateId(id);
if (!service.hasSession(id))
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Id " + id + " not found");
public void delete(
@PathVariable
@Pattern(regexp = ID_REGEX, message = "'id' doesn't match regex " + ID_REGEX)
String id)
throws DockerException {
checkId(id);
service.deleteSession(id);
}

Expand All @@ -94,21 +142,10 @@ public String startupScript(@PathVariable StartupScriptId id) {
return startupScriptsService.get(id);
}

@Autowired
public void setService(JShellSessionService service) {
this.service = service;
}

@Autowired
public void setStartupScriptsService(StartupScriptsService startupScriptsService) {
this.startupScriptsService = startupScriptsService;
}

private static void validateId(String id) throws ResponseStatusException {
if (!id.matches("[a-zA-Z0-9][a-zA-Z0-9_.-]+")) {
private void checkId(String id) {
if (!id.matches(ID_REGEX)) {
throw new ResponseStatusException(
HttpStatus.BAD_REQUEST,
"Id " + id + " doesn't match the regex [a-zA-Z0-9][a-zA-Z0-9_.-]+");
HttpStatus.BAD_REQUEST, "Id " + id + " doesn't match regex " + ID_REGEX);
}
}
}
1 change: 1 addition & 0 deletions JShellAPI/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jshellapi:
server:
error:
include-message: always
include-binding-errors: always

logging:
level:
Expand Down

0 comments on commit 74d6aec

Please sign in to comment.