Skip to content

Commit

Permalink
Support of HttpServletRequest, HttpServletResponse and HttpSession ty…
Browse files Browse the repository at this point in the history
…pes in SpringAnnotationScanner (smallrye#1829)

* Implemented isFrameworkContextType() in SpringAnnotationScanner

* Apply suggestions from code review on

Use the newer jakarta classes

Co-authored-by: Michael Edgar <[email protected]>

* Now Jakarta classes are managed too

* Readded test scope to javax.servlet-api dep

---------

Co-authored-by: Leonardo Moretti <[email protected]>
Co-authored-by: Michael Edgar <[email protected]>
  • Loading branch information
3 people committed Jun 6, 2024
1 parent 47fd3da commit 7a5232b
Show file tree
Hide file tree
Showing 8 changed files with 306 additions and 0 deletions.
11 changes: 11 additions & 0 deletions extension-spring/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@
<artifactId>spring-webmvc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>test</scope>
</dependency>

<!-- Depend on core tests -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ public boolean isMultipartInput(Type inputType) {
return SpringConstants.MULTIPART_INPUTS.contains(inputType.name());
}

@Override
public boolean isFrameworkContextType(Type type) {
return SpringConstants.CONTEXTS.contains(type.name());
}

@Override
public boolean containsScannerAnnotations(List<AnnotationInstance> instances,
List<AnnotationScannerExtension> extensions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.jboss.jandex.DotName;

Expand Down Expand Up @@ -34,6 +36,14 @@ public class SpringConstants {
static final DotName HEADER_PARAM = DotName.createSimple("org.springframework.web.bind.annotation.RequestHeader");
static final DotName MATRIX_PARAM = DotName.createSimple("org.springframework.web.bind.annotation.MatrixVariable");

static final Set<DotName> CONTEXTS = Stream.of("javax", "jakarta")
.map(prefix -> DotName.createComponentized(null, prefix))
.map(prefix -> DotName.createComponentized(prefix, "servlet"))
.map(prefix -> DotName.createComponentized(prefix, "http"))
.flatMap(prefix -> Stream.of("HttpServletRequest", "HttpServletResponse", "HttpSession")
.map(simpleName -> DotName.createComponentized(prefix, simpleName)))
.collect(Collectors.toSet());

public static final Set<DotName> MULTIPART_OUTPUTS = Collections
.unmodifiableSet(new HashSet<>(Arrays.asList(MUTIPART_FILE)));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import test.io.smallrye.openapi.runtime.scanner.resources.GreetingPostControllerAlt;
import test.io.smallrye.openapi.runtime.scanner.resources.GreetingPutController;
import test.io.smallrye.openapi.runtime.scanner.resources.GreetingPutControllerAlt;
import test.io.smallrye.openapi.runtime.scanner.resources.javax.GreetingPostControllerWithServletContext;
import test.io.smallrye.openapi.runtime.scanner.resources.javax.GreetingPutControllerWithServletContext;

/**
* Basic Spring annotation scanning
Expand Down Expand Up @@ -114,6 +116,44 @@ void testBasicPostSpringDefinitionScanningAlt() throws IOException, JSONExceptio
assertJsonEquals("resource.testBasicSpringPostDefinitionScanning.json", result);
}

/**
* This test a basic, no OpenApi annotations, hello world service
*
* @throws IOException
* @throws JSONException
*/
@Test
void testBasicPostSpringDefinitionScanningWithServletContextJakarta() throws IOException, JSONException {
Index i = indexOf(
test.io.smallrye.openapi.runtime.scanner.resources.jakarta.GreetingPostControllerWithServletContext.class,
Greeting.class);
OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), i);

OpenAPI result = scanner.scan();

printToConsole(result);
assertJsonEquals("resource.testBasicSpringPostDefinitionScanning.json", result);
}

/**
* This test a basic, no OpenApi annotations, hello world service
*
* @throws IOException
* @throws JSONException
*/
@Test
void testBasicPostSpringDefinitionScanningWithServletContextJavax() throws IOException, JSONException {
Index i = indexOf(
test.io.smallrye.openapi.runtime.scanner.resources.javax.GreetingPostControllerWithServletContext.class,
Greeting.class);
OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), i);

OpenAPI result = scanner.scan();

printToConsole(result);
assertJsonEquals("resource.testBasicSpringPostDefinitionScanning.json", result);
}

/**
* This test a basic, no OpenApi annotations, hello world service
*
Expand Down Expand Up @@ -148,6 +188,44 @@ void testBasicPutSpringDefinitionScanningAlt() throws IOException, JSONException
assertJsonEquals("resource.testBasicSpringPutDefinitionScanning.json", result);
}

/**
* This test a basic, no OpenApi annotations, hello world service
*
* @throws IOException
* @throws JSONException
*/
@Test
void testBasicPutSpringDefinitionScanningWithServletContextJakarta() throws IOException, JSONException {
Index i = indexOf(
test.io.smallrye.openapi.runtime.scanner.resources.jakarta.GreetingPutControllerWithServletContext.class,
Greeting.class);
OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), i);

OpenAPI result = scanner.scan();

printToConsole(result);
assertJsonEquals("resource.testBasicSpringPutDefinitionScanning.json", result);
}

/**
* This test a basic, no OpenApi annotations, hello world service
*
* @throws IOException
* @throws JSONException
*/
@Test
void testBasicPutSpringDefinitionScanningWithServletContextJavax() throws IOException, JSONException {
Index i = indexOf(
test.io.smallrye.openapi.runtime.scanner.resources.javax.GreetingPutControllerWithServletContext.class,
Greeting.class);
OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), i);

