Upgrade Pinecone java client to 4.0.1 (#2328)

- Upgrade the java client from 0.8.0 to 4.0.1
   - Use io.pinecone.clients.Pinecone to setup the client configuration with the API key
     - Remove projectId, environment and other deprecated client configurations
   - Update upsert, delete, search operations with the new client
   - Remove the projectID and Environment configurations from the builder
   - Updated the Pinecone vectorstore autoconfiguration
   - Update tests

Signed-off-by: Ilayaperumal Gopinathan <ilayaperumal.gopinathan@broadcom.com>

Disable autoconfig IT until the auto-configuration is modularised
This commit is contained in:
Ilayaperumal Gopinathan
2025-02-26 23:09:34 +00:00
committed by GitHub
parent 96c8157cbe
commit c91163b6a3
9 changed files with 52 additions and 210 deletions

View File

@@ -217,7 +217,10 @@
<coherence.version>24.09</coherence.version>
<milvus.version>2.5.4</milvus.version>
<gemfire.testcontainers.version>2.3.0</gemfire.testcontainers.version>
<pinecone.version>0.8.0</pinecone.version>
<pinecone.version>4.0.1</pinecone.version>
<pinecone.protobuf-java-util.version>4.29.3</pinecone.protobuf-java-util.version>
<fastjson2.version>2.0.46</fastjson2.version>
<azure-core.version>1.53.0</azure-core.version>
<azure-json.version>1.3.0</azure-json.version>

View File

@@ -7,15 +7,13 @@ link:https://www.pinecone.io/[Pinecone] is a popular cloud-based vector database
== Prerequisites
1. Pinecone Account: Before you start, sign up for a link:https://app.pinecone.io/[Pinecone account].
2. Pinecone Project: Once registered, create a new project, an index, and generate an API key. You'll need these details for configuration.
2. Pinecone Project: Once registered, generate an API key and create and index. You'll need these details for configuration.
3. `EmbeddingModel` instance to compute the document embeddings. Several options are available:
- If required, an API key for the xref:api/embeddings.adoc#available-implementations[EmbeddingModel] to generate the embeddings stored by the `PineconeVectorStore`.
To set up `PineconeVectorStore`, gather the following details from your Pinecone account:
* Pinecone API Key
* Pinecone Environment
* Pinecone Project ID
* Pinecone Index Name
* Pinecone Namespace
@@ -70,8 +68,6 @@ A simple configuration can either be provided via Spring Boot's _application.pro
[source,properties]
----
spring.ai.vectorstore.pinecone.apiKey=<your api key>
spring.ai.vectorstore.pinecone.environment=<your environment>
spring.ai.vectorstore.pinecone.projectId=<your project id>
spring.ai.vectorstore.pinecone.index-name=<your index name>
# API key if needed, e.g. OpenAI
@@ -109,8 +105,6 @@ You can use the following properties in your Spring Boot configuration to custom
|Property| Description | Default value
|`spring.ai.vectorstore.pinecone.api-key`| Pinecone API Key | -
|`spring.ai.vectorstore.pinecone.environment`| Pinecone environment | `gcp-starter`
|`spring.ai.vectorstore.pinecone.project-id`| Pinecone project ID | -
|`spring.ai.vectorstore.pinecone.index-name`| Pinecone index name | -
|`spring.ai.vectorstore.pinecone.namespace`| Pinecone namespace | -
|`spring.ai.vectorstore.pinecone.content-field-name`| Pinecone metadata field name used to store the original text content. | `document_content`
@@ -191,8 +185,6 @@ To configure Pinecone in your application, you can use the following setup:
public VectorStore pineconeVectorStore(EmbeddingModel embeddingModel) {
return PineconeVectorStore.builder(embeddingModel)
.apiKey(PINECONE_API_KEY)
.projectId(PINECONE_PROJECT_ID)
.environment(PINECONE_ENVIRONMENT)
.indexName(PINECONE_INDEX_NAME)
.namespace(PINECONE_NAMESPACE) // the free tier doesn't support namespaces.
.contentFieldName(CUSTOM_CONTENT_FIELD_NAME) // optional field to store the original content. Defaults to `document_content`

View File

@@ -56,13 +56,10 @@ public class PineconeVectorStoreAutoConfiguration {
return PineconeVectorStore.builder(embeddingModel)
.apiKey(properties.getApiKey())
.projectId(properties.getProjectId())
.environment(properties.getEnvironment())
.indexName(properties.getIndexName())
.namespace(properties.getNamespace())
.contentFieldName(properties.getContentFieldName())
.distanceMetadataFieldName(properties.getDistanceMetadataFieldName())
.serverSideTimeout(properties.getServerSideTimeout())
.observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP))
.customObservationConvention(customObservationConvention.getIfAvailable(() -> null))
.batchingStrategy(batchingStrategy)

View File

@@ -26,6 +26,7 @@ import java.util.concurrent.TimeUnit;
import io.micrometer.observation.tck.TestObservationRegistry;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
@@ -51,14 +52,13 @@ import static org.hamcrest.Matchers.hasSize;
* @author Thomas Vitale
*/
@EnabledIfEnvironmentVariable(named = "PINECONE_API_KEY", matches = ".+")
@Disabled("Can be re-enabled once the auto-configuration is modularised")
public class PineconeVectorStoreAutoConfigurationIT {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(PineconeVectorStoreAutoConfiguration.class))
.withUserConfiguration(Config.class)
.withPropertyValues("spring.ai.vectorstore.pinecone.apiKey=" + System.getenv("PINECONE_API_KEY"),
"spring.ai.vectorstore.pinecone.environment=gcp-starter",
"spring.ai.vectorstore.pinecone.projectId=814621f",
"spring.ai.vectorstore.pinecone.indexName=spring-ai-test-index",
"spring.ai.vectorstore.pinecone.contentFieldName=customContentField",
"spring.ai.vectorstore.pinecone.distanceMetadataFieldName=customDistanceField");

View File

@@ -18,8 +18,10 @@ package org.springframework.ai.test.vectorstore;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.anyOf;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.Matchers.either;
import java.time.Duration;
import java.util.HashMap;

View File

@@ -50,43 +50,13 @@
<dependency>
<groupId>io.pinecone</groupId>
<artifactId>pinecone-client</artifactId>
<exclusions>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
</exclusion>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
</exclusion>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
</exclusion>
</exclusions>
<version>${pinecone.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<version>1.59.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.59.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.59.1</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>${protobuf-java.version}</version>
<version>${pinecone.protobuf-java-util.version}</version>
</dependency>
<!-- TESTING -->
@@ -113,7 +83,6 @@
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>

View File

@@ -16,7 +16,7 @@
package org.springframework.ai.vectorstore.pinecone;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -27,15 +27,10 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.protobuf.Struct;
import com.google.protobuf.Value;
import com.google.protobuf.util.JsonFormat;
import io.pinecone.PineconeClient;
import io.pinecone.PineconeClientConfig;
import io.pinecone.PineconeConnection;
import io.pinecone.PineconeConnectionConfig;
import io.pinecone.proto.DeleteRequest;
import io.pinecone.clients.Pinecone;
import io.pinecone.proto.QueryRequest;
import io.pinecone.proto.QueryResponse;
import io.pinecone.proto.UpsertRequest;
import io.pinecone.proto.Vector;
import io.pinecone.unsigned_indices_model.QueryResponseWithUnsignedIndices;
import io.pinecone.unsigned_indices_model.VectorWithUnsignedIndices;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -65,6 +60,7 @@ import org.springframework.util.StringUtils;
* @author Adam Bchouti
* @author Soby Chacko
* @author Thomas Vitale
* @author Ilayaperumal Gopinathan
*/
public class PineconeVectorStore extends AbstractObservationVectorStore {
@@ -72,8 +68,6 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
public final FilterExpressionConverter filterExpressionConverter = new PineconeFilterExpressionConverter();
private final PineconeConnection pineconeConnection;
private final String pineconeNamespace;
private final String pineconeIndexName;
@@ -82,6 +76,8 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
private final String pineconeDistanceMetadataFieldName;
private final Pinecone pinecone;
private final ObjectMapper objectMapper;
private static final Logger logger = LoggerFactory.getLogger(PineconeVectorStore.class);
@@ -94,8 +90,6 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
super(builder);
Assert.hasText(builder.apiKey, "ApiKey must not be null or empty");
Assert.hasText(builder.projectId, "ProjectId must not be null or empty");
Assert.hasText(builder.environment, "Environment must not be null or empty");
Assert.hasText(builder.indexName, "IndexName must not be null or empty");
this.pineconeNamespace = builder.namespace;
@@ -103,28 +97,10 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
this.pineconeContentFieldName = builder.contentFieldName;
this.pineconeDistanceMetadataFieldName = builder.distanceMetadataFieldName;
PineconeClientConfig clientConfig = new PineconeClientConfig().withApiKey(builder.apiKey)
.withEnvironment(builder.environment)
.withProjectName(builder.projectId)
.withServerSideTimeoutSec((int) builder.serverSideTimeout.toSeconds());
PineconeConnectionConfig connectionConfig = new PineconeConnectionConfig().withIndexName(builder.indexName);
this.pineconeConnection = new PineconeClient(clientConfig).connect(connectionConfig);
this.pinecone = new Pinecone.Builder(builder.apiKey).build();
this.objectMapper = new ObjectMapper();
}
/**
* Creates a new builder instance for configuring a PineconeVectorStore.
* @return A new PineconeBuilder instance
* @deprecated use {@link #builder(EmbeddingModel)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M6")
public static Builder builder(EmbeddingModel embeddingModel, String apiKey, String projectId, String environment,
String indexName) {
return new Builder(embeddingModel, apiKey, projectId, environment, indexName);
}
/**
* Creates a new builder for constructing a PineconeVectorStore instance. This builder
* implements a type-safe step pattern that guides users through the required
@@ -134,8 +110,6 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
* <ol>
* <li>embeddingModel (provided to this method)</li>
* <li>apiKey</li>
* <li>projectId</li>
* <li>environment</li>
* <li>indexName</li>
* </ol>
*
@@ -145,8 +119,6 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
* Example usage: <pre>{@code
* PineconeVectorStore store = PineconeVectorStore.builder(embeddingModel)
* .apiKey("your-api-key")
* .projectId("your-project")
* .environment("your-env")
* .indexName("your-index")
* .namespace("optional") // optional configuration
* .build();
@@ -167,20 +139,13 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
public void add(List<Document> documents, String namespace) {
List<float[]> embeddings = this.embeddingModel.embed(documents, EmbeddingOptionsBuilder.builder().build(),
this.batchingStrategy);
List<Vector> upsertVectors = documents.stream()
.map(document -> Vector.newBuilder()
.setId(document.getId())
.addAllValues(EmbeddingUtils.toList(embeddings.get(documents.indexOf(document))))
.setMetadata(metadataToStruct(document))
.build())
.toList();
UpsertRequest upsertRequest = UpsertRequest.newBuilder()
.addAllVectors(upsertVectors)
.setNamespace(namespace)
.build();
this.pineconeConnection.getBlockingStub().upsert(upsertRequest);
List<VectorWithUnsignedIndices> upsertVectors = new ArrayList<>();
for (Document document : documents) {
upsertVectors.add(io.pinecone.commons.IndexInterface.buildUpsertVectorWithUnsignedIndices(document.getId(),
EmbeddingUtils.toList(embeddings.get(documents.indexOf(document))), null, null,
metadataToStruct(document)));
}
this.pinecone.getIndexConnection(this.pineconeIndexName).upsert(upsertVectors, namespace);
}
/**
@@ -226,14 +191,7 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
* @param namespace The namespace of the document IDs.
*/
public void delete(List<String> documentIds, String namespace) {
DeleteRequest deleteRequest = DeleteRequest.newBuilder()
.setNamespace(namespace) // ignored for free tier.
.addAllIds(documentIds)
.setDeleteAll(false)
.build();
this.pineconeConnection.getBlockingStub().delete(deleteRequest);
this.pinecone.getIndexConnection(this.pineconeIndexName).delete(documentIds, false, namespace, null);
}
/**
@@ -262,7 +220,9 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
queryRequestBuilder.setFilter(metadataFiltersToStruct(nativeExpressionFilters));
}
QueryResponse queryResponse = this.pineconeConnection.getBlockingStub().query(queryRequestBuilder.build());
QueryResponseWithUnsignedIndices queryResponse = this.pinecone.getIndexConnection(this.pineconeIndexName)
.queryByVector(request.getTopK(), EmbeddingUtils.toList(queryEmbedding), namespace,
metadataFiltersToStruct(nativeExpressionFilters), false, true);
return queryResponse.getMatchesList()
.stream()
@@ -321,9 +281,12 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
private Struct metadataFiltersToStruct(String metadataFilters) {
try {
var structBuilder = Struct.newBuilder();
JsonFormat.parser().ignoringUnknownFields().merge(metadataFilters, structBuilder);
return structBuilder.build();
if (StringUtils.hasText(metadataFilters)) {
var structBuilder = Struct.newBuilder();
JsonFormat.parser().ignoringUnknownFields().merge(metadataFilters, structBuilder);
return structBuilder.build();
}
return null;
}
catch (Exception e) {
throw new RuntimeException(e);
@@ -362,7 +325,7 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
@Override
public <T> Optional<T> getNativeClient() {
@SuppressWarnings("unchecked")
T client = (T) this.pineconeConnection;
T client = (T) this.pinecone;
return Optional.of(client);
}
@@ -372,7 +335,7 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
* specific order before optional configuration.
*
* The required fields must be provided in this sequence: 1. embeddingModel (via
* builder method) 2. apiKey 3. projectId 4. environment 5. indexName
* builder method) 2. apiKey 3. indexName
*
* After all required fields are set, optional configurations can be provided using
* the fluent builder pattern.
@@ -380,8 +343,6 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
* Example usage: <pre>{@code
* PineconeVectorStore store = PineconeVectorStore.builder(embeddingModel)
* .apiKey("your-api-key")
* .projectId("your-project")
* .environment("your-env")
* .indexName("your-index")
* .namespace("optional") // optional configuration
* .build();
@@ -392,12 +353,6 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
/** Required field for Pinecone API authentication */
private final String apiKey;
/** Required field identifying the Pinecone project */
private final String projectId;
/** Required field specifying the Pinecone environment (e.g. "gcp-starter") */
private final String environment;
/** Required field specifying the Pinecone index name */
private final String indexName;
@@ -408,14 +363,9 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
private String distanceMetadataFieldName = DocumentMetadata.DISTANCE.value();
private Duration serverSideTimeout = Duration.ofSeconds(20);
private Builder(EmbeddingModel embeddingModel, String apiKey, String projectId, String environment,
String indexName) {
private Builder(EmbeddingModel embeddingModel, String apiKey, String indexName) {
super(embeddingModel);
this.apiKey = apiKey;
this.projectId = projectId;
this.environment = environment;
this.indexName = indexName;
}
@@ -451,16 +401,6 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
return this;
}
/**
* Sets the server-side timeout.
* @param serverSideTimeout The timeout duration to use
* @return The builder instance
*/
public Builder serverSideTimeout(@Nullable Duration serverSideTimeout) {
this.serverSideTimeout = serverSideTimeout != null ? serverSideTimeout : Duration.ofSeconds(20);
return this;
}
/**
* Builds a new PineconeVectorStore instance with the configured properties.
* @return A new PineconeVectorStore instance
@@ -477,42 +417,12 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
public interface BuilderWithApiKey {
/**
* Sets the Pinecone API key and moves to project ID configuration.
* Sets the Pinecone API key and moves to index name configuration.
* @param apiKey The Pinecone API key
* @return The next builder step for project ID
* @return The next builder step for index name
* @throws IllegalArgumentException if apiKey is null or empty
*/
BuilderWithProjectId apiKey(String apiKey);
}
/**
* Second step interface requiring project ID configuration.
*/
public interface BuilderWithProjectId {
/**
* Sets the project ID and moves to environment configuration.
* @param projectId The Pinecone project ID
* @return The next builder step for environment
* @throws IllegalArgumentException if projectId is null or empty
*/
BuilderWithEnvironment projectId(String projectId);
}
/**
* Third step interface requiring environment configuration.
*/
public interface BuilderWithEnvironment {
/**
* Sets the environment and moves to index name configuration.
* @param environment The Pinecone environment
* @return The next builder step for index name
* @throws IllegalArgumentException if environment is null or empty
*/
BuilderWithIndexName environment(String environment);
BuilderWithIndexName apiKey(String apiKey);
}
@@ -552,35 +462,17 @@ public class PineconeVectorStore extends AbstractObservationVectorStore {
private record ApiKeyStep(EmbeddingModel embeddingModel) implements BuilderWithApiKey {
@Override
public BuilderWithProjectId apiKey(String apiKey) {
public BuilderWithIndexName apiKey(String apiKey) {
Assert.hasText(apiKey, "ApiKey must not be null or empty");
return new ProjectIdStep(this.embeddingModel, apiKey);
return new IndexNameStep(this.embeddingModel, apiKey);
}
}
private record ProjectIdStep(EmbeddingModel embeddingModel, String apiKey) implements BuilderWithProjectId {
@Override
public BuilderWithEnvironment projectId(String projectId) {
Assert.hasText(projectId, "ProjectId must not be null or empty");
return new EnvironmentStep(this.embeddingModel, this.apiKey, projectId);
}
}
private record EnvironmentStep(EmbeddingModel embeddingModel, String apiKey,
String projectId) implements BuilderWithEnvironment {
@Override
public BuilderWithIndexName environment(String environment) {
Assert.hasText(environment, "Environment must not be null or empty");
return new IndexNameStep(this.embeddingModel, this.apiKey, this.projectId, environment);
}
}
private record IndexNameStep(EmbeddingModel embeddingModel, String apiKey, String projectId,
String environment) implements BuilderWithIndexName {
private record IndexNameStep(EmbeddingModel embeddingModel, String apiKey) implements BuilderWithIndexName {
@Override
public Builder indexName(String indexName) {
Assert.hasText(indexName, "IndexName must not be null or empty");
return new Builder(this.embeddingModel, this.apiKey, this.projectId, this.environment, indexName);
return new Builder(this.embeddingModel, this.apiKey, indexName);
}
}

View File

@@ -18,6 +18,7 @@ package org.springframework.ai.vectorstore.pinecone;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -27,9 +28,8 @@ import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import io.pinecone.PineconeConnection;
import io.pinecone.clients.Pinecone;
import org.awaitility.Awaitility;
import org.awaitility.Duration;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
@@ -56,16 +56,11 @@ import static org.hamcrest.Matchers.hasSize;
* @author Christian Tzolov
* @author Thomas Vitale
* @author Soby Chacko
* @author Ilayaperumal Gopinathan
*/
@EnabledIfEnvironmentVariable(named = "PINECONE_API_KEY", matches = ".+")
public class PineconeVectorStoreIT extends BaseVectorStoreTests {
// Replace the PINECONE_ENVIRONMENT, PINECONE_PROJECT_ID, PINECONE_INDEX_NAME and
// PINECONE_API_KEY with your pinecone credentials.
private static final String PINECONE_ENVIRONMENT = "gcp-starter";
private static final String PINECONE_PROJECT_ID = "814621f";
private static final String PINECONE_INDEX_NAME = "spring-ai-test-index";
// NOTE: Leave it empty as for free tier as later doesn't support namespaces.
@@ -97,7 +92,7 @@ public class PineconeVectorStoreIT extends BaseVectorStoreTests {
public static void beforeAll() {
Awaitility.setDefaultPollInterval(2, TimeUnit.SECONDS);
Awaitility.setDefaultPollDelay(Duration.ZERO);
Awaitility.setDefaultTimeout(Duration.ONE_MINUTE);
Awaitility.setDefaultTimeout(Duration.ofMinutes(1));
}
@Override
@@ -332,7 +327,7 @@ public class PineconeVectorStoreIT extends BaseVectorStoreTests {
void getNativeClientTest() {
this.contextRunner.run(context -> {
PineconeVectorStore vectorStore = context.getBean(PineconeVectorStore.class);
Optional<PineconeConnection> nativeClient = vectorStore.getNativeClient();
Optional<Pinecone> nativeClient = vectorStore.getNativeClient();
assertThat(nativeClient).isPresent();
});
}
@@ -395,8 +390,6 @@ public class PineconeVectorStoreIT extends BaseVectorStoreTests {
return PineconeVectorStore.builder(embeddingModel)
.apiKey(apikey)
.projectId(PINECONE_PROJECT_ID)
.environment(PINECONE_ENVIRONMENT)
.indexName(PINECONE_INDEX_NAME)
.namespace(PINECONE_NAMESPACE)
.contentFieldName(CUSTOM_CONTENT_FIELD_NAME)

View File

@@ -18,6 +18,7 @@ package org.springframework.ai.vectorstore.pinecone;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -26,7 +27,6 @@ import io.micrometer.observation.ObservationRegistry;
import io.micrometer.observation.tck.TestObservationRegistry;
import io.micrometer.observation.tck.TestObservationRegistryAssert;
import org.awaitility.Awaitility;
import org.awaitility.Duration;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
@@ -58,10 +58,6 @@ import static org.hamcrest.Matchers.hasSize;
@EnabledIfEnvironmentVariable(named = "PINECONE_API_KEY", matches = ".+")
public class PineconeVectorStoreObservationIT {
private static final String PINECONE_ENVIRONMENT = "gcp-starter";
private static final String PINECONE_PROJECT_ID = "814621f";
private static final String PINECONE_INDEX_NAME = "spring-ai-test-index";
// NOTE: Leave it empty as for free tier as later doesn't support namespaces.
@@ -91,7 +87,7 @@ public class PineconeVectorStoreObservationIT {
public static void beforeAll() {
Awaitility.setDefaultPollInterval(2, TimeUnit.SECONDS);
Awaitility.setDefaultPollDelay(Duration.ZERO);
Awaitility.setDefaultTimeout(Duration.ONE_MINUTE);
Awaitility.setDefaultTimeout(Duration.ofMinutes(1));
}
@Test
@@ -190,8 +186,6 @@ public class PineconeVectorStoreObservationIT {
public VectorStore vectorStore(EmbeddingModel embeddingModel, ObservationRegistry observationRegistry) {
return PineconeVectorStore.builder(embeddingModel)
.apiKey(System.getenv("PINECONE_API_KEY"))
.projectId(PINECONE_PROJECT_ID)
.environment(PINECONE_ENVIRONMENT)
.indexName(PINECONE_INDEX_NAME)
.namespace(PINECONE_NAMESPACE)
.contentFieldName(CUSTOM_CONTENT_FIELD_NAME)