Skip to content

Commit 6e109e3

Browse files
authored
Add index tags (#169)
## Problem Add support for Index tags. ## Solution Index tags can be passed as a Map<String, String> to the following operations: 1. create serverless index 2. create pod Index 3. configure serverless index 4. configure pod index When configuring tags, following are the special cases: 1. If an empty map is passed as an input, the tags will remain unchanged 2. If an empty value is passed as an input, the tag will be removed ## Type of Change - [ ] Bug fix (non-breaking change which fixes an issue) - [X] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update - [ ] Infrastructure change (CI configs, etc) - [ ] Non-code change (docs, etc) - [ ] None of the above: (explain here) ## Test Plan Updated integration tests for all 4 operations.
1 parent 1597b00 commit 6e109e3

File tree

7 files changed

+107
-65
lines changed

7 files changed

+107
-65
lines changed

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ serverless and regional availability, see [Understanding indexes](https://docs.p
171171
import io.pinecone.clients.Pinecone;
172172
import org.openapitools.db_control.client.model.IndexModel;
173173
import org.openapitools.db_control.client.model.DeletionProtection;
174+
import java.util.HashMap;
174175
...
175176

176177
Pinecone pinecone = new Pinecone.Builder("PINECONE_API_KEY").build();
@@ -180,8 +181,10 @@ String similarityMetric = "cosine";
180181
int dimension = 1538;
181182
String cloud = "aws";
182183
String region = "us-west-2";
184+
HashMap<String, String> tags = new HashMap<>();
185+
tags.put("env", "test");
183186

184-
IndexModel indexModel = pinecone.createServerlessIndex(indexName, similarityMetric, dimension, cloud, region, DeletionProtection.ENABLED);
187+
IndexModel indexModel = pinecone.createServerlessIndex(indexName, similarityMetric, dimension, cloud, region, DeletionProtection.ENABLED, tags);
185188
```
186189

187190
### Create a pod index
@@ -309,12 +312,16 @@ The following example enables deletion protection for a serverless index.
309312
```java
310313
import io.pinecone.clients.Pinecone;
311314
import org.openapitools.db_control.client.model.DeletionProtection;
315+
import java.util.HashMap;
312316
...
313317

314318
Pinecone pinecone = new Pinecone.Builder("PINECONE_API_KEY").build();
315319

316320
String indexName = "example-index";
317-
pinecone.configureServerlessIndex(indexName, DeletionProtection.ENABLED);
321+
HashMap<String, String> tags = new HashMap<>();
322+
tags.put("env", "test");
323+
324+
pinecone.configureServerlessIndex(indexName, DeletionProtection.ENABLED, tags);
318325
```
319326

320327
## Describe index statistics

src/integration/java/io/pinecone/helpers/TestResourcesManager.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.slf4j.LoggerFactory;
1111

1212
import java.util.Arrays;
13+
import java.util.HashMap;
1314
import java.util.List;
1415

1516
import static io.pinecone.helpers.BuildUpsertRequest.buildRequiredUpsertRequestByDimension;
@@ -315,9 +316,11 @@ public String getOrCreateServerlessIndex() throws InterruptedException, Pinecone
315316
}
316317

317318
String indexName = RandomStringBuilder.build("serverless-index", 8);
319+
HashMap<String, String> tags = new HashMap<>();
320+
tags.put("env", "testing");
318321

319322
serverlessIndexModel = pineconeClient.createServerlessIndex(indexName, metric, dimension, cloud,
320-
region, DeletionProtection.DISABLED);
323+
region, DeletionProtection.DISABLED, tags);
321324
waitUntilIndexIsReady(pineconeClient, indexName);
322325

323326
// Explicitly wait after ready to avoid the "no healthy upstream" issue

src/integration/java/io/pinecone/integration/controlPlane/serverless/CreateDescribeListAndDeleteIndexTest.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.openapitools.db_control.client.model.*;
1111

1212
import java.util.Arrays;
13+
import java.util.Collections;
1314

1415
import static org.junit.jupiter.api.Assertions.*;
1516

@@ -48,7 +49,7 @@ public void describeAndListIndex() {
4849
@Test
4950
public void createServerlessIndexWithInvalidName() {
5051
try {
51-
controlPlaneClient.createServerlessIndex("Invalid-name", "cosine", 3, "aws", "us-west-2", DeletionProtection.DISABLED);
52+
controlPlaneClient.createServerlessIndex("Invalid-name", "cosine", 3, "aws", "us-west-2", DeletionProtection.DISABLED, null);
5253

5354
fail("Expected to throw PineconeBadRequestException");
5455
} catch (PineconeBadRequestException expected) {
@@ -59,7 +60,7 @@ public void createServerlessIndexWithInvalidName() {
5960
@Test
6061
public void createServerlessIndexWithInvalidDimension() {
6162
try {
62-
controlPlaneClient.createServerlessIndex("serverless-test-index", "cosine", -3, "aws", "us-west-2", DeletionProtection.DISABLED);
63+
controlPlaneClient.createServerlessIndex("serverless-test-index", "cosine", -3, "aws", "us-west-2", DeletionProtection.DISABLED, null);
6364
fail("Expected to throw PineconeValidationException");
6465
} catch (PineconeValidationException expected) {
6566
assertTrue(expected.getLocalizedMessage().contains("Dimension must be greater than 0"));
@@ -69,7 +70,7 @@ public void createServerlessIndexWithInvalidDimension() {
6970
@Test
7071
public void createServerlessIndexWithInvalidCloud() {
7172
try {
72-
controlPlaneClient.createServerlessIndex("serverless-test-index", "cosine", 3, "blah", "us-west-2", DeletionProtection.DISABLED);
73+
controlPlaneClient.createServerlessIndex("serverless-test-index", "cosine", 3, "blah", "us-west-2", DeletionProtection.DISABLED, null);
7374
fail("Expected to throw PineconeValidationException");
7475
} catch (PineconeValidationException expected) {
7576
assertTrue(expected.getLocalizedMessage().contains("Cloud cannot be null or empty. Must be one of " + Arrays.toString(ServerlessSpec.CloudEnum.values())));
@@ -79,7 +80,7 @@ public void createServerlessIndexWithInvalidCloud() {
7980
@Test
8081
public void createServerlessIndexWithInvalidRegion() {
8182
try {
82-
controlPlaneClient.createServerlessIndex("serverless-test-index", "cosine", 3, "aws", "invalid-region", DeletionProtection.DISABLED);
83+
controlPlaneClient.createServerlessIndex("serverless-test-index", "cosine", 3, "aws", "invalid-region", DeletionProtection.DISABLED, null);
8384
fail("Expected to throw PineconeNotFoundException");
8485
} catch (PineconeNotFoundException expected) {
8586
assertTrue(expected.getLocalizedMessage().contains("Resource cloud: aws region: invalid-region not found"));

src/integration/java/io/pinecone/integration/controlPlane/serverless/DeletionProtectionTest.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import org.openapitools.db_control.client.model.DeletionProtection;
88
import org.openapitools.db_control.client.model.IndexModel;
99

10+
import java.util.HashMap;
11+
import java.util.Map;
12+
1013
public class DeletionProtectionTest {
1114
private static final Pinecone controlPlaneClient = new Pinecone
1215
.Builder(System.getenv("PINECONE_API_KEY"))
@@ -16,29 +19,37 @@ public class DeletionProtectionTest {
1619
@Test
1720
public void createIndexWithDeletionProtectionEnabled() {
1821
String indexName = RandomStringBuilder.build("create-serv", 8);
22+
HashMap<String, String> expectedTags = new HashMap<>();
23+
expectedTags.put("test", "deletion-protection-enabled");
1924
// Create serverless index with deletion protection enabled
20-
controlPlaneClient.createServerlessIndex(indexName, "cosine", 3, "aws", "us-west-2", DeletionProtection.ENABLED);
25+
controlPlaneClient.createServerlessIndex(indexName, "cosine", 3, "aws", "us-west-2", DeletionProtection.ENABLED, expectedTags);
2126
// Describe index to verify deletion protection is enabled
2227
IndexModel indexModel = controlPlaneClient.describeIndex(indexName);
2328
DeletionProtection deletionProtection = indexModel.getDeletionProtection();
2429
Assertions.assertEquals(deletionProtection, DeletionProtection.ENABLED);
30+
Map<String, String> actualTags = indexModel.getTags();
31+
Assertions.assertEquals(expectedTags, actualTags);
2532
}
2633

2734
@Test
2835
public void createPodIndexWithDeletionProtectionDisabled() {
2936
String indexName = RandomStringBuilder.build("create-pod", 8);
37+
HashMap<String, String> expectedTags = new HashMap<>();
38+
expectedTags.put("test", "deletion-protection-disabled");
3039
// Create serverless index with deletion protection disabled
31-
controlPlaneClient.createServerlessIndex(indexName, "cosine", 3, "aws", "us-west-2", DeletionProtection.DISABLED);
40+
controlPlaneClient.createServerlessIndex(indexName, "cosine", 3, "aws", "us-west-2", DeletionProtection.DISABLED, expectedTags);
3241
IndexModel indexModel = controlPlaneClient.describeIndex(indexName);
3342
DeletionProtection deletionProtection = indexModel.getDeletionProtection();
3443
Assertions.assertEquals(deletionProtection, DeletionProtection.DISABLED);
44+
Map<String, String> actualTags = indexModel.getTags();
45+
Assertions.assertEquals(expectedTags, actualTags);
3546
// Configure index to enable deletionProtection
36-
controlPlaneClient.configureServerlessIndex(indexName, DeletionProtection.ENABLED);
47+
controlPlaneClient.configureServerlessIndex(indexName, DeletionProtection.ENABLED, expectedTags);
3748
indexModel = controlPlaneClient.describeIndex(indexName);
3849
deletionProtection = indexModel.getDeletionProtection();
3950
Assertions.assertEquals(deletionProtection, DeletionProtection.ENABLED);
4051
// Configure index to disable deletionProtection
41-
controlPlaneClient.configureServerlessIndex(indexName, DeletionProtection.DISABLED);
52+
controlPlaneClient.configureServerlessIndex(indexName, DeletionProtection.DISABLED, expectedTags);
4253
// Delete index
4354
controlPlaneClient.deleteIndex(indexName);
4455
}

src/integration/java/io/pinecone/integration/dataPlane/ListEndpointTest.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
import static org.junit.jupiter.api.Assertions.*;
1414

15-
1615
public class ListEndpointTest {
1716
private static final TestResourcesManager indexManager = TestResourcesManager.getInstance();
1817
private static Index indexConnection;
@@ -70,13 +69,6 @@ public void testSyncListEndpoint() throws InterruptedException {
7069
listResponseWithPaginationNoPrefix1.getPagination().getNext()
7170
);
7271
assertEquals(listResponseWithPaginationNoPrefix2.getVectorsList().size(), 2);
73-
ListResponse listResponseWithPaginationNoPrefix3 = indexConnection.list(
74-
customNamespace,
75-
2,
76-
listResponseWithPaginationNoPrefix2.getPagination().getNext()
77-
);
78-
assertEquals(listResponseWithPaginationNoPrefix3.getVectorsList().size(), 0);
79-
assertEquals(listResponseWithPaginationNoPrefix3.getPagination().getNext(), "");
8072
}
8173

8274
@Test
@@ -122,14 +114,5 @@ public void testAsyncListEndpoint() throws InterruptedException {
122114
);
123115
ListResponse asyncListResponseWithPaginationNoPrefix2 = Futures.getUnchecked(futureResponseWithPaginationNoPrefix2);
124116
assertEquals(asyncListResponseWithPaginationNoPrefix2.getVectorsList().size(), 2);
125-
ListenableFuture<ListResponse> futureResponseWithPaginationNoPrefix3 = asyncIndexConnection.list(
126-
customNamespace,
127-
2,
128-
asyncListResponseWithPaginationNoPrefix2.getPagination().getNext()
129-
);
130-
ListResponse asyncListResponseWithPaginationNoPrefix3 = Futures.getUnchecked(futureResponseWithPaginationNoPrefix3);
131-
assertEquals(asyncListResponseWithPaginationNoPrefix3.getVectorsList().size(), 0);
132-
assertEquals(asyncListResponseWithPaginationNoPrefix3.getPagination().getNext(), "");
133117
}
134-
135118
}

0 commit comments

Comments
 (0)