Skip to content

Commit

Permalink
Allow setting user-agent via configuration for the Reactive REST Client
Browse files Browse the repository at this point in the history
  • Loading branch information
geoand committed May 11, 2022
1 parent 1d6fc0b commit 1f86733
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class RestClientConfig {
EMPTY.headers = Collections.emptyMap();
EMPTY.shared = Optional.empty();
EMPTY.name = Optional.empty();
EMPTY.userAgent = Optional.empty();
}

/**
Expand Down Expand Up @@ -220,6 +221,14 @@ public class RestClientConfig {
@ConfigItem
public Optional<String> name;

/**
* Configure the HTTP user-agent header to use.
*
* This property is applicable to reactive REST clients only.
*/
@ConfigItem
public Optional<String> userAgent;

public static RestClientConfig load(String configKey) {
final RestClientConfig instance = new RestClientConfig();

Expand Down Expand Up @@ -248,6 +257,7 @@ public static RestClientConfig load(String configKey) {
instance.headers = getConfigValues(configKey, "headers", String.class, String.class);
instance.shared = getConfigValue(configKey, "shared", Boolean.class);
instance.name = getConfigValue(configKey, "name", String.class);
instance.userAgent = getConfigValue(configKey, "user-agent", String.class);

return instance;
}
Expand Down Expand Up @@ -280,6 +290,7 @@ public static RestClientConfig load(Class<?> interfaceClass) {
instance.headers = getConfigValues(interfaceClass, "headers", String.class, String.class);
instance.shared = getConfigValue(interfaceClass, "shared", Boolean.class);
instance.name = getConfigValue(interfaceClass, "name", String.class);
instance.userAgent = getConfigValue(interfaceClass, "user-agent", String.class);

return instance;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,14 @@ public class RestClientsConfig {
@ConfigItem(defaultValue = "false")
public boolean disableContextualErrorMessages;

/**
* Configure the HTTP user-agent header to use.
*
* This property is applicable to reactive REST clients only.
*/
@ConfigItem
public Optional<String> userAgent;

public RestClientConfig getClientConfig(String configKey) {
if (configKey == null) {
return RestClientConfig.EMPTY;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package io.quarkus.rest.client.reactive.headers;

import static org.assertj.core.api.Assertions.assertThat;

import java.net.URI;

import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;

import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.test.common.http.TestHTTPResource;

public class UserAgentFromConfigTest {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar.addClasses(Resource.class, Client.class)
.addAsResource(new StringAsset(
"quarkus.rest-client.user-agent=base\n" +
"quarkus.rest-client.client1.url=http://localhost:${quarkus.http.test-port:8081}\n" +
"quarkus.rest-client.client2.url=http://localhost:${quarkus.http.test-port:8081}\n" +
"quarkus.rest-client.client2.user-agent=specific"),
"application.properties"));

@TestHTTPResource
URI baseUri;

@RestClient
Client client;

@RestClient
Client2 client2;

@Test
void testProgrammaticClient() {
Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class);
assertThat(client.call()).isEqualTo("base");
}

@Test
void testBaseUserAgent() {
assertThat(client.call()).isEqualTo("base");
}

@Test
void testSpecificUserAgent() {
assertThat(client2.call()).isEqualTo("specific");
}

@Path("/")
@ApplicationScoped
public static class Resource {
@GET
public String returnHeaders(@HeaderParam("user-agent") String header) {
return header;
}
}

@RegisterRestClient(configKey = "client1")
public interface Client {

@Path("/")
@GET
String call();
}

@RegisterRestClient(configKey = "client2")
public interface Client2 {

@Path("/")
@GET
String call();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper;
import org.jboss.resteasy.reactive.client.api.InvalidRestClientDefinitionException;
import org.jboss.resteasy.reactive.client.api.LoggingScope;
import org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties;
import org.jboss.resteasy.reactive.client.impl.ClientBuilderImpl;
import org.jboss.resteasy.reactive.client.impl.ClientImpl;
import org.jboss.resteasy.reactive.client.impl.WebTargetImpl;
Expand Down Expand Up @@ -314,6 +315,11 @@ public <T> T build(Class<T> aClass) throws IllegalStateException, RestClientDefi

clientBuilder.trustAll(trustAll);

String userAgent = (String) getConfiguration().getProperty(QuarkusRestClientProperties.USER_AGENT);
if (userAgent != null) {
clientBuilder.setUserAgent(userAgent);
}

if (proxyHost != null) {
configureProxy(proxyHost, proxyPort, proxyUser, proxyPassword, nonProxyHosts);
} else if (restClientsConfig.proxyAddress.isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ private void configureCustomProperties(RestClientBuilder builder) {

builder.property(QuarkusRestClientProperties.DISABLE_CONTEXTUAL_ERROR_MESSAGES,
configRoot.disableContextualErrorMessages);

Optional<String> userAgent = oneOf(clientConfigByClassName().userAgent,
clientConfigByConfigKey().userAgent, configRoot.userAgent);
if (userAgent.isPresent()) {
builder.property(QuarkusRestClientProperties.USER_AGENT, userAgent.get());
}
}

private void configureProxy(RestClientBuilderImpl builder) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public void testGlobalTimeouts() {
configRoot.connectTimeout = 5000L;
configRoot.readTimeout = 10000L;
configRoot.multipartPostEncoderMode = Optional.empty();
configRoot.userAgent = Optional.empty();
RestClientBuilderImpl restClientBuilderMock = Mockito.mock(RestClientBuilderImpl.class);
new RestClientCDIDelegateBuilder<>(TestClient.class,
"http://localhost:8080",
Expand Down Expand Up @@ -142,6 +143,7 @@ private static RestClientsConfig createSampleConfiguration() {
clientConfig.headers = Collections.emptyMap();
clientConfig.shared = Optional.of(true);
clientConfig.name = Optional.of("my-client");
clientConfig.userAgent = Optional.of("rest-client");

RestClientsConfig configRoot = new RestClientsConfig();
configRoot.multipartPostEncoderMode = Optional.of("HTML5");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,6 @@ public class QuarkusRestClientProperties {
*/
public static final String DISABLE_CONTEXTUAL_ERROR_MESSAGES = "io.quarkus.rest.client.disable-contextual-error-messages";

public static final String USER_AGENT = "io.quarkus.rest.client.user-agent";

}

0 comments on commit 1f86733

Please sign in to comment.