InboundHeadersProviderTest.java
/*
* Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.glassfish.jersey.restclient;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import javax.json.Json;
import javax.json.JsonObject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
import org.eclipse.microprofile.rest.client.ext.ClientHeadersFactory;
import org.glassfish.jersey.microprofile.restclient.InboundHeadersProvider;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Tests if {@link InboundHeadersProvider} is called when it is actually needed.
*/
public class InboundHeadersProviderTest extends JerseyTest {
private static final String EXECUTED = "provide-executed";
private static TestClient clientWithoutProvider;
private static TestClient clientWithProvider;
@Override
protected ResourceConfig configure() {
return new ResourceConfig(HeaderProviderTestResource.class);
}
@BeforeAll
public static void clientSetup() {
clientWithoutProvider = RestClientBuilder.newBuilder()
.baseUri(URI.create("http://localhost:9998"))
.build(TestClient.class);
clientWithProvider = RestClientBuilder.newBuilder()
.baseUri(URI.create("http://localhost:9998"))
.register(new TestInboundHeadersProvider())
.build(TestClient.class);
}
@Test
public void providerExecuted() {
JsonObject expected = Json.createObjectBuilder()
.add("executed", true)
.build();
JsonObject jsonObject = clientWithoutProvider.headersProviderExecuted();
assertEquals(expected, jsonObject);
}
@Test
public void providerNotExecuted() {
JsonObject expected = Json.createObjectBuilder()
.add("executed", false)
.build();
JsonObject jsonObject = clientWithoutProvider.headersProviderNotExecuted();
assertEquals(expected, jsonObject);
}
@Path("/")
@RegisterClientHeaders(CustomClientHeadersFactory.class)
public interface TestClient {
@GET
JsonObject object();
@GET
@Path("executed")
JsonObject headersProviderExecuted();
@GET
@Path("notExecuted")
JsonObject headersProviderNotExecuted();
}
@Path("/")
public static final class HeaderProviderTestResource {
@Context
private HttpHeaders headers;
@Context
private ExecutorService executorService;
@GET
public JsonObject object() {
return Json.createObjectBuilder()
.add("executed", headers.getHeaderString(EXECUTED) != null)
.build();
}
@GET
@Path("executed")
public void headersProviderExecuted(@Suspended AsyncResponse response) {
CompletableFuture.supplyAsync(clientWithProvider::object, executorService)
.thenAccept(response::resume)
.exceptionally(t -> {
response.resume(null);
return null;
});
}
@GET
@Path("notExecuted")
public JsonObject headersProviderNotExecuted() {
return clientWithProvider.object();
}
}
public static final class CustomClientHeadersFactory implements ClientHeadersFactory {
public CustomClientHeadersFactory() {
}
@Override
public MultivaluedMap<String, String> update(MultivaluedMap<String, String> incomingHeaders,
MultivaluedMap<String, String> clientOutgoingHeaders) {
MultivaluedMap<String, String> resultHeaders = new MultivaluedHashMap<>();
resultHeaders.putAll(clientOutgoingHeaders);
resultHeaders.putAll(incomingHeaders);
return resultHeaders;
}
}
private static final class TestInboundHeadersProvider implements InboundHeadersProvider {
@Override
public Map<String, List<String>> inboundHeaders() {
Map<String, List<String>> headers = new HashMap<>();
headers.put(EXECUTED, Collections.singletonList("executed"));
return headers;
}
}
}