Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,64 @@
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.utility.MountableFile;

/**
* Testcontainers implementation for Qdrant.
* <p>
* Supported image: {@code qdrant/qdrant}
* <p>
* Exposed ports:
*
* <p>Supported image: {@code qdrant/qdrant}
*
* <p>Exposed ports:
*
Comment on lines +10 to +14
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we revert those changes, please?

* <ul>
* <li>HTTP: 6333</li>
* <li>Grpc: 6334</li>
* <li>HTTP: 6333
* <li>GRPC: 6334
* </ul>
*/
public class QdrantContainer extends GenericContainer<QdrantContainer> {

private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("qdrant/qdrant");

private final int QDRANT_REST_PORT = 6333;

private final int QDRANT_GRPC_PORT = 6334;

private final String CONFIG_FILE_PATH = "/qdrant/config/config.yaml";

private final String API_KEY_ENV = "QDRANT__SERVICE__API_KEY";

public QdrantContainer(String image) {
this(DockerImageName.parse(image));
}

public QdrantContainer(DockerImageName dockerImageName) {
super(dockerImageName);
dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
withExposedPorts(6333, 6334);
waitingFor(Wait.forHttp("/readyz").forPort(6333));
withExposedPorts(QDRANT_REST_PORT, QDRANT_GRPC_PORT);
waitingFor(Wait.forHttp("/readyz").forPort(QDRANT_REST_PORT));
}

public QdrantContainer withApiKey(String apiKey) {
return withEnv(API_KEY_ENV, apiKey);
}

public QdrantContainer withConfigFile(MountableFile configFile) {
return withCopyFileToContainer(configFile, CONFIG_FILE_PATH);
}

public int getHttpPort() {
return getMappedPort(QDRANT_REST_PORT);
}
Comment on lines +51 to +53
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand one of the ways for the GRPC client is using specifically the port but do we know of any client building the API just like GRPC?

Suggested change
public int getHttpPort() {
return getMappedPort(QDRANT_REST_PORT);
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't get what you meant. Could you clarify, please?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a qdrant client that use the REST port just like GRPC does? In GRPC makes sense because the client allows it but with the REST port IDK

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It for general availability for anyone who wants to use Qdrant via the REST interface in any way.

Copy link
Member

@eddumelendez eddumelendez Apr 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, getHttpHostAddress() or getHttpEndpoint() make sense but since Qdrant doesn't provide a rest client, I'd prefer just to keep the getGrpcHostAddress()

String getHttpHostAddress() {
return getHost() + ":" + getMappedPort(REST_PORT);
}

String getHttpEndpoint() {
return "http://" + getHost() + ":" + getMappedPort(REST_PORT);
}


public int getGrpcPort() {
return getMappedPort(QDRANT_GRPC_PORT);
}

public String getRestHostAddress() {
return getHost() + ":" + getHttpPort();
}

public String getGrpcHostAddress() {
return getHost() + ":" + getMappedPort(6334);
return getHost() + ":" + getGrpcPort();
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package org.testcontainers.qdrant;

import io.grpc.Grpc;
import io.grpc.InsecureChannelCredentials;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.QdrantOuterClass;
import org.junit.Test;

import java.util.UUID;
import java.util.concurrent.ExecutionException;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertThrows;

public class QdrantContainerTest {

Expand All @@ -21,16 +22,38 @@ public void test() throws ExecutionException, InterruptedException {
) {
qdrant.start();

QdrantGrpcClient client = QdrantGrpcClient
.newBuilder(
Grpc.newChannelBuilder(qdrant.getGrpcHostAddress(), InsecureChannelCredentials.create()).build()
)
.build();
QdrantOuterClass.HealthCheckReply healthCheckReply = client
.qdrant()
.healthCheck(QdrantOuterClass.HealthCheckRequest.getDefaultInstance())
.get();
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder(qdrant.getHost(), qdrant.getGrpcPort(), false).build()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wonder why changing this test? It is also a valid way to build a client and using the getGrpcHostAddress()

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only a style improvement. It's comparatively simpler.

);
QdrantOuterClass.HealthCheckReply healthCheckReply = client.healthCheckAsync().get();
assertThat(healthCheckReply.getVersion()).isEqualTo("1.7.4");

client.close();
}
}

@Test
public void testApiKey() throws ExecutionException, InterruptedException {
String apiKey = UUID.randomUUID().toString();
try (QdrantContainer qdrant = new QdrantContainer("qdrant/qdrant:v1.7.4").withApiKey(apiKey)) {
qdrant.start();

final QdrantClient unauthClient = new QdrantClient(
QdrantGrpcClient.newBuilder(qdrant.getHost(), qdrant.getGrpcPort(), false).build()
);

assertThrows(ExecutionException.class, () -> unauthClient.healthCheckAsync().get());

unauthClient.close();

final QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder(qdrant.getHost(), qdrant.getGrpcPort(), false).withApiKey(apiKey).build()
);

QdrantOuterClass.HealthCheckReply healthCheckReply = client.healthCheckAsync().get();
assertThat(healthCheckReply.getVersion()).isEqualTo("1.7.4");

client.close();
}
}
}