• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TrueLayer / truelayer-java / #101

13 Jan 2025 11:16AM UTC coverage: 89.888% (-0.7%) from 90.566%
#101

push

github

web-flow
[ACL-264] CI, dependencies, example project and changelog updates (#338)

480 of 534 relevant lines covered (89.89%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.31
/src/main/java/com/truelayer/java/TrueLayerClientBuilder.java
1
package com.truelayer.java;
2

3
import static org.apache.commons.lang3.ObjectUtils.isEmpty;
4
import static org.apache.commons.lang3.ObjectUtils.isNotEmpty;
5

6
import com.truelayer.java.auth.AuthenticationHandler;
7
import com.truelayer.java.auth.IAuthenticationHandler;
8
import com.truelayer.java.commonapi.CommonHandler;
9
import com.truelayer.java.commonapi.ICommonApi;
10
import com.truelayer.java.commonapi.ICommonHandler;
11
import com.truelayer.java.entities.RequestScopes;
12
import com.truelayer.java.hpp.IHostedPaymentPageLinkBuilder;
13
import com.truelayer.java.http.OkHttpClientFactory;
14
import com.truelayer.java.http.RetrofitFactory;
15
import com.truelayer.java.http.auth.cache.ICredentialsCache;
16
import com.truelayer.java.http.auth.cache.SimpleCredentialsCache;
17
import com.truelayer.java.http.interceptors.logging.DefaultLogConsumer;
18
import com.truelayer.java.mandates.IMandatesApi;
19
import com.truelayer.java.mandates.IMandatesHandler;
20
import com.truelayer.java.mandates.MandatesHandler;
21
import com.truelayer.java.merchantaccounts.IMerchantAccountsApi;
22
import com.truelayer.java.merchantaccounts.IMerchantAccountsHandler;
23
import com.truelayer.java.merchantaccounts.MerchantAccountsHandler;
24
import com.truelayer.java.payments.IPaymentsApi;
25
import com.truelayer.java.payments.IPaymentsHandler;
26
import com.truelayer.java.payments.PaymentsHandler;
27
import com.truelayer.java.paymentsproviders.IPaymentsProvidersApi;
28
import com.truelayer.java.paymentsproviders.IPaymentsProvidersHandler;
29
import com.truelayer.java.paymentsproviders.PaymentsProvidersHandler;
30
import com.truelayer.java.payouts.IPayoutsApi;
31
import com.truelayer.java.payouts.IPayoutsHandler;
32
import com.truelayer.java.payouts.PayoutsHandler;
33
import com.truelayer.java.signupplus.ISignupPlusApi;
34
import com.truelayer.java.signupplus.ISignupPlusHandler;
35
import com.truelayer.java.signupplus.SignupPlusHandler;
36
import com.truelayer.java.versioninfo.LibraryInfoLoader;
37
import java.time.Clock;
38
import java.time.Duration;
39
import java.util.concurrent.ExecutorService;
40
import java.util.function.Consumer;
41
import okhttp3.OkHttpClient;
42

43
/**
44
 * Builder class for TrueLayerClient instances.
45
 */
46
public class TrueLayerClientBuilder {
47
    private ClientCredentials clientCredentials;
48

49
    private RequestScopes globalScopes;
50

51
    private SigningOptions signingOptions;
52

53
    /**
54
     * Optional timeout configuration that defines a time limit for a complete HTTP call.
55
     * This includes resolving DNS, connecting, writing the request body, server processing, as well as
56
     * reading the response body. If not set, the internal HTTP client configuration are used.
57
     */
58
    private Duration timeout;
59

60
    /**
61
     * Optional configuration for internal connection pool.
62
     */
63
    private ConnectionPoolOptions connectionPoolOptions;
64

65
    /**
66
     * Optional execution service to be used by the internal HTTP client.
67
     */
68
    private ExecutorService requestExecutor;
69

70
    // By default, production is used
71
    private Environment environment = Environment.live();
1✔
72

73
    private Consumer<String> logMessageConsumer;
74

75
    private ICredentialsCache credentialsCache;
76

77
    private ProxyConfiguration proxyConfiguration;
78

79
    TrueLayerClientBuilder() {}
1✔
80

81
    /**
82
     * Utility to set the client credentials required for Oauth2 protected endpoints.
83
     * @param credentials the credentials object that holds client id and secret.
84
     * @return the instance of the client builder used.
85
     * @see ClientCredentials
86
     */
87
    public TrueLayerClientBuilder clientCredentials(ClientCredentials credentials) {
88
        this.clientCredentials = credentials;
1✔
89
        return this;
1✔
90
    }
91

92
    /**
93
     * Utility to set the signing options required for payments.
94
     * @param signingOptions the signing options object that holds signature related information.
95
     * @return the instance of the client builder used.
96
     * @see SigningOptions
97
     */
98
    public TrueLayerClientBuilder signingOptions(SigningOptions signingOptions) {
99
        this.signingOptions = signingOptions;
1✔
100
        return this;
1✔
101
    }
102

103
    /**
104
     * Utility to set custom global scopes used by the library. If used, the specified scopes will override the
105
     * default scopes used by the library. If using this option, make sure to set valid scopes for all the API interactions
106
     * that your integration will have.
107
     * @param globalScopes custom global scopes to be used by the library for all authenticated endpoints.
108
     * @return the instance of the client builder used.
109
     */
110
    public TrueLayerClientBuilder withGlobalScopes(RequestScopes globalScopes) {
111
        this.globalScopes = globalScopes;
×
112
        return this;
×
113
    }
114

115
    /**
116
     * Utility to set a call timeout for the client.
117
     * @param timeout Optional timeout configuration that defines a time limit for a complete HTTP call.
118
     * This includes resolving DNS, connecting, writing the request body, server processing, as well as
119
     * reading the response body. If not set, the internal HTTP client configuration are used.
120
     * @return the instance of the client builder used.
121
     */
122
    public TrueLayerClientBuilder withTimeout(Duration timeout) {
123
        this.timeout = timeout;
×
124
        return this;
×
125
    }
126

127
    /**
128
     * Sets a connection pool for the internal HTTP client
129
     * @param connectionPoolOptions optional connection pool to be used
130
     * @return the instance of the client builder used.
131
     */
132
    public TrueLayerClientBuilder withConnectionPool(ConnectionPoolOptions connectionPoolOptions) {
133
        this.connectionPoolOptions = connectionPoolOptions;
×
134
        return this;
×
135
    }
136

137
    /**
138
     * Sets a custom HTTP request dispatcher for the internal HTTP client
139
     * @param requestExecutor an executor service responsible for handling the HTTP requests
140
     * @return the instance of the client builder used.
141
     */
142
    public TrueLayerClientBuilder withRequestExecutor(ExecutorService requestExecutor) {
143
        this.requestExecutor = requestExecutor;
×
144
        return this;
×
145
    }
146

147
    /**
148
     * Utility to configure the library to interact a specific <i>TrueLayer</i> environment.
149
     * By default, <i>TrueLayer</i> production environment is used.
150
     * @param environment the environment to use
151
     * @return the instance of the client builder used.
152
     * @see Environment
153
     */
154
    public TrueLayerClientBuilder environment(Environment environment) {
155
        this.environment = environment;
×
156
        return this;
×
157
    }
158

159
    /**
160
     * Utility to enable default logs for HTTP traces.
161
     * @return the instance of the client builder used
162
     */
163
    public TrueLayerClientBuilder withHttpLogs() {
164
        this.logMessageConsumer = new DefaultLogConsumer();
1✔
165
        return this;
1✔
166
    }
167

168
    /**
169
     * Utility to enable custom logging for HTTP traces. Please notice that blocking
170
     * in the context of this consumer invocation will affect performance. An asynchronous implementation is
171
     * strongly advised.
172
     * @param logConsumer a custom log consumer
173
     * @return the instance of the client builder used
174
     */
175
    public TrueLayerClientBuilder withHttpLogs(Consumer<String> logConsumer) {
176
        this.logMessageConsumer = logConsumer;
1✔
177
        return this;
1✔
178
    }
179

180
    /**
181
     * Utility to enable default in memory caching for Oauth credentials.
182
     * @return the instance of the client builder used
183
     */
184
    public TrueLayerClientBuilder withCredentialsCaching() {
185
        this.credentialsCache = new SimpleCredentialsCache(Clock.systemUTC());
1✔
186
        return this;
1✔
187
    }
188

189
    /**
190
     * Utility to enable a custom cache for Oauth credentials.
191
     * @return the instance of the client builder used
192
     */
193
    public TrueLayerClientBuilder withCredentialsCaching(ICredentialsCache credentialsCache) {
194
        this.credentialsCache = credentialsCache;
1✔
195
        return this;
1✔
196
    }
197

198
    /**
199
     * Utility to configure a custom proxy, optionally including an authentication.
200
     * @param proxyConfiguration the configuration describing the custom proxy
201
     * @return the instance of the client builder used
202
     */
203
    public TrueLayerClientBuilder withProxyConfiguration(ProxyConfiguration proxyConfiguration) {
204
        this.proxyConfiguration = proxyConfiguration;
×
205
        return this;
×
206
    }
207

208
    /**
209
     * Builds the Java library main class to interact with TrueLayer APIs.
210
     * @return a client instance
211
     * @see TrueLayerClient
212
     */
213
    public TrueLayerClient build() {
214
        if (isEmpty(clientCredentials)) {
1✔
215
            throw new TrueLayerException("client credentials must be set");
1✔
216
        }
217

218
        OkHttpClientFactory httpClientFactory = new OkHttpClientFactory(new LibraryInfoLoader());
1✔
219

220
        OkHttpClient baseHttpClient = httpClientFactory.buildBaseApiClient(
1✔
221
                timeout, connectionPoolOptions, requestExecutor, logMessageConsumer, proxyConfiguration);
222

223
        OkHttpClient authServerApiHttpClient =
1✔
224
                httpClientFactory.buildAuthServerApiClient(baseHttpClient, clientCredentials);
1✔
225

226
        IAuthenticationHandler authenticationHandler = AuthenticationHandler.New()
1✔
227
                .clientCredentials(clientCredentials)
1✔
228
                .httpClient(RetrofitFactory.build(authServerApiHttpClient, environment.getAuthApiUri()))
1✔
229
                .build();
1✔
230

231
        IHostedPaymentPageLinkBuilder hppLinkBuilder = com.truelayer.java.hpp.HostedPaymentPageLinkBuilder.New()
1✔
232
                .uri(environment.getHppUri())
1✔
233
                .build();
1✔
234

235
        // We're reusing a client with only User agent and Idempotency key interceptors and give it our base payment
236
        // endpoint
237
        ICommonApi commonApi = RetrofitFactory.build(authServerApiHttpClient, environment.getPaymentsApiUri())
1✔
238
                .create(ICommonApi.class);
1✔
239
        ICommonHandler commonHandler = new CommonHandler(commonApi);
1✔
240

241
        // We're building a client which has the authentication handler and the options to cache the token.
242
        // this one represents the baseline for the client used for Signup+ and Payments
243
        OkHttpClient authenticatedApiClient = httpClientFactory.buildAuthenticatedApiClient(
1✔
244
                authServerApiHttpClient, authenticationHandler, credentialsCache);
245
        ISignupPlusApi signupPlusApi = RetrofitFactory.build(authenticatedApiClient, environment.getPaymentsApiUri())
1✔
246
                .create(ISignupPlusApi.class);
1✔
247
        SignupPlusHandler.SignupPlusHandlerBuilder signupPlusHandlerBuilder =
248
                SignupPlusHandler.builder().signupPlusApi(signupPlusApi);
1✔
249
        if (customScopesPresent()) {
1✔
250
            signupPlusHandlerBuilder.scopes(globalScopes);
×
251
        }
252
        ISignupPlusHandler signupPlusHandler = signupPlusHandlerBuilder.build();
1✔
253

254
        // As per our RFC, if signing options is not configured we create a client which is able to interact
255
        // with the Authentication API only
256
        if (isEmpty(signingOptions)) {
1✔
257
            return new TrueLayerClient(
1✔
258
                    authenticationHandler,
259
                    hppLinkBuilder,
260
                    commonHandler,
261
                    signupPlusHandler,
262
                    new HostedPaymentPageLinkBuilder(environment));
263
        }
264

265
        // The client used for PayIn endpoints has the authenticated as baseline, but adds the signature manager
266
        OkHttpClient paymentsHttpClient =
1✔
267
                httpClientFactory.buildPaymentsApiClient(authenticatedApiClient, signingOptions);
1✔
268

269
        IPaymentsApi paymentsApi = RetrofitFactory.build(paymentsHttpClient, environment.getPaymentsApiUri())
1✔
270
                .create(IPaymentsApi.class);
1✔
271

272
        PaymentsHandler.PaymentsHandlerBuilder paymentsHandlerBuilder =
273
                PaymentsHandler.builder().paymentsApi(paymentsApi);
1✔
274
        if (customScopesPresent()) {
1✔
275
            paymentsHandlerBuilder.scopes(globalScopes);
×
276
        }
277
        IPaymentsHandler paymentsHandler = paymentsHandlerBuilder.build();
1✔
278

279
        IPaymentsProvidersApi paymentsProvidersApi = RetrofitFactory.build(
1✔
280
                        paymentsHttpClient, environment.getPaymentsApiUri())
1✔
281
                .create(IPaymentsProvidersApi.class);
1✔
282

283
        PaymentsProvidersHandler.PaymentsProvidersHandlerBuilder paymentsProvidersHandlerBuilder =
284
                PaymentsProvidersHandler.builder().paymentsProvidersApi(paymentsProvidersApi);
1✔
285
        if (customScopesPresent()) {
1✔
286
            paymentsProvidersHandlerBuilder.scopes(globalScopes);
×
287
        }
288
        IPaymentsProvidersHandler paymentsProvidersHandler = paymentsProvidersHandlerBuilder.build();
1✔
289

290
        IMerchantAccountsApi merchantAccountsApi = RetrofitFactory.build(
1✔
291
                        paymentsHttpClient, environment.getPaymentsApiUri())
1✔
292
                .create(IMerchantAccountsApi.class);
1✔
293
        MerchantAccountsHandler.MerchantAccountsHandlerBuilder merchantAccountsHandlerBuilder =
294
                MerchantAccountsHandler.builder().merchantAccountsApi(merchantAccountsApi);
1✔
295
        if (customScopesPresent()) {
1✔
296
            merchantAccountsHandlerBuilder.scopes(globalScopes);
×
297
        }
298
        IMerchantAccountsHandler merchantAccountsHandler = merchantAccountsHandlerBuilder.build();
1✔
299

300
        IMandatesApi mandatesApi = RetrofitFactory.build(paymentsHttpClient, environment.getPaymentsApiUri())
1✔
301
                .create(IMandatesApi.class);
1✔
302
        MandatesHandler.MandatesHandlerBuilder mandatesHandlerBuilder =
303
                MandatesHandler.builder().mandatesApi(mandatesApi);
1✔
304
        if (customScopesPresent()) {
1✔
305
            mandatesHandlerBuilder.scopes(globalScopes);
×
306
        }
307
        IMandatesHandler mandatesHandler = mandatesHandlerBuilder.build();
1✔
308

309
        IPayoutsApi payoutsApi = RetrofitFactory.build(paymentsHttpClient, environment.getPaymentsApiUri())
1✔
310
                .create(IPayoutsApi.class);
1✔
311
        PayoutsHandler.PayoutsHandlerBuilder payoutsHandlerBuilder =
312
                PayoutsHandler.builder().payoutsApi(payoutsApi);
1✔
313
        if (customScopesPresent()) {
1✔
314
            merchantAccountsHandlerBuilder.scopes(globalScopes);
×
315
        }
316
        IPayoutsHandler payoutsHandler = payoutsHandlerBuilder.build();
1✔
317

318
        return new TrueLayerClient(
1✔
319
                authenticationHandler,
320
                paymentsHandler,
321
                paymentsProvidersHandler,
322
                merchantAccountsHandler,
323
                mandatesHandler,
324
                payoutsHandler,
325
                signupPlusHandler,
326
                commonHandler,
327
                hppLinkBuilder,
328
                new HostedPaymentPageLinkBuilder(environment));
329
    }
330

331
    private boolean customScopesPresent() {
332
        return isNotEmpty(globalScopes) && isNotEmpty(globalScopes.getScopes());
1✔
333
    }
334
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc