Skip to content

Commit 22db8cf

Browse files
kenhuuutien
andauthored
Parallel Authentication Fix (#2551)
* fix: failing authentication when multiple initially requests are executed concurrently * Fix nits in PR for TINKERPOP-3061 regarding sasl authentication. --------- Co-authored-by: Tiến Nguyễn Khắc <tien.nguyenkhac@icloud.com>
1 parent ae2860d commit 22db8cf

File tree

6 files changed

+264
-111
lines changed

6 files changed

+264
-111
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
2525
2626
* Deprecated `ltrim()` and `rTrim()` in favor of `l_trim()` and `r_trim` in Python.
2727
* Fixed bug in `onCreate` for `mergeV()` where use of the `Cardinality` functions was not properly handled.
28+
* Fixed multiple concurrent initially requests caused authentication to fail.
2829
2930
[[release-3-7-1]]
3031
=== TinkerPop 3.7.1 (November 20, 2023)

gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/simple/AbstractClient.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
2626
import org.apache.tinkerpop.gremlin.util.message.RequestMessage;
2727
import org.apache.tinkerpop.gremlin.util.message.ResponseMessage;
28-
import org.apache.tinkerpop.gremlin.util.message.ResponseStatusCode;
2928

3029
import java.util.ArrayList;
30+
import java.util.HashMap;
3131
import java.util.List;
32+
import java.util.Map;
33+
import java.util.UUID;
3234
import java.util.concurrent.CompletableFuture;
3335
import java.util.concurrent.TimeUnit;
3436
import java.util.function.Consumer;
@@ -49,7 +51,7 @@ public AbstractClient(final String threadPattern) {
4951

5052
@Override
5153
public void submit(final RequestMessage requestMessage, final Consumer<ResponseMessage> callback) throws Exception {
52-
callbackResponseHandler.callback = callback;
54+
callbackResponseHandler.callbackByRequestId.put(requestMessage.getRequestId(), callback);
5355
writeAndFlush(requestMessage);
5456
}
5557

@@ -65,7 +67,7 @@ public List<ResponseMessage> submit(final RequestMessage requestMessage) throws
6567
public CompletableFuture<List<ResponseMessage>> submitAsync(final RequestMessage requestMessage) throws Exception {
6668
final List<ResponseMessage> results = new ArrayList<>();
6769
final CompletableFuture<List<ResponseMessage>> f = new CompletableFuture<>();
68-
callbackResponseHandler.callback = response -> {
70+
callbackResponseHandler.callbackByRequestId.put(requestMessage.getRequestId(), response -> {
6971
if (f.isDone())
7072
throw new RuntimeException("A terminating message was already encountered - no more messages should have been received");
7173

@@ -75,19 +77,19 @@ public CompletableFuture<List<ResponseMessage>> submitAsync(final RequestMessage
7577
if (response.getStatus().getCode().isFinalResponse()) {
7678
f.complete(results);
7779
}
78-
};
80+
});
7981

8082
writeAndFlush(requestMessage);
8183

8284
return f;
8385
}
8486

8587
static class CallbackResponseHandler extends SimpleChannelInboundHandler<ResponseMessage> {
86-
public Consumer<ResponseMessage> callback;
88+
public Map<UUID, Consumer<ResponseMessage>> callbackByRequestId = new HashMap<>();
8789

8890
@Override
8991
protected void channelRead0(final ChannelHandlerContext channelHandlerContext, final ResponseMessage response) throws Exception {
90-
callback.accept(response);
92+
callbackByRequestId.get(response.getRequestId()).accept(response);
9193
}
9294
}
9395
}

gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/sasl-authentication-tests.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,19 @@ describe('DriverRemoteConnection', function () {
5454
});
5555
});
5656

57+
it('should be able to send multiple requests concurrently with valid credentials and parse the response', async function () {
58+
connection = helper.getSecureConnectionWithPlainTextSaslAuthenticator(null, 'stephen', 'password');
59+
60+
const submissions = await Promise.all(
61+
Array.from({ length: 10 }).map(() => connection.submit(new Bytecode().addStep('V', []).addStep('tail', []))),
62+
);
63+
64+
submissions.forEach((response) => {
65+
assert.ok(response);
66+
assert.ok(response.traversers);
67+
});
68+
});
69+
5770
it('should send the request with invalid credentials and parse the response error', function () {
5871
connection = helper.getSecureConnectionWithPlainTextSaslAuthenticator(null, 'Bob', 'password');
5972

0 commit comments

Comments
 (0)