atomikos / transactions-essentials

Development repository for next major release of
https://www.atomikos.com/Main/TransactionsEssentials
Other
462 stars 139 forks source link

Builder for Rest Client of remote-transactions #213

Open martinaubele opened 2 months ago

martinaubele commented 2 months ago

At the moment the REST client for remote-transactions is created inside ParticipantAdapter. It is hard coded to use javax.ws.rs.client.ClientBuilder.

We observed severe performance problems because the Jaxrs default client does not offer a proper http connection handling.

To allow customization we propose to introduce a Builder Pattern:

RestClientBuilder is a new abstract class that is extended by DefaultRestClientBuilder. This one creates the REST Client in the same way as before. You can extend RestClientBuild by your own implementation and define it in the new property com.atomikos.remoting.rest_client_builder.

com.atomikos.remoting.rest_client_builder=MyRestClientBuilderWithHttpCommonsConnectionPooling

Here is an example for REST Client with Http Connection Pooling

public class PooledRestClientBuilder extends RestClientBuilder {

    @Override
    public Client build() {
        ResteasyClientBuilder builder = new ResteasyClientBuilder();

        ConfigProperties configProperties = Configuration.getConfigProperties();
        String connectionPoolSizeProperty = configProperties.getProperty("com.atomikos.remoting.twopc.ParticipantAdapter.connectionPoolSize");
        int connectionPoolSize = 20;
        if (connectionPoolSizeProperty != null)
            connectionPoolSize = Integer.valueOf(connectionPoolSizeProperty);

        String connectTimeoutProperty = configProperties.getProperty("com.atomikos.remoting.twopc.ParticipantAdapter.connectTimeout");
        int connectTimeout = 10;
        if (connectTimeoutProperty != null)
            connectTimeout = Integer.valueOf(connectTimeoutProperty);

        String readTimeoutProperty = configProperties.getProperty("com.atomikos.remoting.twopc.ParticipantAdapter.readTimeout");
        int readTimeout = 60;
        if (readTimeoutProperty != null)
            readTimeout = Integer.valueOf(readTimeoutProperty);

        builder.connectTimeout(connectTimeout, TimeUnit.SECONDS);
        builder.readTimeout(readTimeout, TimeUnit.SECONDS);
        Client c = builder.connectionPoolSize(connectionPoolSize).build(); 
        c.property("jersey.config.client.suppressHttpComplianceValidation", true);
        c.register(ParticipantsProvider.class);
        return c;
    }
}

IMPORTANT: To allow connection pooling it has to be ensured that the content of each response is consumed. Therefore we had the change some code in ParticipantAdapter.

Pull request: https://github.com/atomikos/transactions-essentials/pull/214