【问题标题】:Embedded Java HTTPS server for integration testing用于集成测试的嵌入式 Java HTTPS 服务器
【发布时间】:2014-11-27 11:44:14
【问题描述】:

我正在为通过 HTTPS 连接到外部 API 的 Mule ESB 应用程序编写集成测试。我想在 Maven 构建期间模拟外部 API 并运行端到端集成测试。我的问题是关于设置嵌入式 HTTPS 服务器。我试过使用 Jersey,但它只提供 HTTP。我在看这个例子

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

我想知道是否还涉及一些手动步骤,或者它是否可以在每次构建开始时自动设置所有内容。

有什么建议或想法吗?

编辑。我的最终目标是在可通过 HTTPS 访问的嵌入式服务器中部署 JAX-RS 服务。这不需要客户端密钥/证书配置。

编辑 2. 现在我的问题与证书有关。集成测试的重点是模拟外部组件并验证我的应用程序是否正常工作。现在,如果我设置一个嵌入式 HTTPS 服务器并使用命令行构建的证书,我需要在客户端中添加 SSL 配置(正如@Ryan Hoegg 指出的那样)。这不是我理想中想要的:有没有一种解决方案可以在修改我的客户端应用程序代码的情况下让它工作?这应该是一个超越 Mule 的一般 Java 问题。

【问题讨论】:

    标签: java jersey mule grizzly


    【解决方案1】:

    我为此使用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>
    

    我认为某些旧版本的 mule 无法使用这种方法,因为我需要使用解决方法 here

    编辑:只有在使用Spring profile 运行测试时,您才能为 HTTPS 连接器包含此配置:

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

    在测试运行时确保配置文件确实处于活动状态的一种方法是在 @BeforeClass 方法中简单地设置它:

    @BeforeClass
    public void initEnvironment() {
        System.setProperty("spring.profiles.active", "test");
    }
    

    【讨论】:

    • 看起来不错,谢谢。但是,更改客户端(也称为测试的应用程序)代码会稍微破坏集成测试的要点。有没有办法例如通过属性添加该配置,使其只能驻留在测试代码中?请参见上面的 Edit.2。
    • 我也不希望我的应用程序代码需要更改才能运行测试。我为此利用了测试环境。根据您的问题,我假设生产中提供的证书由默认情况下在 JDK 中受信任的 CA 签名。在您的场景中,我只会在运行集成测试时使用弹簧配置文件来包含上面的连接器配置(例如,通过定义系统属性 spring.profiles.active=test)。我已经更新了答案以反映这种方法。
    • 请注意,通过在包含连接器配置的 src/test/resources 中提供单独的 mule 配置文件并将其包含在 getConfigFiles() 中,您可以减少对生产代码的污染。
    • 这正是我目前正在做的事情。尽管完全不改变代码会很好,即根本不必包含单独的测试 xml ;)
    【解决方案2】:

    您引用的示例自动运行。 我能想到的唯一手动部分是创建安全存储(密钥库、信任库)。一旦你有了它们,你就可以像在示例中那样为 Grizzly HttpServer 提供数据。

    【讨论】:

      【解决方案3】:

      如果您愿意嵌入任何其他服务器,请尝试Jetty

      配置见question

      【讨论】:

      • 有没有关于如何配置 Jersey 内置 HTTPS 服务器的示例?基本上使用以下之一:jersey.java.net/documentation/latest/… [Jersey 1.6]
      • @GuidoN 抱歉 Guido,我没有机会使用 Jersey,这就是为什么我指出在您的场景中嵌入 Jetty 服务器(如果您不关心服务器)
      • AFAIK Jersey 具有可插入的架构,如链接所示。这应该意味着我可以使用 Grizzly 或 Jetty。我只是想知道如果我能找到一个 HTTPS Jetty-Jersey 示例:)
      • 对不起,这是我刚刚发布的链接。我需要一个关于如何在嵌入式 HTTPS 服务器中设置 JAX-RS 服务的完整工作示例。
      【解决方案4】:

      您为什么不简单地使用 Mule 来完成这项任务?

      创建一个额外的 Mule XML 文件,通过 HTTPS 公开 JAX-RS 服务。我们的想法是不将其包含在生产代码中(即从 mule-context.xml 引用它),而是从测试用例中加载它。

      您可以将其作为配置与FunctionalTestCase 类中的生产配置并排提交。

      您的模拟服务可能看起来有点像这样(当然不包括提供实际实现的 JAX-RS 注释 bean)。

      <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>
      

      【讨论】:

      • 谢谢。你说得有道理,尽管证书问题仍然存在。请参见上面的 Edit.2。
      • 我通常在集成测试期间使用模拟密钥库,通过依赖注入注入 - 或在集成测试期间切换到 HTTP。
      • 现在的问题是,如何使用 Mockito 使 Mule HTTPS 连接器(“客户端”)“信任一切”?
      • 我已经为此事创建了一个具体问题stackoverflow.com/questions/27255015/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-13
      • 2020-06-09
      • 1970-01-01
      • 2012-10-31
      • 2011-09-30
      • 2010-10-30
      • 1970-01-01
      相关资源
      最近更新 更多