Skip to content

Commit 8da48c1

Browse files
committed
adds support for getting nodes status per class
1 parent fe511b1 commit 8da48c1

File tree

3 files changed

+189
-1
lines changed

3 files changed

+189
-1
lines changed

src/main/java/io/weaviate/client/v1/cluster/api/NodesStatusGetter.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,34 @@
66
import io.weaviate.client.base.Response;
77
import io.weaviate.client.base.Result;
88
import io.weaviate.client.base.http.HttpClient;
9+
import io.weaviate.client.base.util.UrlEncoder;
910
import io.weaviate.client.v1.cluster.model.NodesStatusResponse;
11+
import org.apache.commons.lang3.StringUtils;
1012

1113
public class NodesStatusGetter extends BaseClient<NodesStatusResponse> implements ClientResult<NodesStatusResponse> {
1214

15+
private String className;
16+
1317
public NodesStatusGetter(HttpClient httpClient, Config config) {
1418
super(httpClient, config);
1519
}
1620

21+
public NodesStatusGetter withClassName(String className) {
22+
this.className = className;
23+
return this;
24+
}
25+
1726
@Override
1827
public Result<NodesStatusResponse> run() {
19-
Response<NodesStatusResponse> resp = sendGetRequest("/nodes", NodesStatusResponse.class);
28+
Response<NodesStatusResponse> resp = sendGetRequest(path(), NodesStatusResponse.class);
2029
return new Result<>(resp);
2130
}
31+
32+
private String path() {
33+
String path = "/nodes";
34+
if (StringUtils.isNotBlank(className)) {
35+
path = String.format("%s/%s", path, UrlEncoder.encodePathParam(className));
36+
}
37+
return path;
38+
}
2239
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package io.weaviate.integration.client.cluster;
2+
3+
import io.weaviate.client.Config;
4+
import io.weaviate.client.WeaviateClient;
5+
import io.weaviate.client.base.Result;
6+
import io.weaviate.client.base.util.TriConsumer;
7+
import io.weaviate.client.v1.cluster.model.NodesStatusResponse;
8+
import io.weaviate.integration.client.WeaviateTestGenerics;
9+
import org.junit.After;
10+
import org.junit.Before;
11+
import org.junit.ClassRule;
12+
import org.junit.Test;
13+
import org.testcontainers.containers.DockerComposeContainer;
14+
import org.testcontainers.containers.wait.strategy.Wait;
15+
16+
import java.io.File;
17+
import java.util.List;
18+
import java.util.function.Consumer;
19+
20+
import static io.weaviate.integration.client.WeaviateVersion.EXPECTED_WEAVIATE_GIT_HASH;
21+
import static io.weaviate.integration.client.WeaviateVersion.EXPECTED_WEAVIATE_VERSION;
22+
import static org.assertj.core.api.Assertions.assertThat;
23+
import static org.assertj.core.api.InstanceOfAssertFactories.ARRAY;
24+
25+
public class ClientClusterMultiTenancyTest {
26+
27+
private WeaviateClient client;
28+
private final WeaviateTestGenerics testGenerics = new WeaviateTestGenerics();
29+
30+
@ClassRule
31+
public static DockerComposeContainer<?> compose = new DockerComposeContainer<>(
32+
new File("src/test/resources/docker-compose-test.yaml")
33+
).withExposedService("weaviate_1", 8080, Wait.forHttp("/v1/.well-known/ready").forStatusCode(200));
34+
35+
@Before
36+
public void before() {
37+
String host = compose.getServiceHost("weaviate_1", 8080);
38+
Integer port = compose.getServicePort("weaviate_1", 8080);
39+
Config config = new Config("http", host + ":" + port);
40+
41+
client = new WeaviateClient(config);
42+
}
43+
44+
@After
45+
public void after() {
46+
testGenerics.cleanupWeaviate(client);
47+
}
48+
49+
50+
@Test
51+
public void shouldGetNodeStatusPerClass() {
52+
String[] pizzaTenants = new String[]{"TenantPizza1", "TenantPizza2"};
53+
String[] soupTenants = new String[]{"TenantSoup1", "TenantSoup2", "TenantSoup3"};
54+
List<String> pizzaIds = WeaviateTestGenerics.IDS_BY_CLASS.get("Pizza");
55+
List<String> soupIds = WeaviateTestGenerics.IDS_BY_CLASS.get("Soup");
56+
testGenerics.createSchemaPizzaForTenants(client);
57+
testGenerics.createTenantsPizza(client, pizzaTenants);
58+
testGenerics.createDataPizzaForTenants(client, pizzaTenants);
59+
testGenerics.createSchemaSoupForTenants(client);
60+
testGenerics.createTenantsSoup(client, soupTenants);
61+
testGenerics.createDataSoupForTenants(client, soupTenants);
62+
63+
Consumer<Result<NodesStatusResponse>> assertSingleNode = (Result<NodesStatusResponse> result) ->
64+
assertThat(result).isNotNull()
65+
.returns(false, Result::hasErrors)
66+
.extracting(Result::getResult).isNotNull()
67+
.extracting(NodesStatusResponse::getNodes).asInstanceOf(ARRAY)
68+
.hasSize(1);
69+
70+
TriConsumer<NodesStatusResponse.NodeStatus, Long, Long> assertCounts = (NodesStatusResponse.NodeStatus nodeStatus, Long shardCount, Long objectCount) -> {
71+
assertThat(nodeStatus.getName()).isNotBlank();
72+
assertThat(nodeStatus)
73+
.returns(EXPECTED_WEAVIATE_VERSION, NodesStatusResponse.NodeStatus::getVersion)
74+
.returns(EXPECTED_WEAVIATE_GIT_HASH, NodesStatusResponse.NodeStatus::getGitHash)
75+
.returns(NodesStatusResponse.Status.HEALTHY, NodesStatusResponse.NodeStatus::getStatus)
76+
.extracting(NodesStatusResponse.NodeStatus::getStats)
77+
.returns(shardCount, NodesStatusResponse.Stats::getShardCount)
78+
.returns(objectCount, NodesStatusResponse.Stats::getObjectCount);
79+
};
80+
81+
// ALL
82+
Result<NodesStatusResponse> resultAll = client.cluster()
83+
.nodesStatusGetter()
84+
.run();
85+
86+
long expectedAllShardCount = pizzaTenants.length + soupTenants.length;
87+
long expectedAllObjectsCount = pizzaTenants.length * pizzaIds.size() + soupTenants.length * soupIds.size();
88+
assertSingleNode.accept(resultAll);
89+
assertCounts.accept(resultAll.getResult().getNodes()[0], expectedAllShardCount, expectedAllObjectsCount);
90+
91+
// PIZZA
92+
Result<NodesStatusResponse> resultPizza = client.cluster()
93+
.nodesStatusGetter()
94+
.withClassName("Pizza")
95+
.run();
96+
97+
long expectedPizzaShardCount = pizzaTenants.length;
98+
long expectedPizzaObjectsCount = pizzaTenants.length * pizzaIds.size();
99+
assertSingleNode.accept(resultPizza);
100+
assertCounts.accept(resultPizza.getResult().getNodes()[0], expectedPizzaShardCount, expectedPizzaObjectsCount);
101+
102+
// SOUP
103+
Result<NodesStatusResponse> resultSoup = client.cluster()
104+
.nodesStatusGetter()
105+
.withClassName("Soup")
106+
.run();
107+
108+
long expectedSoupShardCount = soupTenants.length;
109+
long expectedSoupObjectsCount = soupTenants.length * soupIds.size();
110+
assertSingleNode.accept(resultSoup);
111+
assertCounts.accept(resultSoup.getResult().getNodes()[0], expectedSoupShardCount, expectedSoupObjectsCount);
112+
}
113+
}

src/test/java/io/weaviate/integration/client/cluster/ClientClusterTest.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.weaviate.integration.client.cluster;
22

3+
import io.weaviate.client.base.util.TriConsumer;
34
import org.junit.After;
45
import org.junit.Before;
56
import org.junit.ClassRule;
@@ -13,10 +14,13 @@
1314
import io.weaviate.integration.client.WeaviateTestGenerics;
1415

1516
import java.io.File;
17+
import java.util.List;
18+
import java.util.function.Consumer;
1619

1720
import static org.assertj.core.api.Assertions.assertThat;
1821
import static io.weaviate.integration.client.WeaviateVersion.EXPECTED_WEAVIATE_GIT_HASH;
1922
import static io.weaviate.integration.client.WeaviateVersion.EXPECTED_WEAVIATE_VERSION;
23+
import static org.assertj.core.api.InstanceOfAssertFactories.ARRAY;
2024

2125
public class ClientClusterTest {
2226

@@ -109,4 +113,58 @@ public void testClusterNodesEndpointWithData() {
109113
}
110114
}
111115
}
116+
117+
@Test
118+
public void shouldGetNodeStatusPerClass() {
119+
List<String> pizzaIds = WeaviateTestGenerics.IDS_BY_CLASS.get("Pizza");
120+
List<String> soupIds = WeaviateTestGenerics.IDS_BY_CLASS.get("Soup");
121+
testGenerics.createSchemaPizza(client);
122+
testGenerics.createDataPizza(client);
123+
testGenerics.createSchemaSoup(client);
124+
testGenerics.createDataSoup(client);
125+
126+
Consumer<Result<NodesStatusResponse>> assertSingleNode = (Result<NodesStatusResponse> result) ->
127+
assertThat(result).isNotNull()
128+
.returns(false, Result::hasErrors)
129+
.extracting(Result::getResult).isNotNull()
130+
.extracting(NodesStatusResponse::getNodes).asInstanceOf(ARRAY)
131+
.hasSize(1);
132+
133+
TriConsumer<NodesStatusResponse.NodeStatus, Long, Long> assertCounts = (NodesStatusResponse.NodeStatus nodeStatus, Long shardCount, Long objectCount) -> {
134+
assertThat(nodeStatus.getName()).isNotBlank();
135+
assertThat(nodeStatus)
136+
.returns(EXPECTED_WEAVIATE_VERSION, NodesStatusResponse.NodeStatus::getVersion)
137+
.returns(EXPECTED_WEAVIATE_GIT_HASH, NodesStatusResponse.NodeStatus::getGitHash)
138+
.returns(NodesStatusResponse.Status.HEALTHY, NodesStatusResponse.NodeStatus::getStatus)
139+
.extracting(NodesStatusResponse.NodeStatus::getStats)
140+
.returns(shardCount, NodesStatusResponse.Stats::getShardCount)
141+
.returns(objectCount, NodesStatusResponse.Stats::getObjectCount);
142+
};
143+
144+
// ALL
145+
Result<NodesStatusResponse> resultAll = client.cluster()
146+
.nodesStatusGetter()
147+
.run();
148+
149+
assertSingleNode.accept(resultAll);
150+
assertCounts.accept(resultAll.getResult().getNodes()[0], 2L, (long) (pizzaIds.size() + soupIds.size()));
151+
152+
// PIZZA
153+
Result<NodesStatusResponse> resultPizza = client.cluster()
154+
.nodesStatusGetter()
155+
.withClassName("Pizza")
156+
.run();
157+
158+
assertSingleNode.accept(resultPizza);
159+
assertCounts.accept(resultPizza.getResult().getNodes()[0], 1L, (long) pizzaIds.size());
160+
161+
// SOUP
162+
Result<NodesStatusResponse> resultSoup = client.cluster()
163+
.nodesStatusGetter()
164+
.withClassName("Soup")
165+
.run();
166+
167+
assertSingleNode.accept(resultSoup);
168+
assertCounts.accept(resultSoup.getResult().getNodes()[0], 1L, (long) soupIds.size());
169+
}
112170
}

0 commit comments

Comments
 (0)