Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unify the coding style of using testcontainers #48

Closed
wants to merge 10 commits into from
8 changes: 8 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash
export JDK21_HOME=/usr/local/opt/openjdk/libexec/openjdk.jdk/Contents/Home
Copy link
Collaborator

Choose a reason for hiding this comment

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

why is this required?

#export JDK17_HOME=/usr/local/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home
#export JDK11_HOME=/usr/local/opt/openjdk@11/libexec/openjdk.jdk/Contents/Home
#export JDK8_HOME=/usr/local/opt/openjdk@8/libexec/openjdk.jdk/Contents/Home

export JAVA_HOME=$JDK21_HOME
mvn install -DskipTests -Denforcer.skip=true
18 changes: 18 additions & 0 deletions elasticsearch-example/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<log4j.version>2.22.1</log4j.version>
</properties>

<dependencies>
Expand All @@ -34,6 +35,23 @@
<version>1.19.6</version>
</dependency>

<!-- Logging -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>${log4j.version}</version>
</dependency>

<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>elasticsearch</artifactId>
Copy link
Collaborator

Choose a reason for hiding this comment

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

there is another elasticsearch dep with other version above

<version>1.19.4</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,37 @@
import dev.langchain4j.store.embedding.EmbeddingMatch;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.elasticsearch.ElasticsearchEmbeddingStore;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.testcontainers.elasticsearch.ElasticsearchContainer;

