Настройте JettyTestContainer с SSL для JerseyTest

Мне поручили настроить интеграционные тесты для кода моей команды. Эти тесты потребуют выполнения HTTPS-запросов к конечным точкам REST, реализованным в Jersey 2.27. В поисках того, как выполнить такой тест, я наткнулся на эту статью от Baeldung, указал мне на инфраструктуру тестирования Джерси и контейнеры поставщиков, которые они внедрили для этой цели. Я выбрал контейнер 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.

Я нашел этот вопрос, но это не похоже на конфигурацию SSL Grizzly, которую можно было бы использовать в сценарии JerseyTest.

Я нашел этот вопрос, но он выглядит как установка ролей пользователей, а не фактический SSL-конфигурация.

Затем я нашел этот вопрос, и человек, который его задал, похоже, имеет ту же проблему, что и я, однако никто так и не ответил на вопрос.

Пожалуйста помоги!


person DivDiff    schedule 16.09.2020    source источник


Ответы (1)


Похоже, эта опция недоступна в JerseyTest. Я создал запрос на включение, чтобы добавить эту опцию. Пожалуйста, посмотрите здесь: https://github.com/eclipse-ee4j/jersey/pull/4573 Я не совсем уверен, как быстро они это одобрят и опубликуют...

Я знаю, что это не тот ответ, который вы ищете ... Однако, если вы все еще хотите настроить свой сервер с помощью ssl и протестировать свое приложение с помощью https, не дожидаясь одобрения запроса на вытягивание, вы можете взглянуть на мой проект github, который имеет базовый пример тестирования сервера джерси с гризли без JerseyTest: Приложение и IntegrationTest

=============== ОБНОВЛЕНИЕ №1 20-12-2020 ===============

Запрос на включение одобрен, объединен и выпущен. Теперь он доступен, начиная с версии 2.33. Теперь можно предоставить контекст sslcontext с параметрами ssl для настройки теста трикотажа. Пример установки:

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);
    }
}
person Hakan54    schedule 21.09.2020
comment
Спасибо за внимание. Я решил удалить тестирование SSL из своих интеграционных тестов. Это слишком хлопотно без встроенной поддержки Джерси. Может быть, я вернусь к этому через несколько месяцев, чтобы посмотреть, добавлено ли это. - person DivDiff; 21.09.2020
comment
Привет @DivDiff Только что добавил обновление к моему первоначальному ответу. PR был объединен, теперь вы можете легко настроить тест на футболку с помощью ssl. Я также включил пример - person Hakan54; 20.12.2020