Skip to content

[DE-62] Feature/hybrid smart graphs #415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/main/java/com/arangodb/ArangoGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.arangodb.entity.EdgeDefinition;
import com.arangodb.entity.GraphEntity;
import com.arangodb.model.GraphCreateOptions;
import com.arangodb.model.VertexCollectionCreateOptions;

import java.util.Collection;

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

/**
* Adds a vertex collection to the set of collections of the graph. If the collection does not exist, it will be
* created.
*
* @param name Name of the vertex collection
* @param options additional options
* @return information about the graph
* @throws ArangoDBException
* @see <a href="https://www.arangodb.com/docs/stable/http/gharial-management.html#add-vertex-collection">API
* Documentation</a>
* @since ArangoDB 3.9
*/
GraphEntity addVertexCollection(String name, VertexCollectionCreateOptions options) throws ArangoDBException;

/**
* Returns a {@code ArangoVertexCollection} instance for the given vertex collection name.
*
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/arangodb/async/ArangoGraphAsync.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.arangodb.entity.EdgeDefinition;
import com.arangodb.entity.GraphEntity;
import com.arangodb.model.GraphCreateOptions;
import com.arangodb.model.VertexCollectionCreateOptions;

import java.util.Collection;
import java.util.concurrent.CompletableFuture;
Expand Down Expand Up @@ -129,6 +130,19 @@ CompletableFuture<GraphEntity> createGraph(
*/
CompletableFuture<GraphEntity> addVertexCollection(final String name);

/**
* Adds a vertex collection to the set of collections of the graph. If the collection does not exist, it will be
* created.
*
* @param name The name of the collection
* @param options additional options
* @return information about the graph
* @see <a href="https://www.arangodb.com/docs/stable/http/gharial-management.html#add-vertex-collection">API
* Documentation</a>
* @since ArangoDB 3.9
*/
CompletableFuture<GraphEntity> addVertexCollection(final String name, final VertexCollectionCreateOptions options);

/**
* Returns a handler of the vertex collection by the given name
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.arangodb.entity.GraphEntity;
import com.arangodb.internal.InternalArangoGraph;
import com.arangodb.model.GraphCreateOptions;
import com.arangodb.model.VertexCollectionCreateOptions;

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

@Override
public CompletableFuture<GraphEntity> addVertexCollection(final String name) {
return executor.execute(addVertexCollectionRequest(name), addVertexCollectionResponseDeserializer());
return addVertexCollection(name, new VertexCollectionCreateOptions());
}

@Override
public CompletableFuture<GraphEntity> addVertexCollection(final String name, final VertexCollectionCreateOptions options) {
return executor.execute(addVertexCollectionRequest(name, options), addVertexCollectionResponseDeserializer());
}

@Override
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/com/arangodb/entity/EdgeDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class EdgeDefinition {
private String collection;
private Collection<String> from;
private Collection<String> to;
private Options options;

public String getCollection() {
return collection;
Expand Down Expand Up @@ -60,4 +61,24 @@ public EdgeDefinition to(final String... to) {
return this;
}

public Collection<String> getSatellites() {
return options.satellites;
}

/**
* @param satellites collection names that will be used to create SatelliteCollections
* for a Hybrid (Disjoint) SmartGraph (Enterprise Edition only). Each array element
* must be a valid collection name. The collection type cannot be modified later.
* @return this
* @since ArangoDB 3.9.0
*/
public EdgeDefinition satellites(final String... satellites) {
options = new Options();
options.satellites = Arrays.asList(satellites);
return this;
}

private static class Options {
private Collection<String> satellites;
}
}
8 changes: 7 additions & 1 deletion src/main/java/com/arangodb/internal/ArangoGraphImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.arangodb.entity.EdgeDefinition;
import com.arangodb.entity.GraphEntity;
import com.arangodb.model.GraphCreateOptions;
import com.arangodb.model.VertexCollectionCreateOptions;

import java.util.Collection;

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

@Override
public GraphEntity addVertexCollection(final String name) throws ArangoDBException {
return executor.execute(addVertexCollectionRequest(name), addVertexCollectionResponseDeserializer());
return addVertexCollection(name, new VertexCollectionCreateOptions());
}

@Override
public GraphEntity addVertexCollection(final String name, final VertexCollectionCreateOptions options) throws ArangoDBException {
return executor.execute(addVertexCollectionRequest(name, options), addVertexCollectionResponseDeserializer());
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/arangodb/internal/InternalArangoGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ protected ResponseDeserializer<Collection<String>> getVertexCollectionsResponseD
}.getType());
}