import org.testcontainers.utility.DockerImageName;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class ElasticsearchEmbeddingStoreExample {

private static final Logger LOGGER = LogManager.getLogger(ElasticsearchEmbeddingStoreExample.class);

/**
* To run this example, ensure you have Elasticsearch running locally. If not, then:
* - Execute "docker pull docker.elastic.co/elasticsearch/elasticsearch:8.9.0"
* - Execute "docker run -d -p 9200:9200 -p 9300:9300 -e discovery.type=single-node -e xpack.security.enabled=false docker.elastic.co/elasticsearch/elasticsearch:8.9.0"
* - Wait until Elasticsearch is ready to serve (may take a few minutes)
*/

public static void main(String[] args) throws InterruptedException {
DockerImageName imageName = DockerImageName.parse("docker.elastic.co/elasticsearch/elasticsearch:8.9.0");
Map<String, String> env = new HashMap<>();
env.put("xpack.security.enabled", "false");
env.put("discovery.type", "single-node");

try (ElasticsearchContainer elastic = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:8.9.0")
.withEnv("xpack.security.enabled", "false")) {
try (ElasticsearchContainer elastic = new ElasticsearchContainer(imageName).withCertPath(null).withEnv(env)) {
elastic.start();

EmbeddingStore<TextSegment> embeddingStore = ElasticsearchEmbeddingStore.builder()
.serverUrl("http://" + elastic.getHttpHostAddress())
.serverUrl(elastic.getHttpHostAddress())
.dimension(384)
.build();

Expand All @@ -32,14 +49,19 @@ public static void main(String[] args) throws InterruptedException {
Embedding embedding2 = embeddingModel.embed(segment2).content();
embeddingStore.add(embedding2, segment2);

Thread.sleep(1000); // to be sure that embeddings were persisted
// to be sure that embeddings were persisted
TimeUnit.MILLISECONDS.sleep(1000);

Embedding queryEmbedding = embeddingModel.embed("What is your favourite sport?").content();
List<EmbeddingMatch<TextSegment>> relevant = embeddingStore.findRelevant(queryEmbedding, 1);
EmbeddingMatch<TextSegment> embeddingMatch = relevant.get(0);

System.out.println(embeddingMatch.score()); // 0.81442887
System.out.println(embeddingMatch.embedded().text()); // I like football.
// expected 0.8144288659095
LOGGER.info("Score: {}", embeddingMatch.score());
// expected "I like football."
LOGGER.info("Embedded: {}", embeddingMatch.embedded().text());
} catch (Exception e) {
LOGGER.error("Error: {}", e.getMessage());
}
}
}
14 changes: 14 additions & 0 deletions elasticsearch-example/src/main/resources/log4j2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{dd/MM/yyyy HH:mm:ss.SSS} | %-35.35c{1} | %-20.20M | %-8.8level | %highlight{%msg%n}"/>
</Console>
</Appenders>
<Loggers>
<Root level="info" includeLocation="true">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
18 changes: 18 additions & 0 deletions neo4j-example/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<log4j.version>2.22.1</log4j.version>
</properties>

<dependencies>
Expand All @@ -34,6 +35,23 @@
<version>1.19.6</version>
</dependency>

<!-- Logging -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>${log4j.version}</version>
</dependency>

<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>neo4j</artifactId>
Copy link
Collaborator

Choose a reason for hiding this comment

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

same here.
please double-check all your changes.

<version>1.19.4</version>
</dependency>
</dependencies>

</project>
33 changes: 27 additions & 6 deletions neo4j-example/src/main/java/Neo4jEmbeddingStoreExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,35 @@
import dev.langchain4j.store.embedding.EmbeddingMatch;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.neo4j.Neo4jEmbeddingStore;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.GraphDatabase;
import org.testcontainers.containers.Neo4jContainer;

import org.testcontainers.utility.DockerImageName;
import java.util.List;

public class Neo4jEmbeddingStoreExample {

private static final Logger LOGGER = LogManager.getLogger(Neo4jEmbeddingStoreExample.class);

/**
* To run this example, ensure you have Neo4j running locally,
* and change uri, username and password strings consistently.
* If not, then:
* - Execute "docker pull neo4j:latest"
* - Execute "docker run -d -p 7687:7687 --env NEO4J_AUTH=neo4j/password1234 neo4j:latest"
* - Wait until Neo4j is ready to serve (may take a few minutes)
*/

public static void main(String[] args) {
try (Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:5")) {
neo4j.start();
String username = "neo4j";
String password = "password1234";

try (Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>(DockerImageName.parse("neo4j:latest"))) {
neo4jContainer.withEnv("NEO4J_AUTH", username + "/" + password).start();
EmbeddingStore<TextSegment> embeddingStore = Neo4jEmbeddingStore.builder()
.withBasicAuth(neo4j.getBoltUrl(), "neo4j", neo4j.getAdminPassword())
.driver(GraphDatabase.driver(neo4jContainer.getBoltUrl(), AuthTokens.basic(username, password)))
.dimension(384)
.build();

Expand All @@ -33,8 +51,11 @@ public static void main(String[] args) {
List<EmbeddingMatch<TextSegment>> relevant = embeddingStore.findRelevant(queryEmbedding, 1);
EmbeddingMatch<TextSegment> embeddingMatch = relevant.get(0);

System.out.println(embeddingMatch.score()); // 0.8144289255142212
System.out.println(embeddingMatch.embedded().text()); // I like football.
LOGGER.info("Score: {}", embeddingMatch.score());
// expected "I like football."
LOGGER.info("Embedded: {}", embeddingMatch.embedded().text());
} catch (Exception e) {
LOGGER.error("Error: {}", e.getMessage());
}
}
}
14 changes: 14 additions & 0 deletions neo4j-example/src/main/resources/log4j2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{dd/MM/yyyy HH:mm:ss.SSS} | %-35.35c{1} | %-20.20M | %-8.8level | %highlight{%msg%n}"/>
</Console>
</Appenders>
<Loggers>
<Root level="info" includeLocation="true">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
1 change: 1 addition & 0 deletions ollama-examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<version>5.10.0</version>
</dependency>

<!-- Logging -->
<dependency>
<groupId>org.tinylog</groupId>
<artifactId>tinylog-impl</artifactId>
Expand Down
35 changes: 13 additions & 22 deletions ollama-examples/src/main/java/OllamaChatModelTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.tinylog.Logger;

@Testcontainers
class OllamaChatModelTest {
Expand All @@ -21,40 +22,30 @@ class OllamaChatModelTest {
* 2. Run "docker exec -it ollama ollama run mistral" <- specify the desired model here
*/

static String MODEL_NAME = "orca-mini"; // try "mistral", "llama2", "codellama", "phi" or "tinyllama"

@Container
static GenericContainer<?> ollama = new GenericContainer<>("langchain4j/ollama-" + MODEL_NAME + ":latest")
.withExposedPorts(11434);
private static GenericContainer<?> ollama = new GenericContainer<>(OllamaContants.OLLAMA_IMAGE_NAME).withExposedPorts(OllamaContants.OLLAMA_PORT);

@Test
void simple_example() {

void example() {
ChatLanguageModel model = OllamaChatModel.builder()
.baseUrl(baseUrl())
.modelName(MODEL_NAME)
.baseUrl(baseUrl(ollama))
.modelName(OllamaContants.MODEL_NAME)
.build();
simpleExample(model);
jsonOutputExample(model);
}

void simpleExample(ChatLanguageModel model) {
String answer = model.generate("Provide 3 short bullet points explaining why Java is awesome");

System.out.println(answer);
Logger.info("Answer: {}", answer);
}

@Test
void json_output_example() {

ChatLanguageModel model = OllamaChatModel.builder()
.baseUrl(baseUrl())
.modelName(MODEL_NAME)
.format("json")
.build();

void jsonOutputExample(ChatLanguageModel model) {
String json = model.generate("Give me a JSON with 2 fields: name and age of a John Doe, 42");

System.out.println(json);
Logger.info("JSON: {}", json);
}

static String baseUrl() {
static String baseUrl(GenericContainer<?> ollama) {
return String.format("http://%s:%d", ollama.getHost(), ollama.getFirstMappedPort());
}
}
14 changes: 14 additions & 0 deletions ollama-examples/src/main/java/OllamaContants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
public class OllamaContants {

static final String MODEL_ORCA_MINI = "orca-mini";
static final String MODEL_MISTRAL = "mistral";
static final String MODEL_LLAMA2 = "llama2";
static final String MODEL_CODE_LLAMA = "codellama";
static final String MODEL_PHI = "phi";
static final String MODEL_TINY_LLAMA = "tinyllama";

// try "mistral", "llama2", "codellama", "phi" or "tinyllama"
static final String MODEL_NAME = MODEL_ORCA_MINI;
public static final String OLLAMA_IMAGE_NAME = "langchain4j/ollama-" + MODEL_NAME + ":latest";
public static final Integer OLLAMA_PORT = 11434;
}
16 changes: 6 additions & 10 deletions ollama-examples/src/main/java/OllamaStreamingChatModelTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.tinylog.Logger;

import java.util.concurrent.CompletableFuture;

Expand All @@ -26,20 +27,15 @@ class OllamaStreamingChatModelTest {
* 2. Run "docker exec -it ollama ollama run llama2" <- specify the desired model here
*/

static String MODEL_NAME = "orca-mini"; // try "mistral", "llama2", "codellama" or "phi"
static String DOCKER_IMAGE_NAME = "langchain4j/ollama-" + MODEL_NAME + ":latest";
static Integer PORT = 11434;

@Container
static GenericContainer<?> ollama = new GenericContainer<>(DOCKER_IMAGE_NAME)
.withExposedPorts(PORT);
private static GenericContainer<?> ollama = new GenericContainer<>(OllamaContants.OLLAMA_IMAGE_NAME).withExposedPorts(OllamaContants.OLLAMA_PORT);

@Test
void streaming_example() {
void streamingExample() {

StreamingChatLanguageModel model = OllamaStreamingChatModel.builder()
.baseUrl(String.format("http://%s:%d", ollama.getHost(), ollama.getMappedPort(PORT)))
.modelName(MODEL_NAME)
.baseUrl(String.format("http://%s:%d", ollama.getHost(), ollama.getMappedPort(OllamaContants.OLLAMA_PORT)))
.modelName(OllamaContants.MODEL_NAME)
.temperature(0.0)
.build();

Expand All @@ -50,7 +46,7 @@ void streaming_example() {

@Override
public void onNext(String token) {
System.out.print(token);
Logger.info("Token: {}", token);
}

@Override
Expand Down
4 changes: 4 additions & 0 deletions ollama-examples/src/main/resources/tinylog.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#https://tinylog.org/v2/configuration/
writer = console
writer.level = info
writer.format = {date: HH:mm:ss.SSS} {{level}:|min-size=8} {message}
4 changes: 2 additions & 2 deletions open-ai-examples/src/main/java/OpenAiImageModelExamples.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiImageModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.retriever.EmbeddingStoreRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
Expand Down Expand Up @@ -76,7 +76,7 @@ public static void main(String[] args) throws URISyntaxException {
ConversationalRetrievalChain chain = ConversationalRetrievalChain
.builder()
.chatLanguageModel(OpenAiChatModel.builder().apiKey(System.getenv("OPENAI_API_KEY")).build())
.retriever(EmbeddingStoreRetriever.from(embeddingStore, embeddingModel))
.contentRetriever(new EmbeddingStoreContentRetriever(embeddingStore, embeddingModel))
.build();

PromptTemplate drawPromptTemplate = PromptTemplate.from(
Expand Down
1 change: 0 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,4 @@
<module>javafx-example</module>
<module>quarkus-example</module>
</modules>

</project>
Loading