-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
567369d
commit 9e807be
Showing
10 changed files
with
2,423 additions
and
1 deletion.
There are no files selected for viewing
76 changes: 76 additions & 0 deletions
76
...tp-advanced-reactive/src/main/java/io/quarkus/ts/http/advanced/reactive/FootballTeam.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package io.quarkus.ts.http.advanced.reactive; | ||
|
||
import java.util.Date; | ||
import java.util.List; | ||
|
||
public class FootballTeam { | ||
|
||
private String name; | ||
private String colorTShirt; | ||
private int euroCups; | ||
private Date foundationDate; | ||
private String stadium; | ||
private List<String> keyPlayers; | ||
|
||
public FootballTeam() { | ||
} | ||
|
||
public FootballTeam(String name, String colorTShirt, int euroCups, Date foundationDate, String stadium, | ||
List<String> keyPlayers) { | ||
this.name = name; | ||
this.colorTShirt = colorTShirt; | ||
this.euroCups = euroCups; | ||
this.foundationDate = foundationDate; | ||
this.stadium = stadium; | ||
this.keyPlayers = keyPlayers; | ||
} | ||
|
||
public Date getFoundationDate() { | ||
return foundationDate; | ||
} | ||
|
||
public void setFoundationDate(Date foundationDate) { | ||
this.foundationDate = foundationDate; | ||
} | ||
|
||
public String getStadium() { | ||
return stadium; | ||
} | ||
|
||
public void setStadium(String stadium) { | ||
this.stadium = stadium; | ||
} | ||
|
||
public List<String> getKeyPlayers() { | ||
return keyPlayers; | ||
} | ||
|
||
public void setKeyPlayers(List<String> keyPlayers) { | ||
this.keyPlayers = keyPlayers; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public void setName(String name) { | ||
this.name = name; | ||
} | ||
|
||
public String getColorTShirt() { | ||
return colorTShirt; | ||
} | ||
|
||
public void setColorTShirt(String colorTShirt) { | ||
this.colorTShirt = colorTShirt; | ||
} | ||
|
||
public int getEuroCups() { | ||
return euroCups; | ||
} | ||
|
||
public void setEuroCups(int euroCups) { | ||
this.euroCups = euroCups; | ||
} | ||
|
||
} |
93 changes: 93 additions & 0 deletions
93
...ced-reactive/src/main/java/io/quarkus/ts/http/advanced/reactive/FootballTeamResource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package io.quarkus.ts.http.advanced.reactive; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.Date; | ||
import java.util.HashMap; | ||
import java.util.LinkedHashSet; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
import jakarta.ws.rs.Consumes; | ||
import jakarta.ws.rs.GET; | ||
import jakarta.ws.rs.POST; | ||
import jakarta.ws.rs.Path; | ||
import jakarta.ws.rs.Produces; | ||
import jakarta.ws.rs.core.MediaType; | ||
import jakarta.ws.rs.core.Response; | ||
|
||
import org.jboss.logging.Logger; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.core.type.TypeReference; | ||
import com.fasterxml.jackson.databind.JsonMappingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import io.smallrye.mutiny.Uni; | ||
|
||
@Path("/resource") | ||
public class FootballTeamResource { | ||
|
||
private static final Logger LOG = Logger.getLogger(FootballTeamResource.class); | ||
|
||
private Set<FootballTeam> footballTeamSet = Collections.synchronizedSet(new LinkedHashSet<>()); | ||
|
||
public FootballTeamResource() { | ||
footballTeamSet.add(new FootballTeam("Norway", "Red", 0, new Date(1920, 6, 1), "Oslo Stadium", | ||
Arrays.asList("Ole Gunnar Solskjær", "Joshua King"))); | ||
} | ||
|
||
/** | ||
* | ||
* When a JSON extension is installed such as quarkus-rest-jackson or quarkus-rest-jsonb | ||
* Quarkus will use the application/json media type by default for most return values | ||
*/ | ||
@GET | ||
public Response list() { | ||
return Response.ok(footballTeamSet).build(); | ||
} | ||
|
||
@POST | ||
@Path("/upload-football-json") | ||
@Consumes(MediaType.APPLICATION_JSON) | ||
@Produces(MediaType.APPLICATION_JSON) | ||
public Uni<Response> uploadFootballJson(String data) { | ||
try { | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
Set<FootballTeam> teamSet = objectMapper.readValue(data, new TypeReference<Set<FootballTeam>>() { | ||
}); | ||
for (FootballTeam footballTeam : teamSet) { | ||
if (footballTeam == null || footballTeam.getName().isEmpty()) { | ||
return Uni.createFrom().item(Response.status(400).entity("Some fields are empty or null").build()); | ||
} else { | ||
footballTeamSet.add(footballTeam); | ||
} | ||
} | ||
return Uni.createFrom() | ||
.item(() -> { | ||
Map<String, Object> responseMap = new HashMap<>(); | ||
responseMap.put("teams", footballTeamSet); | ||
responseMap.put("message", "Teams added successfully"); | ||
return Response.status(201).entity(responseMap).build(); | ||
}); | ||
} catch (JsonMappingException ex) { | ||
LOG.error(ex.getMessage()); | ||
return Uni.createFrom() | ||
.item(Response.status(400).entity("JsonMappingException : " + ex.getMessage()).build()); | ||
} catch (JsonProcessingException e) { | ||
LOG.error(e.getMessage()); | ||
return Uni.createFrom().item( | ||
Response.status(400).entity("Invalid JSON - JsonProcessingException : " + e.getOriginalMessage()).build()); | ||
} | ||
|
||
} | ||
|
||
@POST | ||
@Path("/process-json") | ||
@Consumes(MediaType.APPLICATION_JSON) | ||
@Produces(MediaType.APPLICATION_JSON) | ||
public Uni<Response> processJson(String jsonData) { | ||
return Uni.createFrom().item(() -> Response.ok().entity(jsonData).build()); | ||
} | ||
|
||
} |
184 changes: 184 additions & 0 deletions
184
...p-advanced-reactive/src/test/java/io/quarkus/ts/http/advanced/reactive/JsonPayloadIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
package io.quarkus.ts.http.advanced.reactive; | ||
|
||
import static io.restassured.RestAssured.given; | ||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.Matchers.containsString; | ||
import static org.hamcrest.Matchers.is; | ||
|
||
import java.io.IOException; | ||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.Paths; | ||
import java.util.Arrays; | ||
import java.util.Date; | ||
|
||
import org.apache.commons.io.FileUtils; | ||
import org.junit.jupiter.api.MethodOrderer; | ||
import org.junit.jupiter.api.Order; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.TestMethodOrder; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import io.quarkus.test.bootstrap.RestService; | ||
import io.quarkus.test.scenarios.QuarkusScenario; | ||
import io.quarkus.test.services.QuarkusApplication; | ||
import io.restassured.http.ContentType; | ||
import io.restassured.response.Response; | ||
|
||
@QuarkusScenario | ||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) | ||
public class JsonPayloadIT { | ||
|
||
@QuarkusApplication(classes = { FootballTeamResource.class, FootballTeam.class | ||
}, properties = "oidcdisable.properties") | ||
static RestService app = new RestService(); | ||
|
||
@Test | ||
@Order(1) | ||
public void sendSuccessfulJSONPayloadFromAFile() throws IOException { | ||
|
||
String jsonPayload = FileUtils.readFileToString( | ||
Paths.get("src", "test", "resources", "football-teams.json").toFile(), | ||
StandardCharsets.UTF_8); | ||
|
||
Response response = given() | ||
.contentType(ContentType.JSON) | ||
.body(jsonPayload) | ||
.when() | ||
.post("/resource/upload-football-json") | ||
.then() | ||
.statusCode(201) | ||
.body("teams.size()", is(27)) | ||
.extract().response(); | ||
assertThat(response.body().asString(), containsString("Teams added successfully")); | ||
|
||
} | ||
|
||
@Test | ||
public void sendLargeComplexJSONPayload() throws IOException { | ||
String jsonPayload = FileUtils.readFileToString( | ||
Paths.get("src", "test", "resources", "big_sample.json").toFile(), | ||
StandardCharsets.UTF_8); | ||
|
||
Response response = given() | ||
.contentType(ContentType.JSON) | ||
.body(jsonPayload) | ||
.when() | ||
.post("/resource/process-json") | ||
.then() | ||
.statusCode(jakarta.ws.rs.core.Response.Status.OK.getStatusCode()) | ||
.extract().response(); | ||
assertThat(response.body().asString(), containsString("Hello, Singleton Middleton! You have 4 unread messages.")); | ||
} | ||
|
||
@Test | ||
public void sendJSONWithEmptyFieldsPayload() throws IOException { | ||
String jsonPayload = FileUtils.readFileToString( | ||
Paths.get("src", "test", "resources", "football-empty-teams.json").toFile(), | ||
StandardCharsets.UTF_8); | ||
|
||
Response response = given() | ||
.contentType(ContentType.JSON) | ||
.body(jsonPayload) | ||
.when() | ||
.post("/resource/upload-football-json") | ||
.then() | ||
.statusCode(jakarta.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode()) | ||
.extract().response(); | ||
|
||
assertThat(response.body().asString(), containsString("Some fields are empty or null")); | ||
} | ||
|
||
@Test | ||
public void sendInvalidJSONPayload() throws IOException { | ||
String jsonPayload = FileUtils.readFileToString( | ||
Paths.get("src", "test", "resources", "football-teams_invalid.json").toFile(), | ||
StandardCharsets.UTF_8); | ||
|
||
Response response = given() | ||
.contentType(ContentType.JSON) | ||
.body(jsonPayload) | ||
.when() | ||
.post("/resource/upload-football-json") | ||
.then() | ||
.statusCode(jakarta.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode()) | ||
.extract().response(); | ||
|
||
assertThat(response.body().asString(), containsString( | ||
"Invalid JSON - JsonProcessingException : Unexpected character ('{' (code 123)): was expecting comma to separate Array entries")); | ||
} | ||
|
||
@Test | ||
public void sendASingleJSONObject() throws JsonProcessingException { | ||
FootballTeam teamX = new FootballTeam( | ||
"Single Team", | ||
"Pink", | ||
3, | ||
new Date(1900, 1, 1), | ||
"A", | ||
Arrays.asList("You", "You")); | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
String jsonPayload = objectMapper.writeValueAsString(teamX); | ||
|
||
Response response = given() | ||
.contentType(ContentType.JSON) | ||
.body(jsonPayload) | ||
.when() | ||
.post("/resource/upload-football-json") | ||
.then() | ||
.statusCode(400) | ||
.extract().response(); | ||
assertThat(response.body().asString(), containsString( | ||
"JsonMappingException : Cannot deserialize value of type `java.util.HashSet<io.quarkus.ts.http.advanced.reactive.FootballTeam>`")); | ||
} | ||
|
||
@Test | ||
public void sendIncorrectContentType() throws IOException { | ||
String jsonPayload = FileUtils.readFileToString( | ||
Paths.get("src", "test", "resources", "football-teams.json").toFile(), | ||
StandardCharsets.UTF_8); | ||
|
||
given() | ||
.contentType(ContentType.TEXT) | ||
.body(jsonPayload) | ||
.when() | ||
.post("/resource/upload-football-json") | ||
.then() | ||
.statusCode(415); | ||
|
||
} | ||
|
||
@Test | ||
public void sendSpecialCharactersJSONPayload() throws Exception { | ||
FootballTeam team1 = new FootballTeam( | ||
"Føøbåll™ Tëâm", | ||
"Rëd&Blüé", | ||
3, | ||
new Date(1900, 1, 1), | ||
"Städiümß©", | ||
Arrays.asList("Pläÿér Ône", "Pläÿér Twø´ñ")); | ||
|
||
FootballTeam team2 = new FootballTeam( | ||
"Tëâm 2", | ||
"Grëèn&Yëllöw", | ||
2, | ||
new Date(2010, 1, 15), | ||
"New Städiüm©", | ||
Arrays.asList("Pläÿér Thrëéñ", "Pläÿér Fòur")); | ||
|
||
ObjectMapper objectMapper = new ObjectMapper(); | ||
String jsonPayload = objectMapper.writeValueAsString(Arrays.asList(team1, team2)); | ||
|
||
Response response = given() | ||
.contentType(ContentType.JSON) | ||
.body(jsonPayload) | ||
.when() | ||
.post("/resource/upload-football-json") | ||
.then() | ||
.statusCode(201) | ||
.extract().response(); | ||
|
||
assertThat(response.body().asString(), containsString("Teams added successfully")); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
...d-reactive/src/test/java/io/quarkus/ts/http/advanced/reactive/OpenShiftJsonPayloadIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package io.quarkus.ts.http.advanced.reactive; | ||
|
||
import io.quarkus.test.scenarios.OpenShiftScenario; | ||
|
||
@OpenShiftScenario | ||
public class OpenShiftJsonPayloadIT extends JsonPayloadIT{ | ||
} |
Oops, something went wrong.