Skip to content

Commit 0f80440

Browse files
author
Petr Vales
committed
extract authentication strategy from GoodData class
* introduce GoodDataEndpoint, class encapsulating GoodData host, port and protocol * introduce Authentication interface, it allows developer to implement new authentication strategy * provide two implementation of new Authentication interface, sst and login + passport * make UriPrefixingClientHttpRequestFactory public class
1 parent d485c49 commit 0f80440

11 files changed

+379
-54
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Copyright (C) 2004-2016, GoodData(R) Corporation. All rights reserved.
3+
* This source code is licensed under the BSD-style license found in the
4+
* LICENSE.txt file in the root directory of this source tree.
5+
*/
6+
package com.gooddata;
7+
8+
import org.apache.http.client.HttpClient;
9+
import org.apache.http.impl.client.HttpClientBuilder;
10+
11+
/**
12+
* HttpClient factory
13+
*/
14+
public interface Authentication {
15+
16+
/**
17+
* create http client for given host, port and protocol using given http client builder
18+
* @param endpoint GoodData Platform's endpoint
19+
* @param httpClientBuilder http client builder
20+
* @return http client
21+
*/
22+
HttpClient createHttpClient(final GoodDataEndpoint endpoint, final HttpClientBuilder httpClientBuilder);
23+
24+
}

