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

TrueLayer / truelayer-java / #100

17 Oct 2024 12:55PM UTC coverage: 89.676%. First build
#100

Pull #322

github

dili91
acceptance test for SU+ uk
Pull Request #322: Adds support for Signup+ and fixes a few PayIn/Out asymmetries with our public API reference

7 of 11 new or added lines in 3 files covered. (63.64%)

443 of 494 relevant lines covered (89.68%)

0.9 hits per line

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

78.05
/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.HostedPaymentPageLinkBuilder;
13
import com.truelayer.java.hpp.IHostedPaymentPageLinkBuilder;
14
import com.truelayer.java.http.OkHttpClientFactory;
15
import com.truelayer.java.http.RetrofitFactory;
16
import com.truelayer.java.http.auth.cache.ICredentialsCache;
17
import com.truelayer.java.http.auth.cache.SimpleCredentialsCache;
18
import com.truelayer.java.http.interceptors.logging.DefaultLogConsumer;
19
import com.truelayer.java.mandates.IMandatesApi;
20
import com.truelayer.java.mandates.IMandatesHandler;
21
import com.truelayer.java.mandates.MandatesHandler;
22
import com.truelayer.java.merchantaccounts.IMerchantAccountsApi;
23
import com.truelayer.java.merchantaccounts.IMerchantAccountsHandler;
24
import com.truelayer.java.merchantaccounts.MerchantAccountsHandler;
25
import com.truelayer.java.payments.IPaymentsApi;
26
import com.truelayer.java.payments.IPaymentsHandler;
27
import com.truelayer.java.payments.PaymentsHandler;
28
import com.truelayer.java.paymentsproviders.IPaymentsProvidersApi;
29
import com.truelayer.java.paymentsproviders.IPaymentsProvidersHandler;
30
import com.truelayer.java.paymentsproviders.PaymentsProvidersHandler;
31
import com.truelayer.java.payouts.IPayoutsApi;
32
import com.truelayer.java.payouts.IPayoutsHandler;
33
import com.truelayer.java.payouts.PayoutsHandler;
34
import com.truelayer.java.signupplus.ISignupPlusApi;
35
import com.truelayer.java.signupplus.ISignupPlusHandler;
36
import com.truelayer.java.signupplus.SignupPlusHandler;
37
import com.truelayer.java.versioninfo.LibraryInfoLoader;
38
import java.time.Clock;
39
import java.time.Duration;
40
import java.util.concurrent.ExecutorService;
41
import java.util.function.Consumer;
42
import okhttp3.OkHttpClient;
43

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

50
    private RequestScopes globalScopes;
51

52
    private SigningOptions signingOptions;
53

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

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

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

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

74
    private Consumer<String> logMessageConsumer;
75

76
    private ICredentialsCache credentialsCache;
77

78
    private ProxyConfiguration proxyConfiguration;
79

80
    TrueLayerClientBuilder() {}
1✔
81

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

224
        OkHttpClient authHttpClient = httpClientFactory.buildAuthApiClient(baseHttpClient, clientCredentials);
1✔
225

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

231
        IHostedPaymentPageLinkBuilder hppLinkBuilder =
232
                HostedPaymentPageLinkBuilder.New().uri(environment.getHppUri()).build();
1✔
233

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

240
        // As per our RFC, if signing options is not configured we create a client which is able to interact
241
        // with the Authentication API only
242
        if (isEmpty(signingOptions)) {
1✔
243
            return new TrueLayerClient(authenticationHandler, hppLinkBuilder, commonHandler);
1✔
244
        }
245

246
        OkHttpClient paymentsHttpClient = httpClientFactory.buildPaymentsApiClient(
1✔
247
                authHttpClient, authenticationHandler, signingOptions, credentialsCache);
248

249
        IPaymentsApi paymentsApi = RetrofitFactory.build(paymentsHttpClient, environment.getPaymentsApiUri())
1✔
250
                .create(IPaymentsApi.class);
1✔
251

252
        PaymentsHandler.PaymentsHandlerBuilder paymentsHandlerBuilder =
253
                PaymentsHandler.builder().paymentsApi(paymentsApi);
1✔
254
        if (customScopesPresent()) {
1✔
255
            paymentsHandlerBuilder.scopes(globalScopes);
×
256
        }