protected Request addVertexCollectionRequest(final String name) {
protected Request addVertexCollectionRequest(final String name, final VertexCollectionCreateOptions options) {
final Request request = request(db.dbName(), RequestType.POST, PATH_API_GHARIAL, name(), VERTEX);
request.setBody(util().serialize(OptionsBuilder.build(new VertexCollectionCreateOptions(), name)));
request.setBody(util().serialize(OptionsBuilder.build(options, name)));
return request;
}

Expand Down
24 changes: 24 additions & 0 deletions src/main/java/com/arangodb/model/GraphCreateOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,22 @@ public GraphCreateOptions smartGraphAttribute(final String smartGraphAttribute)
return this;
}

public Collection<String> getSatellites() {
return getOptions().getSatellites();
}

/**
* @param satellites collection names that will be used to create SatelliteCollections
* for a Hybrid (Disjoint) SmartGraph (Enterprise Edition only). Each array element
* must be a valid collection name. The collection type cannot be modified later.
* @return options
* @since ArangoDB 3.9.0
*/
public GraphCreateOptions satellites(final String... satellites) {
getOptions().setSatellites(satellites);
return this;
}

private SmartOptions getOptions() {
if (options == null) {
options = new SmartOptions();
Expand All @@ -203,6 +219,7 @@ public static class SmartOptions {
private Integer numberOfShards;
private String smartGraphAttribute;
private Boolean isDisjoint;
private Collection<String> satellites;

public SmartOptions() {
super();
Expand Down Expand Up @@ -257,6 +274,13 @@ public void setIsDisjoint(final Boolean isDisjoint) {
this.isDisjoint = isDisjoint;
}

public Collection<String> getSatellites() {
return satellites;
}

public void setSatellites(final String... satellites) {
this.satellites = Arrays.asList(satellites);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@

package com.arangodb.model;

import java.util.Arrays;
import java.util.Collection;

/**
* @author Mark Vollmary
*/
public class VertexCollectionCreateOptions {

private String collection;
private Options options;

public VertexCollectionCreateOptions() {
super();
Expand All @@ -44,4 +48,25 @@ protected VertexCollectionCreateOptions collection(final String collection) {
return this;
}

public Collection<String> getSatellites() {
return options.satellites;
}

/**
* @param satellites collection names that will be used to create SatelliteCollections
* for a Hybrid (Disjoint) SmartGraph (Enterprise Edition only). Each array element
* must be a valid collection name. The collection type cannot be modified later.
* @return options
* @since ArangoDB 3.9.0
*/
public VertexCollectionCreateOptions satellites(final String... satellites) {
options = new Options();
options.satellites = Arrays.asList(satellites);
return this;
}

private static class Options {
private Collection<String> satellites;
}

}
104 changes: 104 additions & 0 deletions src/test/java/com/arangodb/ArangoGraphTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.arangodb.entity.EdgeDefinition;
import com.arangodb.entity.GraphEntity;
import com.arangodb.model.GraphCreateOptions;
import com.arangodb.model.VertexCollectionCreateOptions;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -185,6 +186,26 @@ public void addVertexCollection() {
graph.vertexCollection(VERTEX_COL_4).drop();
}

@Test
public void addSatelliteVertexCollection() {
assumeTrue(isCluster());
assumeTrue(isEnterprise());
assumeTrue(isAtLeastVersion(3, 9));

String v1Name = "vertex-" + rnd();

ArangoGraph g = db.graph(GRAPH_NAME + rnd());
g.create(Collections.emptyList(), new GraphCreateOptions().isSmart(true).smartGraphAttribute("test"));
g.addVertexCollection(v1Name, new VertexCollectionCreateOptions().satellites(v1Name));

Collection<String> vertexCollections = g.getVertexCollections();
assertThat(vertexCollections, hasItems(v1Name));
assertThat(db.collection(v1Name).getProperties().getSatellite(), is(true));

// revert
g.drop();
}

@Test
public void getEdgeCollections() {
final Collection<String> edgeCollections = graph.getEdgeDefinitions();
Expand Down Expand Up @@ -223,6 +244,35 @@ public void addEdgeDefinition() {
graph.removeEdgeDefinition(EDGE_COL_3);
}

@Test
public void addSatelliteEdgeDefinition() {
assumeTrue(isCluster());
assumeTrue(isEnterprise());
assumeTrue(isAtLeastVersion(3, 9));

String eName = "edge-" + rnd();
String v1Name = "vertex-" + rnd();
String v2Name = "vertex-" + rnd();
EdgeDefinition ed = new EdgeDefinition().collection(eName).from(v1Name).to(v2Name).satellites(v1Name);

ArangoGraph g = db.graph(GRAPH_NAME + rnd());
g.create(Collections.emptyList(), new GraphCreateOptions().isSmart(true).smartGraphAttribute("test"));
g.addEdgeDefinition(ed);
final GraphEntity ge = g.getInfo();
assertThat(ge, is(notNullValue()));
final Collection<EdgeDefinition> edgeDefinitions = ge.getEdgeDefinitions();
assertThat(edgeDefinitions.size(), is(1));
EdgeDefinition e = edgeDefinitions.iterator().next();
assertThat(e.getCollection(), is(eName));
assertThat(e.getFrom(), hasItem(v1Name));
assertThat(e.getTo(), hasItem(v2Name));

assertThat(db.collection(v1Name).getProperties().getSatellite(), is(true));

// revert
g.drop();
}

@Test
public void replaceEdgeDefinition() {
final GraphEntity g = graph
Expand Down Expand Up @@ -277,6 +327,33 @@ public void smartGraph() {
assertThat(g.getNumberOfShards(), is(2));
}

@Test
public void hybridSmartGraph() {
assumeTrue(isEnterprise());
assumeTrue(isCluster());
assumeTrue((isAtLeastVersion(3, 9)));

final Collection<EdgeDefinition> edgeDefinitions = new ArrayList<>();
String eName = "hybridSmartGraph-edge-" + rnd();
String v1Name = "hybridSmartGraph-vertex-" + rnd();
String v2Name = "hybridSmartGraph-vertex-" + rnd();
edgeDefinitions.add(new EdgeDefinition().collection(eName).from(v1Name).to(v2Name));

String graphId = GRAPH_NAME + rnd();
final GraphEntity g = db.createGraph(graphId, edgeDefinitions, new GraphCreateOptions()
.satellites(eName, v1Name)
.isSmart(true).smartGraphAttribute("test").replicationFactor(2).numberOfShards(2));

assertThat(g, is(notNullValue()));
assertThat(g.getIsSmart(), is(true));
assertThat(g.getSmartGraphAttribute(), is("test"));
assertThat(g.getNumberOfShards(), is(2));

assertThat(db.collection(eName).getProperties().getSatellite(), is(true));
assertThat(db.collection(v1Name).getProperties().getSatellite(), is(true));
assertThat(db.collection(v2Name).getProperties().getReplicationFactor(), is(2));
}

@Test
public void disjointSmartGraph() {
assumeTrue(isEnterprise());
Expand All @@ -297,6 +374,33 @@ public void disjointSmartGraph() {
assertThat(g.getNumberOfShards(), is(2));
}

@Test
public void hybridDisjointSmartGraph() {
assumeTrue(isEnterprise());
assumeTrue(isCluster());
assumeTrue((isAtLeastVersion(3, 9)));

final Collection<EdgeDefinition> edgeDefinitions = new ArrayList<>();
String eName = "hybridDisjointSmartGraph-edge-" + rnd();
String v1Name = "hybridDisjointSmartGraph-vertex-" + rnd();
String v2Name = "hybridDisjointSmartGraph-vertex-" + rnd();
edgeDefinitions.add(new EdgeDefinition().collection(eName).from(v1Name).to(v2Name));

String graphId = GRAPH_NAME + rnd();
final GraphEntity g = db.createGraph(graphId, edgeDefinitions, new GraphCreateOptions()
.satellites(v1Name)
.isSmart(true).isDisjoint(true).smartGraphAttribute("test").replicationFactor(2).numberOfShards(2));

assertThat(g, is(notNullValue()));
assertThat(g.getIsSmart(), is(true));
assertThat(g.getIsDisjoint(), is(true));
assertThat(g.getSmartGraphAttribute(), is("test"));
assertThat(g.getNumberOfShards(), is(2));

assertThat(db.collection(v1Name).getProperties().getSatellite(), is(true));
assertThat(db.collection(v2Name).getProperties().getReplicationFactor(), is(2));
}

@Test
public void drop() {
final String edgeCollection = "edge_" + rnd();
Expand Down
Loading