Skip to content

Commit d89c045

Browse files
authored
[DE-62] Feature/hybrid smart graphs (#415)
* sync driver implementation * async tests * CI matrix cleanup
1 parent 4d39da8 commit d89c045

11 files changed

+333
-9
lines changed

src/main/java/com/arangodb/ArangoGraph.java

+15
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.arangodb.entity.EdgeDefinition;
2424
import com.arangodb.entity.GraphEntity;
2525
import com.arangodb.model.GraphCreateOptions;
26+
import com.arangodb.model.VertexCollectionCreateOptions;
2627

2728
import java.util.Collection;
2829

@@ -131,6 +132,20 @@ public interface ArangoGraph extends ArangoSerializationAccessor {
131132
*/
132133
GraphEntity addVertexCollection(String name) throws ArangoDBException;
133134

135+
/**
136+
* Adds a vertex collection to the set of collections of the graph. If the collection does not exist, it will be
137+
* created.
138+
*
139+
* @param name Name of the vertex collection
140+
* @param options additional options
141+
* @return information about the graph
142+
* @throws ArangoDBException
143+
* @see <a href="https://www.arangodb.com/docs/stable/http/gharial-management.html#add-vertex-collection">API
144+
* Documentation</a>
145+
* @since ArangoDB 3.9
146+
*/
147+
GraphEntity addVertexCollection(String name, VertexCollectionCreateOptions options) throws ArangoDBException;
148+
134149
/**
135150
* Returns a {@code ArangoVertexCollection} instance for the given vertex collection name.
136151
*

src/main/java/com/arangodb/async/ArangoGraphAsync.java

+14
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.arangodb.entity.EdgeDefinition;
2525
import com.arangodb.entity.GraphEntity;
2626
import com.arangodb.model.GraphCreateOptions;
27+
import com.arangodb.model.VertexCollectionCreateOptions;
2728

2829
import java.util.Collection;
2930
import java.util.concurrent.CompletableFuture;
@@ -129,6 +130,19 @@ CompletableFuture<GraphEntity> createGraph(
129130
*/
130131
CompletableFuture<GraphEntity> addVertexCollection(final String name);
131132

133+
/**
134+
* Adds a vertex collection to the set of collections of the graph. If the collection does not exist, it will be
135+
* created.
136+
*
137+
* @param name The name of the collection
138+
* @param options additional options
139+
* @return information about the graph
140+
* @see <a href="https://www.arangodb.com/docs/stable/http/gharial-management.html#add-vertex-collection">API
141+
* Documentation</a>
142+
* @since ArangoDB 3.9
143+
*/
144+
CompletableFuture<GraphEntity> addVertexCollection(final String name, final VertexCollectionCreateOptions options);
145+
132146
/**
133147
* Returns a handler of the vertex collection by the given name
134148
*

src/main/java/com/arangodb/async/internal/ArangoGraphAsyncImpl.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.arangodb.entity.GraphEntity;
2828
import com.arangodb.internal.InternalArangoGraph;
2929
import com.arangodb.model.GraphCreateOptions;
30+
import com.arangodb.model.VertexCollectionCreateOptions;
3031

3132
import java.util.Collection;
3233
import java.util.Objects;
@@ -82,7 +83,12 @@ public CompletableFuture<Collection<String>> getVertexCollections() {
8283

8384
@Override
8485
public CompletableFuture<GraphEntity> addVertexCollection(final String name) {
85-
return executor.execute(addVertexCollectionRequest(name), addVertexCollectionResponseDeserializer());
86+
return addVertexCollection(name, new VertexCollectionCreateOptions());
87+
}
88+
89+
@Override
90+
public CompletableFuture<GraphEntity> addVertexCollection(final String name, final VertexCollectionCreateOptions options) {
91+
return executor.execute(addVertexCollectionRequest(name, options), addVertexCollectionResponseDeserializer());
8692
}
8793

8894
@Override

src/main/java/com/arangodb/entity/EdgeDefinition.java

+21
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class EdgeDefinition {
3232
private String collection;
3333
private Collection<String> from;
3434
private Collection<String> to;
35+
private Options options;
3536

3637
public String getCollection() {
3738
return collection;
@@ -60,4 +61,24 @@ public EdgeDefinition to(final String... to) {
6061
return this;
6162
}
6263

64+
public Collection<String> getSatellites() {
65+
return options.satellites;
66+
}
67+
68+
/**
69+
* @param satellites collection names that will be used to create SatelliteCollections
70+
* for a Hybrid (Disjoint) SmartGraph (Enterprise Edition only). Each array element
71+
* must be a valid collection name. The collection type cannot be modified later.
72+
* @return this
73+
* @since ArangoDB 3.9.0
74+
*/
75+
public EdgeDefinition satellites(final String... satellites) {
76+
options = new Options();
77+
options.satellites = Arrays.asList(satellites);
78+
return this;
79+
}
80+
81+
private static class Options {
82+
private Collection<String> satellites;
83+
}
6384
}

src/main/java/com/arangodb/internal/ArangoGraphImpl.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.arangodb.entity.EdgeDefinition;
2828
import com.arangodb.entity.GraphEntity;
2929
import com.arangodb.model.GraphCreateOptions;
30+
import com.arangodb.model.VertexCollectionCreateOptions;
3031

3132
import java.util.Collection;
3233

@@ -86,7 +87,12 @@ public Collection<String> getVertexCollections() throws ArangoDBException {
8687

8788
@Override
8889
public GraphEntity addVertexCollection(final String name) throws ArangoDBException {
89-
return executor.execute(addVertexCollectionRequest(name), addVertexCollectionResponseDeserializer());
90+
return addVertexCollection(name, new VertexCollectionCreateOptions());
91+
}
92+
93+
@Override
94+
public GraphEntity addVertexCollection(final String name, final VertexCollectionCreateOptions options) throws ArangoDBException {
95+
return executor.execute(addVertexCollectionRequest(name, options), addVertexCollectionResponseDeserializer());
9096
}
9197

9298
@Override

src/main/java/com/arangodb/internal/InternalArangoGraph.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ protected ResponseDeserializer<Collection<String>> getVertexCollectionsResponseD
8888
}.getType());
8989
}
9090