src/main/java/com/gooddata/GoodData.java

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,15 @@
1212
import com.gooddata.md.maintenance.ExportImportService;
1313
import com.gooddata.notification.NotificationService;
1414
import com.gooddata.util.ResponseErrorHandler;
15+
import com.gooddata.util.LoginPasswordAuthentication;
1516
import com.gooddata.warehouse.WarehouseService;
1617
import com.gooddata.dataset.DatasetService;
1718
import com.gooddata.gdc.DataStoreService;
1819
import com.gooddata.gdc.GdcService;
19-
import com.gooddata.http.client.GoodDataHttpClient;
20-
import com.gooddata.http.client.LoginSSTRetrievalStrategy;
21-
import com.gooddata.http.client.SSTRetrievalStrategy;
2220
import com.gooddata.md.MetadataService;
2321
import com.gooddata.model.ModelService;
2422
import com.gooddata.project.ProjectService;
2523
import com.gooddata.report.ReportService;
26-
import org.apache.http.HttpHost;
2724
import org.apache.http.client.HttpClient;
2825
import org.apache.http.client.config.RequestConfig;
2926
import org.apache.http.config.SocketConfig;
@@ -167,21 +164,31 @@ public GoodData(String hostname, String login, String password, int port, GoodDa
167164
* @param settings additional settings
168165
*/
169166
protected GoodData(String hostname, String login, String password, int port, String protocol, GoodDataSettings settings) {
170-
notEmpty(hostname, "hostname");
171-
notEmpty(login, "login");
172-
notEmpty(password, "password");
173-
notEmpty(protocol, "protocol");
174-
httpClient = createHttpClient(login, password, hostname, port, protocol,
175-
createHttpClientBuilder(settings));
167+
this(
168+
new GoodDataEndpoint(hostname, port, protocol),
169+
new LoginPasswordAuthentication(login, password), settings
170+
);
171+
}
176172

177-
restTemplate = createRestTemplate(hostname, httpClient, port, protocol);
173+
/**
174+
* Create instance configured to communicate with GoodData Platform running on given endpoint and using
175+
* given http client factory.
176+
*
177+
* @param endpoint GoodData platform endpoint
178+
* @param authentication
179+
* @param settings additional settings
180+
*/
181+
protected GoodData(GoodDataEndpoint endpoint, Authentication authentication, GoodDataSettings settings) {
182+
httpClient = authentication.createHttpClient(endpoint, createHttpClientBuilder(settings));
183+
184+
restTemplate = createRestTemplate(endpoint, httpClient);
178185

179186
accountService = new AccountService(getRestTemplate());
180187
projectService = new ProjectService(getRestTemplate(), accountService);
181188
metadataService = new MetadataService(getRestTemplate());
182189
modelService = new ModelService(getRestTemplate());
183190
gdcService = new GdcService(getRestTemplate());
184-
dataStoreService = new DataStoreService(getHttpClient(), getRestTemplate(), gdcService, new HttpHost(hostname, port, protocol).toURI());
191+
dataStoreService = new DataStoreService(getHttpClient(), getRestTemplate(), gdcService, endpoint.toUri());
185192
datasetService = new DatasetService(getRestTemplate(), dataStoreService);
186193
reportService = new ReportService(getRestTemplate());
187194
processService = new ProcessService(getRestTemplate(), accountService, dataStoreService);
@@ -192,10 +199,13 @@ protected GoodData(String hostname, String login, String password, int port, Str
192199
featureFlagService = new FeatureFlagService(restTemplate);
193200
}
194201

195-
private RestTemplate createRestTemplate(String hostname, HttpClient httpClient, int port, String protocol) {
196-
202+
private RestTemplate createRestTemplate(GoodDataEndpoint endpoint, HttpClient httpClient) {
197203
final UriPrefixingClientHttpRequestFactory factory = new UriPrefixingClientHttpRequestFactory(
198-
new HttpComponentsClientHttpRequestFactory(httpClient), hostname, port, protocol);
204+
new HttpComponentsClientHttpRequestFactory(httpClient),
205+
endpoint.getHostname(),
206+
endpoint.getPort(),
207+
endpoint.getProtocol()
208+
);
199209
final RestTemplate restTemplate = new RestTemplate(factory);
200210
restTemplate.setInterceptors(Arrays.<ClientHttpRequestInterceptor>asList(
201211
new HeaderSettingRequestInterceptor(singletonMap("Accept", getAcceptHeaderValue()))));
@@ -233,14 +243,6 @@ private String getAcceptHeaderValue(){
233243
return MediaType.APPLICATION_JSON_VALUE + ";version=" + RESTAPI_VERSION;
234244
}
235245

236-
protected HttpClient createHttpClient(final String login, final String password, final String hostname,
237-
final int port, final String protocol, final HttpClientBuilder builder) {
238-
final HttpHost host = new HttpHost(hostname, port, protocol);
239-
final HttpClient httpClient = builder.build();
240-
final SSTRetrievalStrategy strategy = new LoginSSTRetrievalStrategy(login, password);
241-
return new GoodDataHttpClient(httpClient, host, strategy);
242-
}
243-
244246
private String getUserAgent() {
245247
final Package pkg = Package.getPackage("com.gooddata");
246248
final String clientVersion = pkg != null && pkg.getImplementationVersion() != null
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* Copyright (C) 2004-2016, GoodData(R) Corporation. All rights reserved.
3+
* This source code is licensed under the BSD-style license found in the
4+
* LICENSE.txt file in the root directory of this source tree.
5+
*/
6+
package com.gooddata;
7+
8+
import org.apache.http.HttpHost;
9+
10+
import static com.gooddata.util.Validate.notEmpty;
11+
12+
/**
13+
* GoodData Platform endpoint represented by host, port and protocol
14+
*/
15+
public class GoodDataEndpoint {
16+
17+
private static final String PROTOCOL = "https";
18+
private static final int PORT = 443;
19+
20+
private final String hostname;
21+
private final int port;
22+
private final String protocol;
23+
24+
/**
25+
* Create GoodData endpoint for given hostname, port and protocol
26+
* @param hostname
27+
* @param port
28+
* @param protocol
29+
*/
30+
public GoodDataEndpoint(String hostname, int port, String protocol) {
31+
notEmpty(hostname, "hostname");
32+
notEmpty(protocol, "protocol");
33+
34+
this.hostname = hostname;
35+
this.port = port;
36+
this.protocol = protocol;
37+
}
38+
39+
/**
40+
* Create GoodData endpoint for given hostname, port using HTTPS protocol
41+
* @param hostname
42+
* @param port
43+
*/
44+
public GoodDataEndpoint(String hostname, int port) {
45+
this(hostname, port, PROTOCOL);
46+
}
47+
48+
/**
49+
* Create GoodData endpoint for given hostname using 443 port and HTTPS protocol
50+
* @param hostname
51+
*/
52+
public GoodDataEndpoint(String hostname) {
53+
this(hostname, PORT, PROTOCOL);
54+
}
55+
56+
public HttpHost toHttpHost() {
57+
return new HttpHost(hostname, port, protocol);
58+
}
59+
60+
public String toUri() {
61+
return toHttpHost().toURI();
62+
}
63+
64+
public String getHostname() {
65+
return hostname;
66+
}
67+
68+
public int getPort() {
69+
return port;
70+
}
71+
72+
public String getProtocol() {
73+
return protocol;
74+
}
75+
}

src/main/java/com/gooddata/UriPrefixingClientHttpRequestFactory.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* Sets default URI prefix for Spring REST client which by default requires absolute URI.
2121
* UriPrefixingAsyncClientHttpRequestFactory allows you to specify default hostname and port.
2222
*/
23-
class UriPrefixingClientHttpRequestFactory implements ClientHttpRequestFactory {
23+
public class UriPrefixingClientHttpRequestFactory implements ClientHttpRequestFactory {
2424

2525
private final ClientHttpRequestFactory wrapped;
2626
private final UriPrefixer prefixer;
@@ -32,7 +32,7 @@ class UriPrefixingClientHttpRequestFactory implements ClientHttpRequestFactory {
3232
* @param factory the factory to be wrapped
3333
* @param uriPrefix the URI for setting hostname and port of all HTTP requests
3434
*/
35-
UriPrefixingClientHttpRequestFactory(ClientHttpRequestFactory factory, URI uriPrefix) {
35+
public UriPrefixingClientHttpRequestFactory(ClientHttpRequestFactory factory, URI uriPrefix) {
3636
this.wrapped = notNull(factory, "factory");
3737
this.prefixer = new UriPrefixer(uriPrefix);
3838
}
@@ -46,7 +46,7 @@ class UriPrefixingClientHttpRequestFactory implements ClientHttpRequestFactory {
4646
* @param port the port for all HTTP requests
4747
* @param protocol the protocol for all HTTP requests
4848
*/
49-
UriPrefixingClientHttpRequestFactory(ClientHttpRequestFactory factory, String hostname, int port, String protocol) {
49+
public UriPrefixingClientHttpRequestFactory(ClientHttpRequestFactory factory, String hostname, int port, String protocol) {
5050
this(factory, UriComponentsBuilder.newInstance().scheme(protocol).host(hostname).port(port).build().toUri());
5151
}
5252

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Copyright (C) 2004-2016, GoodData(R) Corporation. All rights reserved.
3+
* This source code is licensed under the BSD-style license found in the
4+
* LICENSE.txt file in the root directory of this source tree.
5+
*/
6+
package com.gooddata.util;
7+
8+
import com.gooddata.GoodDataEndpoint;
9+
import com.gooddata.Authentication;
10+
import com.gooddata.http.client.GoodDataHttpClient;
11+
import com.gooddata.http.client.LoginSSTRetrievalStrategy;
12+
import com.gooddata.http.client.SSTRetrievalStrategy;
13+
import org.apache.http.client.HttpClient;
14+
import org.apache.http.impl.client.HttpClientBuilder;
15+
16+
import static com.gooddata.util.Validate.notEmpty;
17+
import static com.gooddata.util.Validate.notNull;
18+
19+
/**
20+
* This factory creates http client with SST authentication (using login and password).
21+
*/
22+
public class LoginPasswordAuthentication implements Authentication {
23+
24+
private final String login;
25+
private final String password;
26+
27+
/**
28+
* Create factory
29+
* @param login login
30+
* @param password password
31+
*/
32+
public LoginPasswordAuthentication(final String login, final String password) {
33+
notEmpty(login, "login");
34+
notEmpty(password, "password");
35+
36+
this.login = login;
37+
this.password = password;
38+
}
39+
40+
/**
41+
* create http client for given host, port and protocol using given http client builder
42+
* @param endpoint GoodData Platform's endpoint
43+
* @param builder http client builder
44+
* @return http client
45+
*/
46+
@Override
47+
public HttpClient createHttpClient(final GoodDataEndpoint endpoint, final HttpClientBuilder builder) {
48+
notNull(endpoint, "endpoint");
49+
notNull(builder, "builder");
50+
51+
final HttpClient httpClient = builder.build();
52+
final SSTRetrievalStrategy strategy = new LoginSSTRetrievalStrategy(login, password);
53+
return new GoodDataHttpClient(httpClient, endpoint.toHttpHost(), strategy);
54+
}
55+
56+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* Copyright (C) 2004-2016, GoodData(R) Corporation. All rights reserved.
3+
* This source code is licensed under the BSD-style license found in the
4+
* LICENSE.txt file in the root directory of this source tree.
5+
*/
6+
package com.gooddata.util;
7+
8+
import com.gooddata.GoodDataEndpoint;
9+
import com.gooddata.Authentication;
10+
import com.gooddata.http.client.GoodDataHttpClient;
11+
import com.gooddata.http.client.SSTRetrievalStrategy;
12+
import com.gooddata.http.client.SimpleSSTRetrievalStrategy;
13+
import org.apache.http.client.HttpClient;
14+
import org.apache.http.impl.client.HttpClientBuilder;
15+
16+
import static com.gooddata.util.Validate.notEmpty;
17+
import static com.gooddata.util.Validate.notNull;
18+
19+
/**
20+
* This factory creates http client with SST authentication
21+
*/
22+
public class SstAuthentication implements Authentication {
23+
24+
private final String sst;
25+
26+
/**
27+
* Create factory
28+
* @param sst sst
29+
*/
30+
public SstAuthentication(final String sst) {
31+
notEmpty(sst, "sst");
32+
33+
this.sst = sst;
34+
}
35+
36+
/**
37+
* create http client for given host, port and protocol using given http client builder
38+
* @param endpoint GoodData Platform's endpoint
39+
* @param builder http client builder
40+
* @return http client
41+
*/
42+
@Override
43+
public HttpClient createHttpClient(final GoodDataEndpoint endpoint, final HttpClientBuilder builder) {
44+
notNull(endpoint, "endpoint");
45+
notNull(builder, "builder");
46+
47+
final HttpClient httpClient = builder.build();
48+
final SSTRetrievalStrategy strategy = new SimpleSSTRetrievalStrategy(sst);
49+
return new GoodDataHttpClient(httpClient, endpoint.toHttpHost(), strategy);
50+
}
51+
52+
}

src/test/java/com/gooddata/AbstractGoodDataAT.java

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,13 @@
55
*/
66
package com.gooddata;
77

8-
import com.gooddata.http.client.GoodDataHttpClient;
9-
import com.gooddata.http.client.LoginSSTRetrievalStrategy;
10-
import com.gooddata.http.client.SSTRetrievalStrategy;
118
import com.gooddata.md.Attribute;
129
import com.gooddata.md.Metric;
1310
import com.gooddata.md.ScheduledMail;
1411
import com.gooddata.md.report.Report;
1512
import com.gooddata.md.report.ReportDefinition;
1613
import com.gooddata.project.Project;
17-
import org.apache.http.HttpHost;
14+
import com.gooddata.util.LoginPasswordAuthentication;
1815
import org.apache.http.client.HttpClient;
1916
import org.apache.http.impl.client.HttpClientBuilder;
2017
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
@@ -30,20 +27,22 @@ public abstract class AbstractGoodDataAT {
3027
"sdktest " + new LocalDate() + " " + System.getenv("BUILD_NUMBER");
3128

3229
protected static final GoodData gd =
33-
new GoodData(getProperty("host"), getProperty("login"), getProperty("pass")) {
34-
/**
35-
* had to be overriden to access connectionManager, to test how many connections were not closed
36-
*/
37-
@Override
38-
protected HttpClient createHttpClient(String login, String password, String hostname, int port, String protocol, HttpClientBuilder builder) {
39-
PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager();
40-
final HttpHost host = new HttpHost(hostname, port, protocol);
41-
final HttpClient httpClient = builder.setConnectionManager(httpClientConnectionManager).build();
42-
final SSTRetrievalStrategy strategy = new LoginSSTRetrievalStrategy(httpClient, host, login, password);
43-
connManager = httpClientConnectionManager;
44-
return new GoodDataHttpClient(httpClient, strategy);
45-
}
46-
};
30+
new GoodData(
31+
new GoodDataEndpoint(getProperty("host")),
32+
new LoginPasswordAuthentication(getProperty("login"), getProperty("pass")) {
33+
/**
34+
* had to be overriden to access connectionManager, to test how many connections were not closed
35+
*/
36+
@Override
37+
public HttpClient createHttpClient(final GoodDataEndpoint endpoint, final HttpClientBuilder builder) {
38+
PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager();
39+
final HttpClientBuilder builderWithManager = builder.setConnectionManager(httpClientConnectionManager);
40+
connManager = httpClientConnectionManager;
41+
42+
return super.createHttpClient(endpoint, builderWithManager);
43+
}
44+
}, new GoodDataSettings());
45+
4746

4847
protected static PoolingHttpClientConnectionManager connManager;
4948

0 commit comments

Comments
 (0)