Skip to content

Commit 6bd8056

Browse files
committed
test: finish Bearer Token test case
Deleted NimbusTokenProvider.BearerTokenFlow class, no longer used. Added a wrapper for WeaviateClient that can tie client's lifetime to that of the Testcontainer that created it. That way the client, once opened, is only closed when the container it belonged to is stopped.
1 parent 01e58ea commit 6bd8056

5 files changed

Lines changed: 86 additions & 57 deletions

File tree

src/it/java/io/weaviate/containers/Container.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,6 @@ public class Container {
1717
public static final Contextionary CONTEXTIONARY = Contextionary.createDefault();
1818
public static final Img2VecNeural IMG2VEC_NEURAL = Img2VecNeural.createDefault();
1919

20-
static {
21-
startAll();
22-
}
23-
24-
/** Start all shared Testcontainers. */
25-
// TODO: start lazily!
26-
static void startAll() {
27-
// WEAVIATE.start();
28-
}
29-
3020
/**
3121
* Stop all shared Testcontainers created in {@link #startAll}.
3222
* <p>

src/it/java/io/weaviate/containers/Weaviate.java

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
import io.weaviate.client6.v1.internal.ObjectBuilder;
1616

1717
public class Weaviate extends WeaviateContainer {
18-
private WeaviateClient clientInstance;
19-
2018
public static final String VERSION = "1.29.1";
2119
public static final String DOCKER_IMAGE = "semitechnologies/weaviate";
2220

21+
private volatile SharedClient clientInstance;
22+
2323
public WeaviateClient getClient() {
2424
return getClient(ObjectBuilder.identity());
2525
}
@@ -30,24 +30,29 @@ public WeaviateClient getClient() {
3030
* this is not made thread-safe.
3131
*/
3232
public WeaviateClient getClient(Function<Config.Custom, ObjectBuilder<Config>> fn) {
33-
// FIXME: control from containers?
3433
if (!isRunning()) {
3534
start();
3635
}
37-
if (clientInstance == null) {
38-
var host = getHost();
39-
var customFn = ObjectBuilder.partial(fn,
40-
conn -> conn
41-
.scheme("http")
42-
.httpHost(host)
43-
.grpcHost(host)
44-
.httpPort(getMappedPort(8080))
45-
.grpcPort(getMappedPort(50051)));
46-
try {
47-
clientInstance = WeaviateClient.custom(customFn);
48-
// clientInstance = WeaviateClient.local();
49-
} catch (Exception e) {
50-
throw new RuntimeException("create WeaviateClient for Weaviate container", e);
36+
if (clientInstance != null) {
37+
return clientInstance;
38+
}
39+
40+
synchronized (this) {
41+
if (clientInstance == null) {
42+
var host = getHost();
43+
var customFn = ObjectBuilder.partial(fn,
44+
conn -> conn
45+
.scheme("http")
46+
.httpHost(host)
47+
.grpcHost(host)
48+
.httpPort(getMappedPort(8080))
49+
.grpcPort(getMappedPort(50051)));
50+
var config = customFn.apply(new Config.Custom()).build();
51+
try {
52+
clientInstance = new SharedClient(config, this);
53+
} catch (Exception e) {
54+
throw new RuntimeException("create WeaviateClient for Weaviate container", e);
55+
}
5156
}
5257
}
5358
return clientInstance;
@@ -149,10 +154,32 @@ public void stop() {
149154
if (clientInstance == null) {
150155
return;
151156
}
152-
try {
153-
clientInstance.close();
154-
} catch (IOException e) {
155-
// TODO: log error
157+
synchronized (this) {
158+
try {
159+
clientInstance.close(this);
160+
} catch (IOException e) {
161+
throw new RuntimeException(e);
162+
}
163+
}
164+
}
165+
166+
/** SharedClient's lifetime is tied to that of it's parent container. */
167+
private class SharedClient extends WeaviateClient {
168+
private final Weaviate parent;
169+
170+
private SharedClient(Config config, Weaviate parent) {
171+
super(config);
172+
this.parent = parent;
173+
}
174+
175+
private void close(Weaviate caller) throws IOException {
176+
if (caller == parent) {
177+
super.close();
178+
}
179+
}
180+
181+
@Override
182+
public void close() throws IOException {
156183
}
157184
}
158185
}

src/it/java/io/weaviate/integration/OIDCSupportITest.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
import io.weaviate.ConcurrentTest;
1313
import io.weaviate.client6.v1.api.Authorization;
14+
import io.weaviate.client6.v1.internal.TokenProvider;
15+
import io.weaviate.client6.v1.internal.rest.RestTransport;
1416
import io.weaviate.containers.Weaviate;
1517

1618
/**
@@ -45,9 +47,13 @@ public class OIDCSupportITest extends ConcurrentTest {
4547
.build();
4648

4749
@Test
48-
public void test_bearerToken() {
50+
public void test_bearerToken() throws IOException {
4951
Assume.assumeTrue("WCS_DUMMY_CI_PW is not set", WCS_DUMMY_CI_PW != null);
5052
Assume.assumeTrue("no internet connection", hasInternetConnection());
53+
54+
var t = TokenInterceptor.stealToken();
55+
var authz = Authorization.bearerToken(t.accessToken(), t.refreshToken(), t.expiresIn());
56+
pingWeaviate(wcsContainer, authz);
5157
}
5258

5359
@Test
@@ -66,6 +72,7 @@ public void test_clientCredentials() throws IOException {
6672

6773
var authz = Authorization.clientCredentials(OKTA_CLIENT_ID, OKTA_CLIENT_SECRET, List.of());
6874
pingWeaviate(oktaContainer, authz);
75+
pingWeaviate(oktaContainer, authz);
6976
}
7077

7178
private static void pingWeaviate(final Weaviate container, Authorization authz) throws IOException {
@@ -87,4 +94,32 @@ private static boolean ping(String site) {
8794
return false;
8895
}
8996
}
97+
98+
private static class TokenInterceptor implements Authorization, TokenProvider {
99+
/** Exchange resource owner password for a token and return it. */
100+
public static Token stealToken() throws IOException {
101+
var authz = Authorization.resourceOwnerPassword(WCS_DUMMY_CI_USERNAME, WCS_DUMMY_CI_PW, List.of());
102+
var spy = new TokenInterceptor(authz);
103+
pingWeaviate(wcsContainer, spy);
104+
return spy.getToken();
105+
}
106+
107+
private Authorization authorization;
108+
private TokenProvider tokenProvider;
109+
110+
private TokenInterceptor(Authorization actual) {
111+
this.authorization = actual;
112+
}
113+
114+
@Override
115+
public TokenProvider getTokenProvider(RestTransport transport) {
116+
tokenProvider = authorization.getTokenProvider(transport);
117+
return this;
118+
}
119+
120+
@Override
121+
public Token getToken() {
122+
return tokenProvider.getToken();
123+
}
124+
}
90125
}

src/main/java/io/weaviate/client6/v1/internal/oidc/nimbus/HttpResponseParser.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,6 @@ private static ErrorDetails fromErrorResponse(ErrorResponse response) {
7575
}
7676

7777
private static ErrorDetails fromHttpResponse(HTTPResponse response) {
78-
System.out.println(response.getBody());
79-
System.out.println(JSON.deserialize(response.getBody(), ErrorDetails.class));
8078
return JSON.deserialize(response.getBody(), ErrorDetails.class);
8179
}
8280
}

src/main/java/io/weaviate/client6/v1/internal/oidc/nimbus/NimbusTokenProvider.java

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@
44

55
import javax.annotation.concurrent.NotThreadSafe;
66

7-
import com.nimbusds.oauth2.sdk.AuthorizationGrant;
87
import com.nimbusds.oauth2.sdk.ParseException;
9-
import com.nimbusds.oauth2.sdk.RefreshTokenGrant;
108
import com.nimbusds.oauth2.sdk.Scope;
119
import com.nimbusds.oauth2.sdk.TokenRequest;
1210
import com.nimbusds.oauth2.sdk.id.ClientID;
13-
import com.nimbusds.oauth2.sdk.token.RefreshToken;
1411
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
1512
import com.nimbusds.openid.connect.sdk.token.OIDCTokens;
1613

@@ -102,8 +99,8 @@ public Token getToken() {
10299
? Token.expireAfter(accessToken.getValue(), accessToken.getLifetime())
103100
: Token.expireAfter(accessToken.getValue(), refreshToken.getValue(), accessToken.getLifetime());
104101

105-
if (flow instanceof BearerTokenFlow btf) {
106-
btf.setToken(newToken);
102+
if (flow instanceof RefreshTokenFlow rtf) {
103+
rtf.setToken(newToken);
107104
}
108105

109106
return newToken;
@@ -121,22 +118,4 @@ private static OIDCProviderMetadata _parseProviderMetadata(String providerMetada
121118
throw new WeaviateOAuthException("parse provider metadata: ", ex);
122119
}
123120
}
124-
125-
@NotThreadSafe
126-
final class BearerTokenFlow implements Flow {
127-
private Token t;
128-
129-
BearerTokenFlow(Token t) {
130-
this.t = t;
131-
}
132-
133-
@Override
134-
public AuthorizationGrant getAuthorizationGrant() {
135-
return new RefreshTokenGrant(new RefreshToken(t.refreshToken()));
136-
}
137-
138-
public void setToken(Token t) {
139-
this.t = t;
140-
}
141-
}
142121
}

0 commit comments

Comments
 (0)