257
        IPaymentsHandler paymentsHandler = paymentsHandlerBuilder.build();
1✔
258

259
        IPaymentsProvidersApi paymentsProvidersApi = RetrofitFactory.build(
1✔
260
                        paymentsHttpClient, environment.getPaymentsApiUri())
1✔
261
                .create(IPaymentsProvidersApi.class);
1✔
262

263
        PaymentsProvidersHandler.PaymentsProvidersHandlerBuilder paymentsProvidersHandlerBuilder =
264
                PaymentsProvidersHandler.builder().paymentsProvidersApi(paymentsProvidersApi);
1✔
265
        if (customScopesPresent()) {
1✔
266
            paymentsProvidersHandlerBuilder.scopes(globalScopes);
×
267
        }
268
        IPaymentsProvidersHandler paymentsProvidersHandler = paymentsProvidersHandlerBuilder.build();
1✔
269

270
        IMerchantAccountsApi merchantAccountsApi = RetrofitFactory.build(
1✔
271
                        paymentsHttpClient, environment.getPaymentsApiUri())
1✔
272
                .create(IMerchantAccountsApi.class);
1✔
273
        MerchantAccountsHandler.MerchantAccountsHandlerBuilder merchantAccountsHandlerBuilder =
274
                MerchantAccountsHandler.builder().merchantAccountsApi(merchantAccountsApi);
1✔
275
        if (customScopesPresent()) {
1✔
276
            merchantAccountsHandlerBuilder.scopes(globalScopes);
×
277
        }
278
        IMerchantAccountsHandler merchantAccountsHandler = merchantAccountsHandlerBuilder.build();
1✔
279

280
        IMandatesApi mandatesApi = RetrofitFactory.build(paymentsHttpClient, environment.getPaymentsApiUri())
1✔
281
                .create(IMandatesApi.class);
1✔
282
        MandatesHandler.MandatesHandlerBuilder mandatesHandlerBuilder =
283
                MandatesHandler.builder().mandatesApi(mandatesApi);
1✔
284
        if (customScopesPresent()) {
1✔
285
            mandatesHandlerBuilder.scopes(globalScopes);
×
286
        }
287
        IMandatesHandler mandatesHandler = mandatesHandlerBuilder.build();
1✔
288

289
        IPayoutsApi payoutsApi = RetrofitFactory.build(paymentsHttpClient, environment.getPaymentsApiUri())
1✔
290
                .create(IPayoutsApi.class);
1✔
291
        PayoutsHandler.PayoutsHandlerBuilder payoutsHandlerBuilder =
292
                PayoutsHandler.builder().payoutsApi(payoutsApi);
1✔
293
        if (customScopesPresent()) {
1✔
294
            merchantAccountsHandlerBuilder.scopes(globalScopes);
×
295
        }
296
        IPayoutsHandler payoutsHandler = payoutsHandlerBuilder.build();
1✔
297

298
        // We're reusing a client with only User agent and Idempotency key interceptors and give it our base payment
299
        // endpoint
300
        ISignupPlusApi signupPlusApi = RetrofitFactory.build(paymentsHttpClient, environment.getPaymentsApiUri())
1✔
301
                .create(ISignupPlusApi.class);
1✔
302
        SignupPlusHandler.SignupPlusHandlerBuilder signupPlusHandlerBuilder =
303
                SignupPlusHandler.builder().signupPlusApi(signupPlusApi);
1✔
304
        if (customScopesPresent()) {
1✔
NEW
305
            signupPlusHandlerBuilder.scopes(globalScopes);
×
306
        }
307
        ISignupPlusHandler signupPlusHandler = signupPlusHandlerBuilder.build();
1✔
308

309
        return new TrueLayerClient(
1✔
310
                authenticationHandler,
311
                paymentsHandler,
312
                paymentsProvidersHandler,
313
                merchantAccountsHandler,
314
                mandatesHandler,
315
                payoutsHandler,
316
                signupPlusHandler,
317
                commonHandler,
318
                hppLinkBuilder);
319
    }
320

321
    private boolean customScopesPresent() {
322
        return isNotEmpty(globalScopes) && isNotEmpty(globalScopes.getScopes());
1✔
323
    }
324
}
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