Skip to content

Commit

Permalink
Cover bug with rest client hanging on malformed chunks
Browse files Browse the repository at this point in the history
  • Loading branch information
fedinskiy committed Oct 31, 2023
1 parent d9ecdd5 commit 1160898
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 1 deletion.
10 changes: 10 additions & 0 deletions http/rest-client-reactive/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,15 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.wiremock</groupId>
<artifactId>wiremock</artifactId>
<version>3.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-fault-tolerance</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.ts.http.restclient.reactive;

import static java.time.temporal.ChronoUnit.SECONDS;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

import org.eclipse.microprofile.faulttolerance.Timeout;
import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

@RegisterRestClient
@Path("/malformed")
@RegisterClientHeaders
@Timeout(value = 5, unit = SECONDS)
public interface MalformedClient {

@GET
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
String get();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.quarkus.ts.http.restclient.reactive.resources;

import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

import org.eclipse.microprofile.rest.client.inject.RestClient;

import io.quarkus.ts.http.restclient.reactive.MalformedClient;

@Path("/client/malformed")
public class MalformedClientResource {
@Inject
@RestClient
MalformedClient client;

@GET
@Path("/")
public String getMalformed() {
try {
return client.get();
} catch (Exception ex) {
return ex.getClass().getName();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.files.FileClient".ur
quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.BookClient".url=http://localhost:${quarkus.http.port}
quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.BookClient.AuthorClient".url=http://localhost:${quarkus.http.port}
quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.ResourceAndSubResourcesClient".url=http://localhost:${quarkus.http.port}
quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.MalformedClient".url=http://localhost:${quarkus.http.port}

quarkus.rest-client.logging.scope=request-response
quarkus.log.category."org.jboss.resteasy.reactive.client.logging".level=DEBUG
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.ts.http.restclient.reactive;

import static com.github.tomakehurst.wiremock.core.Options.ChunkedEncodingPolicy.NEVER;
import static io.quarkus.ts.http.restclient.reactive.resources.PlainBookResource.SEARCH_TERM_VAL;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
Expand All @@ -8,12 +9,20 @@
import java.util.UUID;

import org.apache.http.HttpStatus;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import com.github.tomakehurst.wiremock.http.Fault;

import io.quarkus.test.bootstrap.Protocol;
import io.quarkus.test.bootstrap.RestService;
import io.quarkus.test.scenarios.QuarkusScenario;
import io.quarkus.test.scenarios.annotations.DisabledOnQuarkusVersion;
import io.quarkus.test.services.QuarkusApplication;
import io.quarkus.ts.http.restclient.reactive.json.Book;
import io.quarkus.ts.http.restclient.reactive.json.BookRepository;
Expand All @@ -23,9 +32,23 @@
public class ReactiveRestClientIT {

private static final String HEMINGWAY_BOOKS = "In Our Time, The Sun Also Rises, A Farewell to Arms, The Old Man and the Sea";
private static WireMockServer mockServer;

static {
mockServer = new WireMockServer(WireMockConfiguration.options()
.dynamicPort()
.useChunkedTransferEncoding(NEVER));
mockServer.stubFor(WireMock.get(WireMock.urlPathMatching("/malformed/"))
.willReturn(WireMock.aResponse().withFault(Fault.MALFORMED_RESPONSE_CHUNK)));

mockServer.start();
}

static final String MALFORMED_URL = "quarkus.rest-client.\"io.quarkus.ts.http.restclient.reactive.MalformedClient\".url";
@QuarkusApplication
static RestService app = new RestService().withProperties("modern.properties");
static RestService app = new RestService()
.withProperties("modern.properties")
.withProperty(MALFORMED_URL, () -> mockServer.baseUrl());

@Test
public void shouldGetBookFromRestClientJson() {
Expand Down Expand Up @@ -226,4 +249,16 @@ public void programmaticRestClient() {
.statusCode(200)
.body(is("The Hobbit: An Unexpected Journey"));
}

@Test
@DisabledOnQuarkusVersion(version = "3\\.2\\.(6|7).*", reason = "Fixed in 3.2.8")
public void malformedChunk() {
Response response = app.given().get("/client/malformed");
Assertions.assertEquals("io.vertx.core.http.HttpClosedException", response.body().asString());
}

@AfterAll
static void afterAll() {
mockServer.stop();
}
}

0 comments on commit 1160898

Please sign in to comment.