Skip to content
This repository was archived by the owner on Nov 22, 2020. It is now read-only.

Commit e646b10

Browse files
authored
Add support for api key (#94)
* Add support for api key Signed-off-by: wslulciuc <willy@datakin.com> * Add api to http backend test Signed-off-by: wslulciuc <willy@datakin.com> * Add client constructors to handle case where no API key is provided Signed-off-by: wslulciuc <willy@datakin.com> * Add Utils.addAuthTo() Signed-off-by: wslulciuc <willy@datakin.com> * Add Backends.newHttpBackend(URL) Signed-off-by: wslulciuc <willy@datakin.com> * Add BackendsTest.testHttpWithApiKey() Signed-off-by: wslulciuc <willy@datakin.com> * Ensure api key not set Signed-off-by: wslulciuc <willy@datakin.com> * Add null checks for HttpBackend Signed-off-by: wslulciuc <willy@datakin.com> * continued: Add null checks for HttpBackend Signed-off-by: wslulciuc <willy@datakin.com> * Add null checks for backends Signed-off-by: wslulciuc <willy@datakin.com> * Add null checks for MarquezHttp.create() Signed-off-by: wslulciuc <willy@datakin.com>
1 parent 2ec82aa commit e646b10

10 files changed

Lines changed: 180 additions & 41 deletions

File tree

src/main/java/marquez/client/Backends.java

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,23 @@
77
import java.net.MalformedURLException;
88
import java.net.URL;
99
import java.util.Map;
10+
import lombok.NonNull;
1011
import lombok.extern.slf4j.Slf4j;
1112

1213
/** To initialize the Marquez backend protocol. */
1314
@Slf4j
1415
public class Backends {
16+
private Backends() {}
1517

16-
@VisibleForTesting static final String DEFAULT_URL = "http://localhost:8080";
18+
@VisibleForTesting static final URL DEFAULT_BASE_URL = Utils.toUrl("http://localhost:8080");
1719

1820
/**
1921
* Will write to a file.
2022
*
2123
* @param file the file to write to
2224
* @return the corresponding backend implementation
2325
*/
24-
public static Backend newFileBackend(File file) {
26+
public static Backend newFileBackend(@NonNull final File file) {
2527
return new FileBackend(file);
2628
}
2729

@@ -31,10 +33,21 @@ public static Backend newFileBackend(File file) {
3133
* @param baseUrl the base url for http requests
3234
* @return the corresponding backend implementation
3335
*/
34-
public static Backend newHttpBackend(URL baseUrl) {
36+
public static Backend newHttpBackend(@NonNull final URL baseUrl) {
3537
return new HttpBackend(baseUrl);
3638
}
3739

40+
/**
41+
* Will issue http requests.
42+
*
43+
* @param baseUrl the base url for http requests
44+
* @param apiKey the API key to authenticate http requests
45+
* @return the corresponding backend implementation
46+
*/
47+
public static Backend newHttpBackend(@NonNull final URL baseUrl, @NonNull final String apiKey) {
48+
return new HttpBackend(baseUrl, apiKey);
49+
}
50+
3851
/**
3952
* Will log requests.
4053
*
@@ -63,14 +76,17 @@ public static Backend newBackendFromEnv() {
6376

6477
@VisibleForTesting
6578
static Backend newBackendFromEnv(Map<String, String> env) {
66-
String backendName = env.getOrDefault("MARQUEZ_BACKEND", "http");
79+
final String backendName = env.getOrDefault("MARQUEZ_BACKEND", "http");
6780
switch (backendName.toUpperCase(US)) {
6881
case "FILE":
6982
return newFileBackend(new File(env.get("MARQUEZ_FILE")));
7083
case "HTTP":
71-
String configuredBaseUrl = env.getOrDefault("MARQUEZ_URL", DEFAULT_URL);
84+
final String configuredBaseUrl = env.get("MARQUEZ_URL");
85+
final String apiKey = env.get("MARQUEZ_API_KEY");
7286
try {
73-
return newHttpBackend(new URL(configuredBaseUrl));
87+
final URL baseUrl =
88+
(configuredBaseUrl == null) ? DEFAULT_BASE_URL : new URL(configuredBaseUrl);
89+
return (apiKey == null) ? newHttpBackend(baseUrl) : newHttpBackend(baseUrl, apiKey);
7490
} catch (MalformedURLException e) {
7591
log.error(
7692
"Could not initialize Marquez http backend because of an invalid base url "

src/main/java/marquez/client/HttpBackend.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,28 @@
44
import java.io.IOException;
55
import java.net.MalformedURLException;
66
import java.net.URL;
7+
import lombok.NonNull;
78

89
/**
910
* A backend who issues HTTP requests by appending the path to the provided baseUrl and
1011
* posting/putting the payload.
1112
*/
1213
class HttpBackend implements Backend {
13-
1414
private final URL baseUrl;
15-
private final MarquezHttp http;
15+
@VisibleForTesting final MarquezHttp http;
1616

17-
HttpBackend(URL baseUrl) {
17+
@VisibleForTesting
18+
HttpBackend(final URL baseUrl) {
1819
this(baseUrl, MarquezHttp.create(MarquezClient.Version.get()));
1920
}
2021

2122
@VisibleForTesting
22-
HttpBackend(URL baseUrl, MarquezHttp http) {
23+
HttpBackend(final URL baseUrl, @NonNull final String apiKey) {
24+
this(baseUrl, MarquezHttp.create(MarquezClient.Version.get(), apiKey));
25+
}
26+
27+
@VisibleForTesting
28+
HttpBackend(@NonNull final URL baseUrl, @NonNull final MarquezHttp http) {
2329
this.baseUrl = baseUrl;
2430
this.http = http;
2531
}

src/main/java/marquez/client/MarquezClient.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,26 @@ public class MarquezClient {
6262
@VisibleForTesting final MarquezHttp http;
6363

6464
public MarquezClient() {
65-
this(DEFAULT_BASE_URL);
65+
this(DEFAULT_BASE_URL, null);
6666
}
6767

6868
public MarquezClient(final String baseUrlString) {
69-
this(Utils.toUrl(baseUrlString));
69+
this(baseUrlString, null);
70+
}
71+
72+
public MarquezClient(final String baseUrlString, @Nullable final String apiKey) {
73+
this(Utils.toUrl(baseUrlString), apiKey);
7074
}
7175

7276
public MarquezClient(final URL baseUrl) {
73-
this(MarquezUrl.create(baseUrl), MarquezHttp.create(MarquezClient.Version.get()));
77+
this(baseUrl, null);
78+
}
79+
80+
public MarquezClient(final URL baseUrl, @Nullable final String apiKey) {
81+
this(MarquezUrl.create(baseUrl), MarquezHttp.create(MarquezClient.Version.get(), apiKey));
7482
}
7583

84+
@VisibleForTesting
7685
MarquezClient(@NonNull final MarquezUrl url, @NonNull final MarquezHttp http) {
7786
this.url = url;
7887
this.http = http;
@@ -262,6 +271,7 @@ public Set<Tag> listTags(int limit, int offset) {
262271

263272
public static final class Builder {
264273
@VisibleForTesting URL baseUrl;
274+
@VisibleForTesting @Nullable String apiKey;
265275

266276
private Builder() {
267277
this.baseUrl = DEFAULT_BASE_URL;
@@ -276,9 +286,14 @@ public Builder baseUrl(@NonNull URL baseUrl) {
276286
return this;
277287
}
278288

289+
public Builder apiKey(@Nullable String apiKey) {
290+
this.apiKey = apiKey;
291+
return this;
292+
}
293+
279294
public MarquezClient build() {
280295
return new MarquezClient(
281-
MarquezUrl.create(baseUrl), MarquezHttp.create(MarquezClient.Version.get()));
296+
MarquezUrl.create(baseUrl), MarquezHttp.create(MarquezClient.Version.get(), apiKey));
282297
}
283298
}
284299

src/main/java/marquez/client/MarquezHttp.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,22 @@
2121

2222
import com.fasterxml.jackson.annotation.JsonCreator;
2323
import com.fasterxml.jackson.core.type.TypeReference;
24+
import com.google.common.annotations.VisibleForTesting;
2425
import java.io.Closeable;
2526
import java.io.IOException;
2627
import java.net.URISyntaxException;
2728
import java.net.URL;
2829
import javax.annotation.Nullable;
2930
import lombok.Getter;
31+
import lombok.NonNull;
3032
import lombok.Value;
3133
import lombok.extern.slf4j.Slf4j;
3234
import org.apache.http.HttpResponse;
3335
import org.apache.http.client.HttpClient;
3436
import org.apache.http.client.methods.HttpGet;
3537
import org.apache.http.client.methods.HttpPost;
3638
import org.apache.http.client.methods.HttpPut;
39+
import org.apache.http.client.methods.HttpRequestBase;
3740
import org.apache.http.entity.StringEntity;
3841
import org.apache.http.impl.client.CloseableHttpClient;
3942
import org.apache.http.impl.client.HttpClientBuilder;
@@ -42,16 +45,23 @@
4245
@Slf4j
4346
class MarquezHttp implements Closeable {
4447
private final HttpClient http;
48+
@VisibleForTesting @Nullable final String apiKey;
4549

46-
MarquezHttp(final HttpClient http) {
50+
MarquezHttp(@NonNull final HttpClient http, @Nullable final String apiKey) {
4751
this.http = http;
52+
this.apiKey = apiKey;
4853
}
4954

50-
static final MarquezHttp create(final MarquezClient.Version version) {
55+
static MarquezHttp create(final MarquezClient.Version version) {
56+
return create(version, null);
57+
}
58+
59+
static MarquezHttp create(
60+
@NonNull final MarquezClient.Version version, @Nullable final String apiKey) {
5161
final UserAgent userAgent = UserAgent.of(version);
5262
final CloseableHttpClient http =
5363
HttpClientBuilder.create().setUserAgent(userAgent.getValue()).build();
54-
return new MarquezHttp(http);
64+
return new MarquezHttp(http, apiKey);
5565
}
5666

5767
String post(URL url) {
@@ -69,6 +79,8 @@ String post(URL url, @Nullable String json) {
6979
request.setEntity(new StringEntity(json, APPLICATION_JSON));
7080
}
7181

82+
addAuthToReqIfKeyPresent(request);
83+
7284
final HttpResponse response = http.execute(request);
7385
throwOnHttpError(response);
7486

@@ -89,6 +101,8 @@ String put(URL url, String json) {
89101
request.addHeader(CONTENT_TYPE, APPLICATION_JSON.toString());
90102
request.setEntity(new StringEntity(json, APPLICATION_JSON));
91103

104+
addAuthToReqIfKeyPresent(request);
105+
92106
final HttpResponse response = http.execute(request);
93107
throwOnHttpError(response);
94108

@@ -107,6 +121,8 @@ String get(URL url) {
107121
request.setURI(url.toURI());
108122
request.addHeader(ACCEPT, APPLICATION_JSON.toString());
109123

124+
addAuthToReqIfKeyPresent(request);
125+
110126
final HttpResponse response = http.execute(request);
111127
throwOnHttpError(response);
112128

@@ -132,6 +148,12 @@ public void close() throws IOException {
132148
}
133149
}
134150

151+
private void addAuthToReqIfKeyPresent(final HttpRequestBase request) {
152+
if (apiKey != null) {
153+
Utils.addAuthTo(request, apiKey);
154+
}
155+
}
156+
135157
@Value
136158
static class UserAgent {
137159
@Getter String value;

src/main/java/marquez/client/Utils.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
package marquez.client;
1616

17+
import static org.apache.http.HttpHeaders.AUTHORIZATION;
18+
1719
import com.fasterxml.jackson.annotation.JsonInclude;
1820
import com.fasterxml.jackson.core.JsonProcessingException;
1921
import com.fasterxml.jackson.core.type.TypeReference;
@@ -25,6 +27,7 @@
2527
import java.net.MalformedURLException;
2628
import java.net.URL;
2729
import lombok.NonNull;
30+
import org.apache.http.client.methods.HttpRequestBase;
2831

2932
public final class Utils {
3033
private Utils() {}
@@ -63,4 +66,9 @@ public static URL toUrl(@NonNull final String urlString) {
6366
throw error;
6467
}
6568
}
69+
70+
public static void addAuthTo(
71+
@NonNull final HttpRequestBase request, @NonNull final String apiKey) {
72+
request.addHeader(AUTHORIZATION, "Bearer " + apiKey);
73+
}
6674
}
Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,95 @@
11
package marquez.client;
22

3-
import static org.junit.Assert.assertEquals;
4-
import static org.junit.Assert.assertTrue;
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.assertj.core.api.Assertions.assertThatNullPointerException;
55

66
import com.google.common.collect.ImmutableMap;
77
import java.io.IOException;
88
import org.junit.Test;
99

1010
public class BackendsTest {
11+
private static final String API_KEY = "PuRx8GT3huSXlheDIRUK1YUatGpLVEuL";
12+
13+
@Test
14+
public void testHttp_throwsOnNull() {
15+
assertThatNullPointerException().isThrownBy(() -> Backends.newHttpBackend(null));
16+
assertThatNullPointerException()
17+
.isThrownBy(() -> Backends.newHttpBackend(Backends.DEFAULT_BASE_URL, null));
18+
}
1119

1220
@Test
1321
public void testHttp() {
14-
ImmutableMap<String, String> env =
22+
final ImmutableMap<String, String> env =
1523
ImmutableMap.<String, String>builder()
1624
.put("MARQUEZ_BACKEND", "HTTP")
1725
.put("MARQUEZ_URL", "https://localhost:8080")
1826
.build();
19-
Backend backend = Backends.newBackendFromEnv(env);
20-
assertTrue(backend.getClass().getName(), backend instanceof HttpBackend);
27+
final Backend backend = Backends.newBackendFromEnv(env);
28+
assertThat(backend).isInstanceOf(Backend.class);
29+
assertThat(((HttpBackend) backend).http.apiKey).isNull();
30+
}
31+
32+
@Test
33+
public void testHttpWithApiKey() {
34+
final ImmutableMap<String, String> env =
35+
ImmutableMap.<String, String>builder()
36+
.put("MARQUEZ_BACKEND", "HTTP")
37+
.put("MARQUEZ_URL", "https://localhost:8080")
38+
.put("MARQUEZ_API_KEY", API_KEY)
39+
.build();
40+
final Backend backend = Backends.newBackendFromEnv(env);
41+
assertThat(backend).isInstanceOf(Backend.class);
42+
assertThat(((HttpBackend) backend).http.apiKey).isEqualTo(API_KEY);
43+
}
44+
45+
@Test
46+
public void testFile_throwsOnNull() {
47+
assertThatNullPointerException().isThrownBy(() -> Backends.newFileBackend(null));
2148
}
2249

2350
@Test
2451
public void testFile() {
25-
ImmutableMap<String, String> env =
52+
final ImmutableMap<String, String> env =
2653
ImmutableMap.<String, String>builder()
2754
.put("MARQUEZ_BACKEND", "FILE")
28-
.put("MARQUEZ_FILE", "/tmp/marquez.log")
55+
.put("MARQUEZ_FILE", "/tmp/marquez/client.requests.log")
2956
.build();
30-
Backend backend = Backends.newBackendFromEnv(env);
31-
assertTrue(backend.getClass().getName(), backend instanceof FileBackend);
57+
final Backend backend = Backends.newBackendFromEnv(env);
58+
assertThat(backend).isInstanceOf(FileBackend.class);
3259
}
3360

3461
@Test
3562
public void testDefault() {
36-
Backend backend = Backends.newBackendFromEnv();
37-
assertTrue(backend.getClass().getName(), backend instanceof HttpBackend);
38-
assertEquals(((HttpBackend) backend).getBaseUrl().toString(), Backends.DEFAULT_URL);
63+
final Backend backend = Backends.newBackendFromEnv();
64+
assertThat(backend).isInstanceOf(HttpBackend.class);
65+
assertThat(((HttpBackend) backend).getBaseUrl()).isEqualTo(Backends.DEFAULT_BASE_URL);
3966
}
4067

4168
@Test
4269
public void testLog() {
43-
ImmutableMap<String, String> env =
70+
final ImmutableMap<String, String> env =
4471
ImmutableMap.<String, String>builder().put("MARQUEZ_BACKEND", "LOG").build();
45-
Backend backend = Backends.newBackendFromEnv(env);
46-
assertTrue(backend.getClass().getName(), backend instanceof LoggingBackend);
72+
final Backend backend = Backends.newBackendFromEnv(env);
73+
assertThat(backend).isInstanceOf(LoggingBackend.class);
4774
}
4875

4976
@Test
5077
public void testWrongUrl() {
51-
ImmutableMap<String, String> env =
78+
final ImmutableMap<String, String> env =
5279
ImmutableMap.<String, String>builder()
5380
.put("MARQUEZ_BACKEND", "HTTP")
5481
.put("MARQUEZ_URL", "badProtocol://localhost:8080")
5582
.build();
56-
Backend backend = Backends.newBackendFromEnv(env);
57-
assertTrue(backend.getClass().getName(), backend instanceof NullBackend);
83+
final Backend backend = Backends.newBackendFromEnv(env);
84+
assertThat(backend).isInstanceOf(NullBackend.class);
5885
}
5986

6087
@Test
6188
public void testWrongBackend() throws IOException {
62-
ImmutableMap<String, String> env =
89+
final ImmutableMap<String, String> env =
6390
ImmutableMap.<String, String>builder().put("MARQUEZ_BACKEND", "WRONG_BACKEND").build();
64-
Backend backend = Backends.newBackendFromEnv(env);
65-
assertTrue(backend.getClass().getName(), backend instanceof NullBackend);
91+
final Backend backend = Backends.newBackendFromEnv(env);
92+
assertThat(backend).isInstanceOf(NullBackend.class);
6693
backend.close();
6794
}
6895
}

0 commit comments

Comments
 (0)