Настройте JettyTestContainer с SSL для JerseyTest
Мне было поручено настроить интеграционные тесты для кода моей команды. Эти тесты потребуют выполнения HTTPS-запросов к конечным точкам REST, реализованным в Jersey 2.27. В своем поиске того, как выполнить такой тест, я наткнулся на эту статью от Baeldung, которая указала мне на Jersey Test Framework и контейнеры провайдеров, которые они реализовали для этой цели. Я выбрал контейнер Jetty, поскольку в нашем коде для всего этого использовался экземпляр Jetty «сверните свой собственный». Я начал реализацию наших тестов и столкнулся с трудностями при настройке SSL для JettyTestContainer, который будет обслуживать остальные запросы. Я начал получать исключение IllegalArgumentException о том, что «Схема URI должна быть http, когда не используется SSL». Я не понимаю, что делать дальше.
Вот мой тестовый класс:
public class ProjectTest extends JerseyTest {
private SSLContext sslCtx;
@Override
protected Application configure() {
ResourceConfig conf = new ResourceConfig(Sets.newHashSet(RestSuite1.class));
SslConfigurator sslConfig = SslConfigurator.newInstance()
.trustStoreFile()
.trustStorePassword()
.keyStoreFile()
.keyStorePassword()
sslCtx = sslConfig.createSSLContext();
}
@Override
public URI getBaseUri() {
return URI.create("https://localhost:1234")
}
@Override
public Client getClient() {
return ClientBuilder.newBuilder().sslContext(sslCtx).build();
}
@Test
public void test1() throws Exception {
String testString = "HelloWorld";
OurObject oo = target("/restSuite1")
.request()
.post(Entity.entity(testString, MediaType.APPLICATION_JSON), String.class);
}
}
Вот RestSuite1:
@Path("restSuite1")
@Produces("application/json")
public class RestSuite1 {
@POST
@Consumes("application/json")
@Produces("application/json")
public String doSomething(String payload) {
// Do Something
}
}
Вот мой pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>my-application1</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>my war</name>
<url>http://some-url.com</url>
<dependencies>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.27</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.27</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.27</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.27</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.27</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<version>2.27</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-jetty</artifactId>
<version>2.27</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Я должен отметить, что до попытки настройки SSL мне удалось успешно достичь конечной точки POST / restSuite1.
Я нашел этот вопрос , но он не похож на конфигурацию Grizzly SSL, которую можно было бы использовать в сценарии JerseyTest.
Я нашел этот вопрос , но похоже, что это установка ролей пользователей, а не фактическая конфигурация SSL.
Затем я нашел этот вопрос , и у человека, который его задал, похоже, была та же проблема, что и у меня, однако никто так и не ответил на этот вопрос.
Пожалуйста помоги!
Ответы
Похоже, эта опция недоступна в JerseyTest. Я создал пул-реквест, чтобы добавить эту опцию. Пожалуйста, посмотрите здесь:https://github.com/eclipse-ee4j/jersey/pull/4573 Я не совсем уверен, как быстро они его утвердят и опубликуют ...
Я знаю, что это был не тот ответ, который вы ищете ... Однако, если вы все еще хотите настроить свой сервер с помощью ssl и протестировать свое приложение с помощью https, не дожидаясь утверждения запроса на перенос, вы можете взглянуть на мой проект github, который имеет базовый пример тестирования сервера jersey с помощью grizzly без JerseyTest: Application & IntegrationTest
=============== ОБНОВЛЕНИЕ №1 20-12-2020 ===============
Запрос на вытягивание был одобрен, объединен и выпущен. Теперь он доступен, начиная с версии 2.33. Теперь можно предоставить sslcontext с параметрами ssl для настройки теста jersey. Пример настройки:
public class SecuredJerseyTest extends JerseyTest {
@Override
protected TestContainerFactory getTestContainerFactory() {
return new GrizzlyTestContainerFactory();
}
@Path("hello")
public static class TestResource {
@GET
public String hello() {
return "hello";
}
}
@Override
protected Application configure() {
return new ResourceConfig(TestResource.class);
}
@Override
protected URI getBaseUri() {
return UriBuilder
.fromUri("https://localhost")
.port(getPort())
.build();
}
@Override
protected Optional<SSLContext> getSslContext() {
SSLContext sslContext = ... // your initialised server sslContext
return Optional.of(sslContext);
}
@Override
protected Optional<SSLParameters> getSslParameters() {
serverSslParameters = new SSLParameters();
serverSslParameters.setNeedClientAuth(false);
return Optional.of(serverSslParameters);
}
@Test
public void testHello() {
SSLContext sslContext = ... // your initialised client sslContext
Client client = ClientBuilder.newBuilder()
.sslContext(sslContext)
.build();
WebTarget target = client.target(getBaseUri()).path("hello");
String s = target.request().get(String.class);
Assert.assertEquals("hello", s);
}
}