Skip to content

Commit 95b4ecf

Browse files
authored
Add property query (#80)
1 parent ef2bd0d commit 95b4ecf

File tree

7 files changed

+247
-30
lines changed

7 files changed

+247
-30
lines changed

README.md

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,25 @@ Measure m = Measure.newBuilder()
289289
client.define(m);
290290
```
291291

292+
### Define a Property
293+
294+
```java
295+
// Define property schema
296+
BanyandbDatabase.Property propertyDef =
297+
BanyandbDatabase.Property.newBuilder()
298+
.setMetadata(Metadata.newBuilder()
299+
.setGroup("default")
300+
.setName("ui_template"))
301+
.addTags(
302+
TagSpec.newBuilder()
303+
.setName("name")
304+
.setType(
305+
TagType.TAG_TYPE_STRING))
306+
.build();
307+
308+
client.define(propertyDef);
309+
```
310+
292311
For more APIs usage, refer to test cases and API docs.
293312

294313
## Query
@@ -414,6 +433,31 @@ After response is returned, `trace` can be extracted,
414433
MeasureQueryResponse resp = client.query(query);
415434
Trace trace = resp.getTrace();
416435
```
436+
437+
### Property
438+
439+
Query properties:
440+
441+
```java
442+
BanyandbProperty.QueryRequest queryRequest = new PropertyQuery(Lists.newArrayList("default"), "ui_template", ImmutableSet.of("name")).build();
443+
BanyandbProperty.QueryResponse queryResponse = client.query(queryRequest);
444+
```
445+
446+
Query properties based on ID:
447+
448+
```java
449+
BanyandbProperty.QueryRequest queryRequest = new PropertyQuery(Lists.newArrayList("default"), "ui_template", ImmutableSet.of("name")).id("dashboard-1").build();
450+
BanyandbProperty.QueryResponse queryResponse = client.query(queryRequest);
451+
```
452+
453+
Query properties based on tags:
454+
455+
```java
456+
PropertyQuery pQuery = new PropertyQuery(Lists.newArrayList("default"), "ui_template", ImmutableSet.of("name"));
457+
pQuery.criteria(PairQueryCondition.StringQueryCondition.eq("name", "foo"));
458+
BanyandbProperty.QueryResponse resp = client.query(pQuery.build());
459+
```
460+
417461
### Criteria
418462

419463
Both `StreamQuery` and `MeausreQuery` support the `criteria` flag to filter data.
@@ -525,28 +569,10 @@ MeasureWrite measureWrite = client.createMeasureWrite("sw_metric", "service_cpm_
525569
CompletableFuture<Void> f = measureBulkWriteProcessor.add(measureWrite);
526570
f.get(10, TimeUnit.SECONDS);
527571
```
528-
# Property APIs
529-
530-
Before using properties, you need to define a property schema:
531-
532-
```java
533-
// Define property schema
534-
BanyandbDatabase.Property propertyDef =
535-
BanyandbDatabase.Property.newBuilder()
536-
.setMetadata(Metadata.newBuilder()
537-
.setGroup("default")
538-
.setName("sw"))
539-
.addTags(
540-
TagSpec.newBuilder()
541-
.setName("name")
542-
.setType(
543-
TagType.TAG_TYPE_STRING))
544-
.build();
545572

546-
client.define(propertyDef);
547-
```
573+
### Property
548574

549-
After defining the schema, you can apply (create/update) properties:
575+
Unlike `Stream` and `Measure`, `Property` is a single write operation. The `Property` object is created and sent to the server.
550576

551577
```java
552578
// Apply a property (create or update)
@@ -570,18 +596,13 @@ You can also apply with a specific strategy:
570596
ApplyResponse response = client.apply(property, Strategy.STRATEGY_MERGE);
571597
```
572598

573-
Query properties:
599+
## Delete
574600

575-
```java
576-
// Query properties
577-
BanyandbProperty.QueryRequest queryRequest = BanyandbProperty.QueryRequest.newBuilder()
578-
.setMetadata(Metadata.newBuilder()
579-
.setGroup("default")
580-
.setName("ui_template"))
581-
.build();
601+
### Stream and Measure
582602

583-
BanyandbProperty.QueryResponse queryResponse = client.query(queryRequest);
584-
```
603+
The `Stream` and `Measure` are deleted by the TTL mechanism. You can set the TTL when defining the group schema.
604+
605+
### Property
585606

586607
Delete a property:
587608

src/main/java/org/apache/skywalking/banyandb/v1/client/MeasureQuery.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ public class MeasureQuery extends AbstractQuery<BanyandbMeasure.QueryRequest> {
5050

5151
private OrderBy orderBy;
5252

53+
private String nodeSelector;
54+
5355
public MeasureQuery(final List<String> groups, final String name, final Set<String> tagProjections, final Set<String> fieldProjections) {
5456
this(groups, name, null, tagProjections, fieldProjections);
5557
}
@@ -136,6 +138,11 @@ public MeasureQuery offset(int offset) {
136138
return this;
137139
}
138140

141+
public MeasureQuery nodeSelector(String nodeSelector) {
142+
this.nodeSelector = nodeSelector;
143+
return this;
144+
}
145+
139146
/**
140147
* @return QueryRequest for gRPC level query.
141148
*/
@@ -161,6 +168,9 @@ BanyandbMeasure.QueryRequest build(MetadataCache.EntityMetadata entityMetadata)
161168
.addAllNames(fieldProjections)
162169
.build());
163170
}
171+
if (nodeSelector != null && !nodeSelector.isEmpty()) {
172+
builder.setNodeSelector(nodeSelector);
173+
}
164174
if (this.aggregation != null) {
165175
BanyandbMeasure.QueryRequest.GroupBy.Builder groupByBuilder = BanyandbMeasure.QueryRequest.GroupBy.newBuilder()
166176
.setTagProjection(buildTagProjections(entityMetadata, this.aggregation.groupByTagsProjection));
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.banyandb.v1.client;
20+
21+
import java.util.ArrayList;
22+
import java.util.List;
23+
import java.util.Set;
24+
25+
import lombok.Setter;
26+
import org.apache.skywalking.banyandb.property.v1.BanyandbProperty;
27+
import org.apache.skywalking.banyandb.v1.client.grpc.exception.BanyanDBException;
28+
import org.apache.skywalking.banyandb.v1.client.metadata.MetadataCache;
29+
30+
/**
31+
* PropertyQuery is the high-level query API for the property model.
32+
*/
33+
@Setter
34+
public class PropertyQuery extends AbstractQuery<BanyandbProperty.QueryRequest> {
35+
/**
36+
* The limit size of the query. Default value is 20.
37+
*/
38+
private int limit;
39+
40+
/**
41+
* Specific property IDs to query
42+
*/
43+
private List<String> ids;
44+
45+
/**
46+
* Node selector for distributed query routing
47+
*/
48+
private String nodeSelector;
49+
50+
/**
51+
* Construct a property query with required fields
52+
*/
53+
public PropertyQuery(final List<String> groups, final String name, final Set<String> projections) {
54+
super(groups, name, null, projections);
55+
this.limit = 20;
56+
this.ids = new ArrayList<>();
57+
}
58+
59+
/**
60+
* Add a property ID to filter query results
61+
* @param id property ID
62+
* @return this query instance for chaining
63+
*/
64+
public PropertyQuery id(String id) {
65+
if (id != null && !id.isEmpty()) {
66+
this.ids.add(id);
67+
}
68+
return this;
69+
}
70+
71+
/**
72+
* Add multiple property IDs to filter query results
73+
* @param ids list of property IDs
74+
* @return this query instance for chaining
75+
*/
76+
public PropertyQuery ids(List<String> ids) {
77+
if (ids != null) {
78+
this.ids.addAll(ids);
79+
}
80+
return this;
81+
}
82+
83+
/**
84+
* Set a node selector for query routing
85+
* @param nodeSelector the node selector expression
86+
* @return this query instance for chaining
87+
*/
88+
public PropertyQuery nodeSelector(String nodeSelector) {
89+
this.nodeSelector = nodeSelector;
90+
return this;
91+
}
92+
93+
@Override
94+
public PropertyQuery and(PairQueryCondition<?> condition) {
95+
return (PropertyQuery) super.and(condition);
96+
}
97+
98+
@Override
99+
public PropertyQuery or(PairQueryCondition<?> condition) {
100+
return (PropertyQuery) super.or(condition);
101+
}
102+
103+
@Override
104+
BanyandbProperty.QueryRequest build(MetadataCache.EntityMetadata ignored) throws BanyanDBException {
105+
return build();
106+
}
107+
108+
public BanyandbProperty.QueryRequest build() throws BanyanDBException {
109+
final BanyandbProperty.QueryRequest.Builder builder = BanyandbProperty.QueryRequest.newBuilder();
110+
builder.setName(this.name);
111+
builder.addAllGroups(this.groups);
112+
builder.addAllTagProjection(this.tagProjections);
113+
buildCriteria().ifPresent(builder::setCriteria);
114+
builder.setLimit(this.limit);
115+
builder.setTrace(this.trace);
116+
117+
if (!this.ids.isEmpty()) {
118+
builder.addAllIds(this.ids);
119+
}
120+
121+
if (this.nodeSelector != null && !this.nodeSelector.isEmpty()) {
122+
builder.setNodeSelector(this.nodeSelector);
123+
}
124+
125+
return builder.build();
126+
}
127+
}

src/main/java/org/apache/skywalking/banyandb/v1/client/StreamQuery.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ public class StreamQuery extends AbstractQuery<BanyandbStream.QueryRequest> {
4343
* One order condition is supported and optional.
4444
*/
4545
private OrderBy orderBy;
46+
47+
/**
48+
* Node selector for the query.
49+
*/
50+
private String nodeSelector;
4651

4752
public StreamQuery(final List<String> groups, final String name, final TimestampRange timestampRange, final Set<String> projections) {
4853
super(groups, name, timestampRange, projections);
@@ -63,6 +68,17 @@ public StreamQuery and(PairQueryCondition<?> condition) {
6368
public StreamQuery or(PairQueryCondition<?> condition) {
6469
return (StreamQuery) super.or(condition);
6570
}
71+
72+
/**
73+
* Set the node selector for this query.
74+
*
75+
* @param nodeSelector the node selector
76+
* @return this query instance for chaining
77+
*/
78+
public StreamQuery nodeSelector(String nodeSelector) {
79+
this.nodeSelector = nodeSelector;
80+
return this;
81+
}
6682

6783
@Override
6884
BanyandbStream.QueryRequest build(MetadataCache.EntityMetadata entityMetadata) throws BanyanDBException {
@@ -82,6 +98,9 @@ BanyandbStream.QueryRequest build(MetadataCache.EntityMetadata entityMetadata) t
8298
if (orderBy != null) {
8399
builder.setOrderBy(orderBy.build());
84100
}
101+
if (nodeSelector != null && !nodeSelector.isEmpty()) {
102+
builder.setNodeSelector(nodeSelector);
103+
}
85104
builder.setTrace(this.trace);
86105
return builder.build();
87106
}

src/main/proto/banyandb/v1/banyandb-measure.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ message QueryRequest {
104104
model.v1.QueryOrder order_by = 12;
105105
// trace is used to enable trace for the query
106106
bool trace = 13;
107+
// node_selector is used to specify the target node for the query
108+
string node_selector = 14;
107109
}
108110

109111
// TopNList contains a series of topN items

src/main/proto/banyandb/v1/banyandb-stream.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ message QueryRequest {
7676
model.v1.TagProjection projection = 8 [(validate.rules).message.required = true];
7777
// trace is used to enable trace for the query
7878
bool trace = 9;
79+
// node_selector is used to select the node to query
80+
string node_selector = 10;
7981
}
8082

8183
message ElementValue {

src/test/java/org/apache/skywalking/banyandb/v1/client/ITBanyanDBPropertyTests.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,13 @@
2727
import org.junit.Assert;
2828
import org.junit.Before;
2929
import org.junit.Test;
30+
31+
import com.google.common.collect.ImmutableSet;
32+
import com.google.common.collect.Lists;
33+
3034
import java.io.IOException;
3135
import java.util.concurrent.TimeUnit;
36+
3237
import org.apache.skywalking.banyandb.common.v1.BanyandbCommon;
3338
import org.apache.skywalking.banyandb.common.v1.BanyandbCommon.Group;
3439
import org.apache.skywalking.banyandb.property.v1.BanyandbProperty.Property;
@@ -158,6 +163,7 @@ public void test_PropertyList() throws BanyanDBException {
158163
Assert.assertTrue(this.client.apply(property).getCreated());
159164

160165
await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> {
166+
client.query(new PropertyQuery(Lists.newArrayList("default"), "sw", ImmutableSet.of("name")).build(null));
161167
BanyandbProperty.QueryResponse resp = client.query(BanyandbProperty.QueryRequest.newBuilder()
162168
.addGroups("default")
163169
.setName("sw")
@@ -183,6 +189,36 @@ public void test_PropertyList() throws BanyanDBException {
183189
});
184190
}
185191

192+
@Test
193+
public void test_PropertyQuery() throws BanyanDBException {
194+
Property property = buildProperty("default", "sw", "id1").toBuilder().addTags(
195+
Tag.newBuilder().setKey("name").setValue(
196+
TagValue.newBuilder().setStr(Str.newBuilder().setValue("bar")))).build();
197+
Assert.assertTrue(this.client.apply(property).getCreated());
198+
property = buildProperty("default", "sw", "id2").toBuilder().addTags(
199+
Tag.newBuilder().setKey("name").setValue(
200+
TagValue.newBuilder().setStr(Str.newBuilder().setValue("foo")))).build();
201+
Assert.assertTrue(this.client.apply(property).getCreated());
202+
203+
await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> {
204+
BanyandbProperty.QueryResponse resp = client.query(new PropertyQuery(Lists.newArrayList("default"), "sw", ImmutableSet.of("name")).build());
205+
Assert.assertEquals(2, resp.getPropertiesCount());
206+
});
207+
await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> {
208+
PropertyQuery pQuery = new PropertyQuery(Lists.newArrayList("default"), "sw", ImmutableSet.of("name"));
209+
pQuery.criteria(PairQueryCondition.StringQueryCondition.eq("name", "foo"));
210+
BanyandbProperty.QueryResponse resp = client.query(pQuery.build());
211+
Assert.assertEquals(1, resp.getPropertiesCount());
212+
});
213+
await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> {
214+
PropertyQuery pQuery = new PropertyQuery(Lists.newArrayList("default"), "sw", ImmutableSet.of("name"));
215+
pQuery.criteria(Or.create(PairQueryCondition.StringQueryCondition.eq("name", "foo"),
216+
PairQueryCondition.StringQueryCondition.eq("name", "bar")));
217+
BanyandbProperty.QueryResponse resp = client.query(pQuery.build());
218+
Assert.assertEquals(2, resp.getPropertiesCount());
219+
});
220+
}
221+
186222
private BanyandbProperty.Property buildProperty(String group, String name, String id) {
187223
BanyandbProperty.Property.Builder builder = BanyandbProperty.Property.newBuilder()
188224
.setMetadata(

0 commit comments

Comments
 (0)