javadockernetwork-programmingtestcontainersopen-liberty

ProcessingException RESTEASY004655: Testcontainers unable to invoke request to an external REST API service


In my OpenLiberty with Microprofile application, I am using Testcontainers for my integration tests. There is a need for these tests to communicate with an external service by making a POST request to it, get a response back and continue their execution.

When reaching this point, the communication fails with the next exception:

INFO Slf4jLogConsumer.accept:66 STDOUT: 2024-03-10 09:54:36 6e82989c-b1b4-42d3-b121-a970d2958051 ERROR 
GenericHttpClient.callService:165 Exception occurred RESTEASY004655: Unable to invoke request: 
org.apache.http.conn.ConnectTimeoutException: Connect to external-service-url [external-service-url/10.2.38.235] 
failed: Read timed out for url=external-service-url, reqObject={key=someKey, timeToLive=aTimeToLiveValue}

INFO Slf4jLogConsumer.accept:66 STDOUT: jakarta.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: 
org.apache.http.conn.ConnectTimeoutException: Connect to external-service-url [external-service-url/10.2.38.235] 
failed: Read timed out

I tried to send a request to the external service via Postman and it works as expected, but it seems that there is a network issue from my Testcontainers setup which I can't identify. Any suggestions?

I am providing my Testcontainers configuration class for better clarity.

class TestcontainersConfig extends Specification {

    private static final String LIBERTY_CONFIG_BASE_PATH = 'src/main/liberty/config'
    private static final String CONTAINER_CONFIG_BASE_PATH = 'config'

    static Network network = Network.newNetwork()

    @Shared
    Db2Container db2

    @Shared
    GenericContainer openLiberty

    @Shared
    Sql sql

    def setupSpec() {
        db2 = new Db2Container("icr.io/db2_community/db2:latest")
                .withExposedPorts(50000)
                .withNetwork(network)
                .withNetworkAliases("db2alias")
                .acceptLicense()
                .withReuse(true)
                .waitingFor(Wait.forLogMessage(".*All databases are now active.*\\n", 1))
                .withStartupTimeout(Duration.ofMinutes(3))
                .withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("db2")))
        db2.start()
        sql = Sql.newInstance(db2.getJdbcUrl(), db2.getUsername(), db2.getPassword(), db2.getDriverClassName())

        openLiberty = new GenericContainer(DockerImageName.parse("icr.io/appcafe/open-liberty:full-java17-openj9-ubi"))
                .withExposedPorts(9080, 9443)
                .withNetwork(network)
                .withEnv('db.usr', db2.getUsername())
                .withEnv('db.pwd', db2.getPassword())
                .withEnv('db.dbname', db2.getDatabaseName())
                .withEnv('db.host', 'db2alias')
                .withEnv('db.port', '50000')
                .withEnv('jdbc.driver.dir', "/jdbc")
                .withCopyFileToContainer(MountableFile.forHostPath("build/libs/file-name.war"), "${CONTAINER_CONFIG_BASE_PATH}/apps/file-name.war")
                .withCopyFileToContainer(MountableFile.forHostPath("${LIBERTY_CONFIG_BASE_PATH}/server.xml"), "${CONTAINER_CONFIG_BASE_PATH}/server.xml")
                .withCopyFileToContainer(MountableFile.forHostPath("${LIBERTY_CONFIG_BASE_PATH}/cacerts"), "${CONTAINER_CONFIG_BASE_PATH}/cacerts")
                .withCopyFileToContainer(MountableFile.forHostPath("${LIBERTY_CONFIG_BASE_PATH}/db2jcc4.jar"), "/jdbc/db2jcc4.jar")
                .withCopyFileToContainer(MountableFile.forHostPath("${LIBERTY_CONFIG_BASE_PATH}/server.env"), "${CONTAINER_CONFIG_BASE_PATH}/server.env")
                .withCopyFileToContainer(MountableFile.forHostPath("${LIBERTY_CONFIG_BASE_PATH}/bootstrap.properties"), "${CONTAINER_CONFIG_BASE_PATH}/bootstrap.properties")
                .withCopyFileToContainer(MountableFile.forHostPath("${LIBERTY_CONFIG_BASE_PATH}/GeneratedSSLInclude.xml"), "${CONTAINER_CONFIG_BASE_PATH}/GeneratedSSLInclude.xml")
                .withCopyFileToContainer(MountableFile.forHostPath("${LIBERTY_CONFIG_BASE_PATH}/users.xml"), "${CONTAINER_CONFIG_BASE_PATH}/users.xml")
                .waitingFor(Wait.forLogMessage(".*CWWKZ0001I: Application .* started in .* seconds.*", 1)).withStartupTimeout(Duration.ofMinutes(2))
                .withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("openLiberty")))

        openLiberty.start()
    }
}

Solution

  • I managed to solve my problem by creating a custom Network as shown below. I was working via VPN and by default the MTU value for VPN is set to 1350. But my network MTU value was set to 1500 which meant that the packages sent during my request execution were being cut.

    static Network customNetwork = Network.builder()
                .createNetworkCmdModifier({ CreateNetworkCmd createNetworkCmd ->
                    createNetworkCmd.withOptions(['mtu': '1350'] as Map)
                })
                .build()