Встроенный Java HTTPS-сервер для интеграционного тестирования

Я пишу интеграционные тесты для приложения Mule ESB, которое подключается к внешнему API через HTTPS. Я хотел бы смоделировать внешний API и запустить сквозной интеграционный тест во время сборки Maven. Мой вопрос касается настройки встроенного HTTPS-сервера. Я пытался использовать Джерси, но он обеспечивает только HTTP. Я смотрел на этот пример

https://github.com/jersey/jersey/tree/master/examples/https-clientserver-grizzly

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

Любые предложения или идеи?

Редактировать. Моя конечная цель — развернуть службу JAX-RS на встроенном сервере, доступном через HTTPS. И для этого не требуется настройка ключей/сертификата на стороне клиента.

Редактировать 2. Теперь моя проблема касается сертификатов. Смысл интеграционных тестов — имитировать внешние компоненты и проверять, работает ли мое приложение. Теперь, если я настрою встроенный HTTPS-сервер и использую встроенный сертификат cmd-line, мне нужно добавить конфигурацию SSL в клиенте (как указал @Ryan Hoegg). Это не то, что я хотел бы в идеале: есть ли решение, позволяющее заставить его работать без необходимости изменять код моего клиентского приложения? Это должен быть общий вопрос о Java, выходящий за рамки Mule.


person Guido    schedule 27.11.2014    source источник


Ответы (4)


Для этого я использую https://github.com/Confluex/confluex-mock-http. Под капотом используется Jetty, но он выполняет всю настройку за вас. Создание MockHttpsServer немедленно запускает HTTPS-сервер:

public static final int PORT = 1443;
private MockHttpsServer mockServer;

@Before
public void initHttps() {
    mockServer = new MockHttpsServer(PORT);
    mockServer.respondTo(get("a-service/resource")).withBody(expectedResponse);
}

Вы можете настроить приложение Mule так, чтобы оно доверяло сертификату, используемому фиктивным сервером. Хранилище доверенных сертификатов в формате JKS доступно в пути к классам, и вы можете предоставить его своему коннектору HTTPS следующим образом:

<https:connector name="someHttpsConnector">
    <https:tls-server path="confluex-mock.truststore" storePassword="confluex" />
</https:connector>

Я думаю, что у некоторых старых версий мулов есть проблемы с этим подходом, потому что мне нужно было использовать обходной путь здесь.

РЕДАКТИРОВАТЬ: вы можете включить эту конфигурацию для соединителя HTTPS, только когда тесты выполняются с использованием весенний профиль:

<spring:beans profile="test">
    <mule>
        <!-- connector configuration goes here -->
    </mule>
</spring:beans>

Один из способов убедиться, что профиль действительно активен во время выполнения тестов, — просто установить его в методе @BeforeClass:

@BeforeClass
public void initEnvironment() {
    System.setProperty("spring.profiles.active", "test");
}
person Ryan Hoegg    schedule 28.11.2014
comment
Это выглядит красиво, спасибо. Однако изменение кода клиента (т. е. тестируемого приложения) немного снижает смысл интеграционного тестирования. Есть ли способ, например. добавить эту конфигурацию через свойства, чтобы она могла находиться только в коде тестирования? См. Edit.2 выше. - person Guido; 01.12.2014
comment
Я также не хочу, чтобы код моего приложения требовал изменений для запуска тестов. Для этого я использую тестовую среду. Основываясь на вашем вопросе, я предполагаю, что сертификат, представленный в производстве, подписан ЦС, которому по умолчанию доверяют в JDK. В вашем сценарии я бы использовал профиль Spring, чтобы включить указанную выше конфигурацию соединителя только при выполнении интеграционных тестов (например, путем определения системного свойства spring.profiles.active=test). Я обновил ответ, чтобы отразить этот подход. - person Ryan Hoegg; 02.12.2014
comment
Обратите внимание, что вы можете еще меньше загрязнить свой производственный код, предоставив отдельный файл конфигурации мула в src/test/resources, содержащий конфигурацию коннектора и включив его в getConfigFiles(). - person Ryan Hoegg; 02.12.2014
comment
Это именно то, что я делаю в данный момент. Хотя было бы неплохо оставить код полностью нетронутым, т.е. вообще не включать отдельный тестовый xml ;) - person Guido; 02.12.2014
comment
Речь идет о выдающемся бите stackoverflow .com/questions/27255015/ - person Guido; 02.12.2014

Пример, на который вы ссылаетесь, работает автоматически. Единственная ручная часть, о которой я могу думать, это создание хранилищ безопасности (хранилище ключей, хранилище доверенных сертификатов). Получив их, вы можете скормить Grizzly HttpServer так же, как это сделано в примере.

person alexey    schedule 28.11.2014

Если вы хотите встроить любой другой сервер, попробуйте Jetty.

Для настройки см. этот вопрос

person dasrohith    schedule 27.11.2014
comment
Есть ли пример настройки встроенного HTTPS-сервера в Джерси? В основном используется одно из следующего: jersey.java.net/documentation/latest / [Джерси 1.6] - person Guido; 27.11.2014
comment
@GuidoN Извините, Гвидо, у меня не было возможности использовать Джерси, поэтому я указал встроить сервер Jetty в ваш сценарий (если вас не беспокоит сервер) - person dasrohith; 27.11.2014
comment
Как показывает ссылка, Джерси AFAIK имеет подключаемую архитектуру. Что должно означать, что я могу использовать Grizzly или Jetty. Мне просто интересно, смогу ли я найти пример HTTPS Jetty-Jersey :) - person Guido; 27.11.2014
comment
проверьте этот URL-адрес jersey.java.net/documentation/latest/ - person dasrohith; 27.11.2014
comment
Извините, это ссылка, которую я только что разместил. Мне нужен полный рабочий пример того, как настроить службу JAX-RS на встроенном HTTPS-сервере. - person Guido; 27.11.2014
comment
@GuidoN Извините, я этого не видел. Проверьте ответ для этого SO вопрос. Надеюсь это поможет - person dasrohith; 28.11.2014

Почему бы вам просто не использовать Mule для этой задачи?

Создайте дополнительный XML-файл Mule, который предоставляет службу JAX-RS через HTTPS. Идея состоит в том, чтобы не включать это в производственный код (т. е. ссылаться на него из mule-context.xml), а загружать его из тестового примера.

Вы можете отправить его в качестве конфигурации параллельно с рабочей конфигурацией в FunctionalTestCase.

Ваш фиктивный сервис может выглядеть примерно так (за исключением аннотированного компонента JAX-RS, который, конечно, обеспечивает реальную реализацию).

<flow name="mock-service">
    <https:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8085" path="mockapi"/>
    <jersey:resources>
        <component>
            <spring-object bean="mockApiBean"/>
        </component>
    </jersey:resources>
</flow>
person Petter Nordlander    schedule 01.12.2014
comment
Спасибо. Вы правы, хотя проблема с сертификатами осталась. См. Edit.2 выше. - person Guido; 01.12.2014
comment
Обычно я использую фиктивное хранилище ключей во время интеграционного тестирования, внедряю через внедрение зависимостей или переключаюсь на HTTP во время интеграционного теста. - person Petter Nordlander; 01.12.2014
comment
Теперь вопрос будет заключаться в том, как сделать коннектор Mule HTTPS (клиент), чтобы доверять всему, используя Mockito? - person Guido; 02.12.2014
comment
Я создал специальный вопрос по этому поводу сертификаты"> stackoverflow.com/questions/27255015/ - person Guido; 02.12.2014