OpenAPI result = scanner.scan();

printToConsole(result);
assertJsonEquals("resource.testBasicSpringPutDefinitionScanning.json", result);
}

/**
* This test a basic, no OpenApi annotations, hello world service
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package test.io.smallrye.openapi.runtime.scanner.resources.jakarta;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import test.io.smallrye.openapi.runtime.scanner.entities.Greeting;

/**
* Spring.
* Some basic test, comparing with what we get in the JAX-RS version.
* See the GreetingPostResource in the JAX-RS test
*
* @author Phillip Kruger ([email protected])
*/
@RestController
@RequestMapping(value = "/greeting", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public class GreetingPostControllerWithServletContext {

// 1) Basic path var test
@PostMapping("/greet")
public Greeting greet(HttpServletRequest request, HttpServletResponse response, @RequestBody Greeting greeting) {
return greeting;
}

// 2) ResponseEntity without a type specified
@PostMapping("/greetWithResponse")
@APIResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(ref = "#/components/schemas/Greeting")))
public ResponseEntity greetWithResponse(@RequestBody Greeting greeting, HttpServletRequest request,
HttpServletResponse response) {
return ResponseEntity.ok(greeting);
}

// 3) ResponseEntity with a type specified (No JaxRS comparison)
@PostMapping("/greetWithResponseTyped")
public ResponseEntity<Greeting> greetWithResponseTyped(HttpSession session, @RequestBody Greeting greeting) {
return ResponseEntity.ok(greeting);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package test.io.smallrye.openapi.runtime.scanner.resources.jakarta;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import test.io.smallrye.openapi.runtime.scanner.entities.Greeting;

/**
* Spring.
* Some basic test, comparing with what we get in the JAX-RS version.
* See the GreetingPutResource in the JAX-RS test
*
* @author Phillip Kruger ([email protected])
*/
@RestController
@RequestMapping(value = "/greeting", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public class GreetingPutControllerWithServletContext {

// 1) Basic path var test
@PutMapping("/greet/{id}")
public Greeting greet(HttpServletRequest request, HttpServletResponse response, @RequestBody Greeting greeting,
@PathVariable(name = "id") String id) {
return greeting;
}

// 2) ResponseEntity without a type specified
@PutMapping("/greetWithResponse/{id}")
@APIResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(ref = "#/components/schemas/Greeting")))
public ResponseEntity greetWithResponse(@RequestBody Greeting greeting, @PathVariable(name = "id") String id,
HttpServletRequest request, HttpServletResponse response) {
return ResponseEntity.ok(greeting);
}

// 3) ResponseEntity with a type specified (No JaxRS comparison)
@PutMapping("/greetWithResponseTyped/{id}")
public ResponseEntity<Greeting> greetWithResponseTyped(HttpSession session, @RequestBody Greeting greeting,
@PathVariable(name = "id") String id) {
return ResponseEntity.ok(greeting);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package test.io.smallrye.openapi.runtime.scanner.resources.javax;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import test.io.smallrye.openapi.runtime.scanner.entities.Greeting;

/**
* Spring.
* Some basic test, comparing with what we get in the JAX-RS version.
* See the GreetingPostResource in the JAX-RS test
*
* @author Phillip Kruger ([email protected])
*/
@RestController
@RequestMapping(value = "/greeting", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public class GreetingPostControllerWithServletContext {

// 1) Basic path var test
@PostMapping("/greet")
public Greeting greet(HttpServletRequest request, HttpServletResponse response, @RequestBody Greeting greeting) {
return greeting;
}

// 2) ResponseEntity without a type specified
@PostMapping("/greetWithResponse")
@APIResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(ref = "#/components/schemas/Greeting")))
public ResponseEntity greetWithResponse(@RequestBody Greeting greeting, HttpServletRequest request,
HttpServletResponse response) {
return ResponseEntity.ok(greeting);
}

// 3) ResponseEntity with a type specified (No JaxRS comparison)
@PostMapping("/greetWithResponseTyped")
public ResponseEntity<Greeting> greetWithResponseTyped(HttpSession session, @RequestBody Greeting greeting) {
return ResponseEntity.ok(greeting);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package test.io.smallrye.openapi.runtime.scanner.resources.javax;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import test.io.smallrye.openapi.runtime.scanner.entities.Greeting;

/**
* Spring.
* Some basic test, comparing with what we get in the JAX-RS version.
* See the GreetingPutResource in the JAX-RS test
*
* @author Phillip Kruger ([email protected])
*/
@RestController
@RequestMapping(value = "/greeting", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public class GreetingPutControllerWithServletContext {

// 1) Basic path var test
@PutMapping("/greet/{id}")
public Greeting greet(HttpServletRequest request, HttpServletResponse response, @RequestBody Greeting greeting,
@PathVariable(name = "id") String id) {
return greeting;
}

// 2) ResponseEntity without a type specified
@PutMapping("/greetWithResponse/{id}")
@APIResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(ref = "#/components/schemas/Greeting")))
public ResponseEntity greetWithResponse(@RequestBody Greeting greeting, @PathVariable(name = "id") String id,
HttpServletRequest request, HttpServletResponse response) {
return ResponseEntity.ok(greeting);
}

// 3) ResponseEntity with a type specified (No JaxRS comparison)
@PutMapping("/greetWithResponseTyped/{id}")
public ResponseEntity<Greeting> greetWithResponseTyped(HttpSession session, @RequestBody Greeting greeting,
@PathVariable(name = "id") String id) {
return ResponseEntity.ok(greeting);
}
}

0 comments on commit 7a5232b

Please sign in to comment.