Skip to content

Commit

Permalink
[#2976] improve(api): support header for gravitino client (#2991)
Browse files Browse the repository at this point in the history
### What changes were proposed in this pull request?

- Support pass header when using the Java Gravitino Client.

### Why are the changes needed?

- For now, we can't pass the useful header on the Java Gravitino Client.
We want to pass on more information such as some audit messages. The
base header may not be used for now, but it is useful for users to
integrate with their platform.

Fix: #2976 

### Does this PR introduce _any_ user-facing change?

- yes
  1. Change in user-facing APIs.
 
- add `withHeaders` in GravitinoClientBuilder.
```
GravitinoClient.builder("uri")
.withMetalake("metalake")
.withHeaders(Map) // add header
.builder();

GravitinoAdminClient.builder("uri")
.withHeaders(Map) // add header
.builder();
```

  2. Addition or removal of property keys.

  - add withHeaders() method

### How was this patch tested?
- original Uts
  • Loading branch information
coolderli authored Apr 17, 2024
1 parent 6cdd9aa commit eb1f11e
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ public class GravitinoAdminClient extends GravitinoClientBase implements Support
*
* @param uri The base URI for the Gravitino API.
* @param authDataProvider The provider of the data which is used for authentication.
* @param headers The base header for Gravitino API.
*/
private GravitinoAdminClient(String uri, AuthDataProvider authDataProvider) {
super(uri, authDataProvider);
private GravitinoAdminClient(
String uri, AuthDataProvider authDataProvider, Map<String, String> headers) {
super(uri, authDataProvider, headers);
}

/**
Expand Down Expand Up @@ -188,7 +190,7 @@ public GravitinoAdminClient build() {
Preconditions.checkArgument(
uri != null && !uri.isEmpty(), "The argument 'uri' must be a valid URI");

return new GravitinoAdminClient(uri, authDataProvider);
return new GravitinoAdminClient(uri, authDataProvider, headers);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,15 @@ public class GravitinoClient extends GravitinoClientBase implements SupportsCata
* @param uri The base URI for the Gravitino API.
* @param metalakeName The specified metalake name.
* @param authDataProvider The provider of the data which is used for authentication.
* @param headers The base header for Gravitino API.
* @throws NoSuchMetalakeException if the metalake with specified name does not exist.
*/
private GravitinoClient(String uri, String metalakeName, AuthDataProvider authDataProvider) {
super(uri, authDataProvider);
private GravitinoClient(
String uri,
String metalakeName,
AuthDataProvider authDataProvider,
Map<String, String> headers) {
super(uri, authDataProvider, headers);
this.metalake = loadMetalake(NameIdentifier.of(metalakeName));
}

Expand Down Expand Up @@ -138,7 +143,7 @@ public GravitinoClient build() {
metalakeName != null && !metalakeName.isEmpty(),
"The argument 'metalakeName' must be a valid name");

return new GravitinoClient(uri, metalakeName, authDataProvider);
return new GravitinoClient(uri, metalakeName, authDataProvider, headers);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
import com.datastrato.gravitino.dto.responses.MetalakeResponse;
import com.datastrato.gravitino.dto.responses.VersionResponse;
import com.datastrato.gravitino.exceptions.NoSuchMetalakeException;
import com.google.common.collect.ImmutableMap;
import java.io.Closeable;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -37,12 +39,15 @@ public abstract class GravitinoClientBase implements Closeable {
*
* @param uri The base URI for the Gravitino API.
* @param authDataProvider The provider of the data which is used for authentication.
* @param headers The base header of the Gravitino API.
*/
protected GravitinoClientBase(String uri, AuthDataProvider authDataProvider) {
protected GravitinoClientBase(
String uri, AuthDataProvider authDataProvider, Map<String, String> headers) {
this.restClient =
HTTPClient.builder(Collections.emptyMap())
.uri(uri)
.withAuthDataProvider(authDataProvider)
.withHeaders(headers)
.build();
}

Expand Down Expand Up @@ -103,6 +108,8 @@ public abstract static class Builder<T> {
protected String uri;
/** The authentication provider. */
protected AuthDataProvider authDataProvider;
/** The request base header for the Gravitino API. */
protected Map<String, String> headers = ImmutableMap.of();

/**
* The constructor for the Builder class.
Expand Down Expand Up @@ -154,6 +161,19 @@ public Builder<T> withKerberosAuth(KerberosTokenProvider dataProvider) {
return this;
}

/**
* Set base header for Gravitino Client.
*
* @param headers the base header.
* @return This Builder instance for method chaining.
*/
public Builder<T> withHeaders(Map<String, String> headers) {
if (headers != null) {
this.headers = ImmutableMap.copyOf(headers);
}
return this;
}

/**
* Builds a new instance. Subclasses should overwrite this method.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright 2024 Datastrato Pvt Ltd.
* This software is licensed under the Apache License version 2.
*/
package com.datastrato.gravitino.client;

import com.google.common.collect.ImmutableMap;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class TestGravitinoClientBuilder {
@Test
public void testGravitinoClientHeaders() {
Map<String, String> headers = ImmutableMap.of("k1", "v1");
try (MockGravitinoClient client =
MockGravitinoClient.builder("http://127.0.0.1").withHeaders(headers).build()) {
Assertions.assertEquals(headers, client.getHeaders());
}

try (MockGravitinoClient client1 = MockGravitinoClient.builder("http://127.0.0.1").build()) {
Assertions.assertEquals(ImmutableMap.of(), client1.getHeaders());
}

try (MockGravitinoClient client1 =
MockGravitinoClient.builder("http://127.0.0.1").withHeaders(null).build()) {
Assertions.assertEquals(ImmutableMap.of(), client1.getHeaders());
}
}
}

class MockGravitinoClient extends GravitinoClientBase {

private Map<String, String> headers;

/**
* Constructs a new GravitinoClient with the given URI, authenticator and AuthDataProvider.
*
* @param uri The base URI for the Gravitino API.
* @param authDataProvider The provider of the data which is used for authentication.
* @param headers The base header of the Gravitino API.
*/
private MockGravitinoClient(
String uri, AuthDataProvider authDataProvider, Map<String, String> headers) {
super(uri, authDataProvider, headers);
this.headers = headers;
}

Map<String, String> getHeaders() {
return headers;
}

/**
* Creates a new builder for constructing a GravitinoClient.
*
* @param uri The base URI for the Gravitino API.
* @return A new instance of the Builder class for constructing a GravitinoClient.
*/
static MockGravitinoClientBuilder builder(String uri) {
return new MockGravitinoClientBuilder(uri);
}

static class MockGravitinoClientBuilder extends GravitinoClientBase.Builder<MockGravitinoClient> {

/**
* The constructor for the Builder class.
*
* @param uri The base URI for the Gravitino API.
*/
protected MockGravitinoClientBuilder(String uri) {
super(uri);
}

@Override
public MockGravitinoClient build() {
return new MockGravitinoClient(uri, authDataProvider, headers);
}
}
}

0 comments on commit eb1f11e

Please sign in to comment.