91-
protected Request addVertexCollectionRequest(final String name) {
91+
protected Request addVertexCollectionRequest(final String name, final VertexCollectionCreateOptions options) {
9292
final Request request = request(db.dbName(), RequestType.POST, PATH_API_GHARIAL, name(), VERTEX);
93-
request.setBody(util().serialize(OptionsBuilder.build(new VertexCollectionCreateOptions(), name)));
93+
request.setBody(util().serialize(OptionsBuilder.build(options, name)));
9494
return request;
9595
}
9696

src/main/java/com/arangodb/model/GraphCreateOptions.java

+24
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,22 @@ public GraphCreateOptions smartGraphAttribute(final String smartGraphAttribute)
190190
return this;
191191
}
192192

193+
public Collection<String> getSatellites() {
194+
return getOptions().getSatellites();
195+
}
196+
197+
/**
198+
* @param satellites collection names that will be used to create SatelliteCollections
199+
* for a Hybrid (Disjoint) SmartGraph (Enterprise Edition only). Each array element
200+
* must be a valid collection name. The collection type cannot be modified later.
201+
* @return options
202+
* @since ArangoDB 3.9.0
203+
*/
204+
public GraphCreateOptions satellites(final String... satellites) {
205+
getOptions().setSatellites(satellites);
206+
return this;
207+
}
208+
193209
private SmartOptions getOptions() {
194210
if (options == null) {
195211
options = new SmartOptions();
@@ -203,6 +219,7 @@ public static class SmartOptions {
203219
private Integer numberOfShards;
204220
private String smartGraphAttribute;
205221
private Boolean isDisjoint;
222+
private Collection<String> satellites;
206223

207224
public SmartOptions() {
208225
super();
@@ -257,6 +274,13 @@ public void setIsDisjoint(final Boolean isDisjoint) {
257274
this.isDisjoint = isDisjoint;
258275
}
259276

277+
public Collection<String> getSatellites() {
278+
return satellites;
279+
}
280+
281+
public void setSatellites(final String... satellites) {
282+
this.satellites = Arrays.asList(satellites);
283+
}
260284
}
261285

262286
}

src/main/java/com/arangodb/model/VertexCollectionCreateOptions.java

+25
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@
2020

2121
package com.arangodb.model;
2222

23+
import java.util.Arrays;
24+
import java.util.Collection;
25+
2326
/**
2427
* @author Mark Vollmary
2528
*/
2629
public class VertexCollectionCreateOptions {
2730

2831
private String collection;
32+
private Options options;
2933

3034
public VertexCollectionCreateOptions() {
3135
super();
@@ -44,4 +48,25 @@ protected VertexCollectionCreateOptions collection(final String collection) {
4448
return this;
4549
}
4650

51+
public Collection<String> getSatellites() {
52+
return options.satellites;
53+
}
54+
55+
/**
56+
* @param satellites collection names that will be used to create SatelliteCollections
57+
* for a Hybrid (Disjoint) SmartGraph (Enterprise Edition only). Each array element
58+
* must be a valid collection name. The collection type cannot be modified later.
59+
* @return options
60+
* @since ArangoDB 3.9.0
61+
*/
62+
public VertexCollectionCreateOptions satellites(final String... satellites) {
63+
options = new Options();
64+
options.satellites = Arrays.asList(satellites);
65+
return this;
66+
}
67+
68+
private static class Options {
69+
private Collection<String> satellites;
70+
}
71+
4772
}

src/test/java/com/arangodb/ArangoGraphTest.java

+104
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.arangodb.entity.EdgeDefinition;
2525
import com.arangodb.entity.GraphEntity;
2626
import com.arangodb.model.GraphCreateOptions;
27+
import com.arangodb.model.VertexCollectionCreateOptions;
2728
import org.junit.BeforeClass;
2829
import org.junit.Test;
2930
import org.junit.runner.RunWith;
@@ -185,6 +186,26 @@ public void addVertexCollection() {
185186
graph.vertexCollection(VERTEX_COL_4).drop();
186187
}
187188

189+
@Test
190+
public void addSatelliteVertexCollection() {
191+
assumeTrue(isCluster());
192+
assumeTrue(isEnterprise());
193+
assumeTrue(isAtLeastVersion(3, 9));
194+
195+
String v1Name = "vertex-" + rnd();
196+
197+
ArangoGraph g = db.graph(GRAPH_NAME + rnd());
198+
g.create(Collections.emptyList(), new GraphCreateOptions().isSmart(true).smartGraphAttribute("test"));
199+
g.addVertexCollection(v1Name, new VertexCollectionCreateOptions().satellites(v1Name));
200+
201+
Collection<String> vertexCollections = g.getVertexCollections();
202+
assertThat(vertexCollections, hasItems(v1Name));
203+
assertThat(db.collection(v1Name).getProperties().getSatellite(), is(true));
204+
205+
// revert
206+
g.drop();
207+
}
208+
188209
@Test
189210
public void getEdgeCollections() {
190211
final Collection<String> edgeCollections = graph.getEdgeDefinitions();
@@ -223,6 +244,35 @@ public void addEdgeDefinition() {
223244
graph.removeEdgeDefinition(EDGE_COL_3);
224245
}
225246

247+
@Test
248+
public void addSatelliteEdgeDefinition() {
249+
assumeTrue(isCluster());
250+
assumeTrue(isEnterprise());
251+
assumeTrue(isAtLeastVersion(3, 9));
252+
253+
String eName = "edge-" + rnd();
254+
String v1Name = "vertex-" + rnd();
255+
String v2Name = "vertex-" + rnd();
256+
EdgeDefinition ed = new EdgeDefinition().collection(eName).from(v1Name).to(v2Name).satellites(v1Name);
257+
258+
ArangoGraph g = db.graph(GRAPH_NAME + rnd());
259+
g.create(Collections.emptyList(), new GraphCreateOptions().isSmart(true).smartGraphAttribute("test"));
260+
g.addEdgeDefinition(ed);
261+
final GraphEntity ge = g.getInfo();
262+
assertThat(ge, is(notNullValue()));
263+
final Collection<EdgeDefinition> edgeDefinitions = ge.getEdgeDefinitions();
264+
assertThat(edgeDefinitions.size(), is(1));
265+
EdgeDefinition e = edgeDefinitions.iterator().next();
266+
assertThat(e.getCollection(), is(eName));
267+
assertThat(e.getFrom(), hasItem(v1Name));
268+
assertThat(e.getTo(), hasItem(v2Name));
269+
270+
assertThat(db.collection(v1Name).getProperties().getSatellite(), is(true));
271+
272+
// revert
273+
g.drop();
274+
}
275+
226276
@Test
227277
public void replaceEdgeDefinition() {
228278
final GraphEntity g = graph
@@ -277,6 +327,33 @@ public void smartGraph() {
277327
assertThat(g.getNumberOfShards(), is(2));
278328
}
279329

330+
@Test
331+
public void hybridSmartGraph() {
332+
assumeTrue(isEnterprise());
333+
assumeTrue(isCluster());
334+
assumeTrue((isAtLeastVersion(3, 9)));
335+
336+
final Collection<EdgeDefinition> edgeDefinitions = new ArrayList<>();
337+
String eName = "hybridSmartGraph-edge-" + rnd();
338+
String v1Name = "hybridSmartGraph-vertex-" + rnd();
339+
String v2Name = "hybridSmartGraph-vertex-" + rnd();
340+
edgeDefinitions.add(new EdgeDefinition().collection(eName).from(v1Name).to(v2Name));
341+
342+
String graphId = GRAPH_NAME + rnd();
343+
final GraphEntity g = db.createGraph(graphId, edgeDefinitions, new GraphCreateOptions()
344+
.satellites(eName, v1Name)
345+
.isSmart(true).smartGraphAttribute("test").replicationFactor(2).numberOfShards(2));
346+
347+
assertThat(g, is(notNullValue()));
348+
assertThat(g.getIsSmart(), is(true));
349+
assertThat(g.getSmartGraphAttribute(), is("test"));
350+
assertThat(g.getNumberOfShards(), is(2));
351+
352+
assertThat(db.collection(eName).getProperties().getSatellite(), is(true));
353+
assertThat(db.collection(v1Name).getProperties().getSatellite(), is(true));
354+
assertThat(db.collection(v2Name).getProperties().getReplicationFactor(), is(2));
355+
}
356+
280357
@Test
281358
public void disjointSmartGraph() {
282359
assumeTrue(isEnterprise());
@@ -297,6 +374,33 @@ public void disjointSmartGraph() {
297374
assertThat(g.getNumberOfShards(), is(2));
298375
}
299376

377+
@Test
378+
public void hybridDisjointSmartGraph() {
379+
assumeTrue(isEnterprise());
380+
assumeTrue(isCluster());
381+
assumeTrue((isAtLeastVersion(3, 9)));
382+
383+
final Collection<EdgeDefinition> edgeDefinitions = new ArrayList<>();
384+
String eName = "hybridDisjointSmartGraph-edge-" + rnd();
385+
String v1Name = "hybridDisjointSmartGraph-vertex-" + rnd();
386+
String v2Name = "hybridDisjointSmartGraph-vertex-" + rnd();
387+
edgeDefinitions.add(new EdgeDefinition().collection(eName).from(v1Name).to(v2Name));
388+
389+
String graphId = GRAPH_NAME + rnd();
390+
final GraphEntity g = db.createGraph(graphId, edgeDefinitions, new GraphCreateOptions()
391+
.satellites(v1Name)
392+
.isSmart(true).isDisjoint(true).smartGraphAttribute("test").replicationFactor(2).numberOfShards(2));
393+
394+
assertThat(g, is(notNullValue()));
395+
assertThat(g.getIsSmart(), is(true));
396+
assertThat(g.getIsDisjoint(), is(true));
397+
assertThat(g.getSmartGraphAttribute(), is("test"));
398+
assertThat(g.getNumberOfShards(), is(2));
399+
400+
assertThat(db.collection(v1Name).getProperties().getSatellite(), is(true));
401+
assertThat(db.collection(v2Name).getProperties().getReplicationFactor(), is(2));
402+
}
403+
300404
@Test
301405
public void drop() {
302406
final String edgeCollection = "edge_" + rnd();

0 commit comments

Comments
 (0)