Skip to content

Commit b538a7c

Browse files
committed
adapted jnosql-tinkerpop for ArangoDB Tinkerpop provider
1 parent 511e6c7 commit b538a7c

File tree

18 files changed

+146
-132
lines changed

18 files changed

+146
-132
lines changed

jnosql-tinkerpop/pom.xml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@
5454
<scope>provided</scope>
5555
</dependency>
5656
<dependency>
57-
<groupId>org.apache.tinkerpop</groupId>
58-
<artifactId>neo4j-gremlin</artifactId>
59-
<version>${tinkerpop.version}</version>
57+
<groupId>com.arangodb</groupId>
58+
<artifactId>arangodb-tinkerpop-provider</artifactId>
59+
<version>3.2.1</version>
6060
<scope>test</scope>
6161
</dependency>
6262
<dependency>
63-
<groupId>org.neo4j</groupId>
64-
<artifactId>neo4j-tinkerpop-api-impl</artifactId>
65-
<version>${neo4j.connector.version}</version>
63+
<groupId>org.slf4j</groupId>
64+
<artifactId>slf4j-simple</artifactId>
65+
<version>1.7.25</version>
6666
<scope>test</scope>
6767
</dependency>
6868
</dependencies>

jnosql-tinkerpop/src/main/java/org/eclipse/jnosql/databases/tinkerpop/communication/CommunicationEntityConverter.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,16 @@
1919

2020
import java.util.function.Function;
2121

22-
public enum CommunicationEntityConverter implements Function<Vertex, CommunicationEntity>{
23-
INSTANCE;
22+
import static org.eclipse.jnosql.databases.tinkerpop.communication.TinkerpopGraphDatabaseManager.ID;
2423

24+
public enum CommunicationEntityConverter implements Function<Vertex, CommunicationEntity> {
25+
INSTANCE;
2526

2627
@Override
2728
public CommunicationEntity apply(Vertex vertex) {
2829
var entity = CommunicationEntity.of(vertex.label());
2930
vertex.properties().forEachRemaining(p -> entity.add(p.key(), p.value()));
30-
entity.add(DefaultTinkerpopGraphDatabaseManager.ID_PROPERTY, vertex.id());
31+
entity.add(ID, vertex.id());
3132
return entity;
3233
}
3334
}

jnosql-tinkerpop/src/main/java/org/eclipse/jnosql/databases/tinkerpop/communication/DefaultTinkerpopGraphDatabaseManager.java

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
import org.apache.tinkerpop.gremlin.structure.Direction;
2020
import org.apache.tinkerpop.gremlin.structure.Edge;
2121
import org.apache.tinkerpop.gremlin.structure.Graph;
22+
import org.apache.tinkerpop.gremlin.structure.T;
2223
import org.apache.tinkerpop.gremlin.structure.Vertex;
2324
import org.eclipse.jnosql.communication.CommunicationException;
2425
import org.eclipse.jnosql.communication.ValueUtil;
2526
import org.eclipse.jnosql.communication.graph.CommunicationEdge;
2627
import org.eclipse.jnosql.communication.semistructured.CommunicationEntity;
2728
import org.eclipse.jnosql.communication.semistructured.DeleteQuery;
29+
import org.eclipse.jnosql.communication.semistructured.Element;
2830
import org.eclipse.jnosql.communication.semistructured.SelectQuery;
2931

3032
import java.time.Duration;
@@ -52,7 +54,6 @@
5254
*/
5355
public class DefaultTinkerpopGraphDatabaseManager implements TinkerpopGraphDatabaseManager {
5456

55-
public static final String ID_PROPERTY = "_id";
5657
private final Graph graph;
5758

5859
DefaultTinkerpopGraphDatabaseManager(Graph graph) {
@@ -71,13 +72,8 @@ public String name() {
7172

7273
@Override
7374
public CommunicationEntity insert(CommunicationEntity entity) {
74-
7575
Objects.requireNonNull(entity, "entity is required");
76-
Vertex vertex = graph.addVertex(entity.name());
77-
entity.elements().forEach(e -> vertex.property(e.name(), ValueUtil.convert(e.value())));
78-
entity.add(ID_PROPERTY, vertex.id());
79-
vertex.property(ID_PROPERTY, vertex.id());
80-
GraphTransactionUtil.transaction(graph);
76+
addVertex(entity);
8177
return entity;
8278
}
8379

@@ -101,14 +97,16 @@ public Iterable<CommunicationEntity> insert(Iterable<CommunicationEntity> iterab
10197
@Override
10298
public CommunicationEntity update(CommunicationEntity entity) {
10399
Objects.requireNonNull(entity, "entity is required");
104-
entity.find(ID_PROPERTY).ifPresent(id -> {
105-
Iterator<Vertex> vertices = graph.vertices(id.get());
106-
if(!vertices.hasNext()) {
107-
throw new EmptyResultException("The entity does not exist with the id: " + id);
108-
}
109-
Vertex vertex = vertices.next();
110-
entity.elements().forEach(e -> vertex.property(e.name(), ValueUtil.convert(e.value())));
111-
});
100+
Object id = entity.find(ID).map(Element::get)
101+
.orElseThrow(() -> new IllegalArgumentException("Entity must have an ID"));
102+
Iterator<Vertex> vertices = graph.vertices(id);
103+
if (!vertices.hasNext()) {
104+
throw new EmptyResultException("The entity does not exist with the id: " + id);
105+
}
106+
Vertex vertex = vertices.next();
107+
entity.elements().stream()
108+
.filter(it -> !ID.equals(it.name()))
109+
.forEach(e -> vertex.property(e.name(), ValueUtil.convert(e.value())));
112110
GraphTransactionUtil.transaction(graph);
113111
return entity;
114112
}
@@ -198,11 +196,11 @@ public void remove(CommunicationEntity source, String label, CommunicationEntity
198196
Objects.requireNonNull(target, "target is required");
199197
Objects.requireNonNull(label, "label is required");
200198

201-
Vertex sourceVertex = findVertexById(source.find(ID_PROPERTY)
199+
Vertex sourceVertex = findVertexById(source.find(ID)
202200
.orElseThrow(() -> new CommunicationException("Source entity must have an ID")).get())
203201
.orElseThrow(() -> new EmptyResultException("Source entity not found"));
204202

205-
Vertex targetVertex = findVertexById(target.find(ID_PROPERTY)
203+
Vertex targetVertex = findVertexById(target.find(ID)
206204
.orElseThrow(() -> new CommunicationException("Target entity must have an ID")).get())
207205
.orElseThrow(() -> new EmptyResultException("Target entity not found"));
208206

@@ -241,27 +239,33 @@ public <K> Optional<CommunicationEdge> findEdgeById(K id) {
241239

242240
var edge = traversal.next();
243241
var source = CommunicationEntity.of(edge.outVertex().label());
244-
source.add(ID_PROPERTY, edge.outVertex().id());
242+
source.add(ID, edge.outVertex().id());
245243

246244
var target = CommunicationEntity.of(edge.inVertex().label());
247-
target.add(ID_PROPERTY, edge.inVertex().id());
245+
target.add(ID, edge.inVertex().id());
248246

249247
Map<String, Object> properties = new HashMap<>();
250248
edge.properties().forEachRemaining(p -> properties.put(p.key(), p.value()));
251249

252250
return Optional.of(new TinkerpopCommunicationEdge(id, source, target, edge.label(), properties));
253251
}
254252

253+
private Vertex addVertex(CommunicationEntity entity) {
254+
Object[] args = Stream.concat(
255+
Stream.of(T.label, entity.name()),
256+
entity.elements().stream().flatMap(it -> ID.equals(it.name()) ?
257+
Stream.of(T.id, it.get()) :
258+
Stream.of(it.name(), ValueUtil.convert(it.value())))
259+
).toArray();
260+
Vertex vertex = graph.addVertex(args);
261+
entity.add(ID, vertex.id());
262+
return vertex;
263+
}
264+
255265
private Vertex findOrCreateVertex(CommunicationEntity entity) {
256-
return entity.find(ID_PROPERTY)
266+
return entity.find(ID)
257267
.flatMap(id -> findVertexById(id.get()))
258-
.orElseGet(() -> {
259-
var newVertex = graph.addVertex(entity.name());
260-
entity.elements().forEach(e -> newVertex.property(e.name(), ValueUtil.convert(e.value())));
261-
newVertex.property(ID_PROPERTY, newVertex.id());
262-
entity.add(ID_PROPERTY, newVertex.id());
263-
return newVertex;
264-
});
268+
.orElseGet(() -> addVertex(entity));
265269
}
266270

267271
private Optional<Vertex> findVertexById(Object id) {

jnosql-tinkerpop/src/main/java/org/eclipse/jnosql/databases/tinkerpop/communication/TinkerpopGraphDatabaseManager.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package org.eclipse.jnosql.databases.tinkerpop.communication;
1616

1717
import org.apache.tinkerpop.gremlin.structure.Graph;
18+
import org.apache.tinkerpop.gremlin.structure.T;
1819
import org.eclipse.jnosql.communication.graph.GraphDatabaseManager;
1920
import org.eclipse.jnosql.communication.semistructured.DatabaseManager;
2021

@@ -35,6 +36,8 @@
3536
*/
3637
public interface TinkerpopGraphDatabaseManager extends GraphDatabaseManager, Supplier<Graph> {
3738

39+
String ID = T.id.getAccessor();
40+
3841
/**
3942
* Creates a new instance of DefaultGraphDatabaseManager with the specified TinkerPop Graph.
4043
*

jnosql-tinkerpop/src/test/java/org/eclipse/jnosql/databases/tinkerpop/communication/DefaultTinkerpopGraphDatabaseManagerTest.java

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import static org.assertj.core.api.Assertions.assertThat;
4343
import static org.eclipse.jnosql.communication.semistructured.DeleteQuery.delete;
4444
import static org.eclipse.jnosql.communication.semistructured.SelectQuery.select;
45+
import static org.eclipse.jnosql.databases.tinkerpop.communication.TinkerpopGraphDatabaseManager.ID;
4546
import static org.junit.jupiter.api.Assertions.assertEquals;
4647
import static org.junit.jupiter.api.Assertions.assertFalse;
4748
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -50,7 +51,7 @@
5051

5152
class DefaultTinkerpopGraphDatabaseManagerTest {
5253

53-
public static final String COLLECTION_NAME = "person";
54+
public static final String COLLECTION_NAME = "Person";
5455

5556
private TinkerpopGraphDatabaseManager entityManager;
5657

@@ -80,7 +81,7 @@ void shouldInsertEntity(){
8081
SoftAssertions.assertSoftly(softly -> {
8182
softly.assertThat(communicationEntity.find("name", String.class)).get().isEqualTo(name);
8283
softly.assertThat(communicationEntity.find("age", int.class)).get().isEqualTo(age);
83-
softly.assertThat(communicationEntity.find(DefaultTinkerpopGraphDatabaseManager.ID_PROPERTY)).isPresent();
84+
softly.assertThat(communicationEntity.find(ID)).isPresent();
8485
});
8586
}
8687

@@ -106,11 +107,11 @@ void shouldInsertEntities(){
106107
softly.assertThat(communicationEntities).hasSize(2);
107108
softly.assertThat(communicationEntities.get(0).find("name", String.class)).get().isEqualTo(name);
108109
softly.assertThat(communicationEntities.get(0).find("age", int.class)).get().isEqualTo(age);
109-
softly.assertThat(communicationEntities.get(0).find(DefaultTinkerpopGraphDatabaseManager.ID_PROPERTY)).isPresent();
110+
softly.assertThat(communicationEntities.get(0).find(ID)).isPresent();
110111

111112
softly.assertThat(communicationEntities.get(1).find("name", String.class)).get().isEqualTo(name2);
112113
softly.assertThat(communicationEntities.get(1).find("age", int.class)).get().isEqualTo(age2);
113-
softly.assertThat(communicationEntities.get(1).find(DefaultTinkerpopGraphDatabaseManager.ID_PROPERTY)).isPresent();
114+
softly.assertThat(communicationEntities.get(1).find(ID)).isPresent();
114115
});
115116

116117
}
@@ -119,7 +120,7 @@ void shouldInsertEntities(){
119120
void shouldInsert() {
120121
var entity = getEntity();
121122
var documentEntity = entityManager.insert(entity);
122-
assertTrue(documentEntity.elements().stream().map(Element::name).anyMatch(s -> s.equals("_id")));
123+
assertTrue(documentEntity.elements().stream().map(Element::name).anyMatch(s -> s.equals(ID)));
123124
}
124125

125126
@Test
@@ -142,11 +143,11 @@ void shouldUpdate() {
142143
void shouldRemoveEntity() {
143144
var documentEntity = entityManager.insert(getEntity());
144145

145-
Optional<Element> id = documentEntity.find("_id");
146+
Optional<Element> id = documentEntity.find(ID);
146147
var query = select().from(COLLECTION_NAME)
147-
.where("_id").eq(id.orElseThrow().get())
148+
.where(ID).eq(id.orElseThrow().get())
148149
.build();
149-
var deleteQuery = delete().from(COLLECTION_NAME).where("_id")
150+
var deleteQuery = delete().from(COLLECTION_NAME).where(ID)
150151
.eq(id.get().get())
151152
.build();
152153

@@ -157,10 +158,10 @@ void shouldRemoveEntity() {
157158
@Test
158159
void shouldFindDocument() {
159160
var entity = entityManager.insert(getEntity());
160-
Optional<Element> id = entity.find("_id");
161+
Optional<Element> id = entity.find(ID);
161162

162163
var query = select().from(COLLECTION_NAME)
163-
.where("_id").eq(id.orElseThrow().get())
164+
.where(ID).eq(id.orElseThrow().get())
164165
.build();
165166

166167
var entities = entityManager.select(query).collect(Collectors.toList());
@@ -171,11 +172,12 @@ void shouldFindDocument() {
171172
@Test
172173
void shouldFindDocument2() {
173174
var entity = entityManager.insert(getEntity());
174-
Optional<Element> id = entity.find("_id");
175+
Optional<Element> id = entity.find(ID);
175176

176177
var query = select().from(COLLECTION_NAME)
177178
.where("name").eq("Poliana")
178-
.and("city").eq("Salvador").and("_id").eq(id.orElseThrow().get())
179+
.and("city").eq("Salvador")
180+
.and(ID).eq(id.orElseThrow().get())
179181
.build();
180182

181183
List<CommunicationEntity> entities = entityManager.select(query).collect(Collectors.toList());
@@ -186,11 +188,11 @@ void shouldFindDocument2() {
186188
@Test
187189
void shouldFindDocument3() {
188190
var entity = entityManager.insert(getEntity());
189-
Optional<Element> id = entity.find("_id");
191+
Optional<Element> id = entity.find(ID);
190192
var query = select().from(COLLECTION_NAME)
191193
.where("name").eq("Poliana")
192194
.or("city").eq("Salvador")
193-
.and(id.orElseThrow().name()).eq(id.get().get())
195+
.and(ID).eq(id.orElseThrow().get())
194196
.build();
195197

196198
List<CommunicationEntity> entities = entityManager.select(query).collect(Collectors.toList());
@@ -426,7 +428,7 @@ void shouldFindAllByFields() {
426428
assertEquals(3, entity.size());
427429
SoftAssertions.assertSoftly(softly -> {
428430
softly.assertThat(entity.find("name")).isPresent();
429-
softly.assertThat(entity.find("_id")).isPresent();
431+
softly.assertThat(entity.find(ID)).isPresent();
430432
softly.assertThat(entity.find("city")).isPresent();
431433
});
432434
}
@@ -436,15 +438,15 @@ void shouldCreateEdge() {
436438
var person1 = entityManager.insert(getEntity());
437439
var person2 = entityManager.insert(getEntity());
438440

439-
String label = "FRIEND";
441+
String label = "friend";
440442
Map<String, Object> properties = Map.of("since", 2023);
441443

442444
var edge = entityManager.edge(person1, label, person2, properties);
443445

444446
assertNotNull(edge);
445447
assertEquals(label, edge.label());
446-
assertEquals(person1.find("_id").orElseThrow().get(), edge.source().find("_id").orElseThrow().get());
447-
assertEquals(person2.find("_id").orElseThrow().get(), edge.target().find("_id").orElseThrow().get());
448+
assertEquals(person1.find(ID).orElseThrow().get(), edge.source().find(ID).orElseThrow().get());
449+
assertEquals(person2.find(ID).orElseThrow().get(), edge.target().find(ID).orElseThrow().get());
448450
assertEquals(properties, edge.properties());
449451
}
450452

@@ -453,9 +455,9 @@ void shouldRemoveEdge() {
453455
var person1 = entityManager.insert(getEntity());
454456
var person2 = entityManager.insert(getEntity());
455457

456-
CommunicationEdge communicationEdge = entityManager.edge(person1, "FRIEND", person2, Map.of());
458+
CommunicationEdge communicationEdge = entityManager.edge(person1, "friend", person2, Map.of());
457459

458-
entityManager.remove(person1, "FRIEND", person2);
460+
entityManager.remove(person1, "friend", person2);
459461

460462
var edges = entityManager.findEdgeById(communicationEdge.id());
461463

@@ -467,7 +469,7 @@ void shouldDeleteEdgeById() {
467469
var person1 = entityManager.insert(getEntity());
468470
var person2 = entityManager.insert(getEntity());
469471

470-
var edge = entityManager.edge(person1, "FRIEND", person2, Map.of());
472+
var edge = entityManager.edge(person1, "friend", person2, Map.of());
471473

472474
entityManager.deleteEdge(edge.id());
473475

@@ -480,15 +482,15 @@ void shouldFindEdgeById() {
480482
var person1 = entityManager.insert(getEntity());
481483
var person2 = entityManager.insert(getEntity());
482484

483-
var edge = entityManager.edge(person1, "FRIEND", person2, Map.of("since", 2023));
485+
var edge = entityManager.edge(person1, "friend", person2, Map.of("since", 2023));
484486

485487
Optional<CommunicationEdge> foundEdge = entityManager.findEdgeById(edge.id());
486488

487489
assertTrue(foundEdge.isPresent());
488490
assertEquals(edge.id(), foundEdge.get().id());
489491
assertEquals(edge.label(), foundEdge.get().label());
490-
assertEquals(edge.source().find("_id").orElseThrow().get(), foundEdge.get().source().find("_id").orElseThrow().get());
491-
assertEquals(edge.target().find("_id").orElseThrow().get(), foundEdge.get().target().find("_id").orElseThrow().get());
492+
assertEquals(edge.source().find(ID).orElseThrow().get(), foundEdge.get().source().find(ID).orElseThrow().get());
493+
assertEquals(edge.target().find(ID).orElseThrow().get(), foundEdge.get().target().find(ID).orElseThrow().get());
492494
}
493495

494496
@Test

jnosql-tinkerpop/src/test/java/org/eclipse/jnosql/databases/tinkerpop/communication/GraphSupplier.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,26 @@
1414
*/
1515
package org.eclipse.jnosql.databases.tinkerpop.communication;
1616

17-
import org.apache.tinkerpop.gremlin.neo4j.structure.Neo4jGraph;
1817
import org.apache.tinkerpop.gremlin.structure.Graph;
18+
import org.apache.tinkerpop.gremlin.structure.util.GraphFactory;
1919

20-
import java.io.File;
2120
import java.util.function.Supplier;
2221
import java.util.logging.Logger;
2322

24-
import static java.lang.System.currentTimeMillis;
25-
2623
public enum GraphSupplier implements Supplier<Graph> {
2724
INSTANCE;
2825

2926
private static final Logger LOGGER = Logger.getLogger(GraphSupplier.class.getName());
3027

31-
private final String directory;
32-
3328
private final Graph graph;
3429

3530
{
36-
this.directory = new File("").getAbsolutePath() + "/target/jnosql-communication-graph/" + currentTimeMillis() + "/";
37-
graph = Neo4jGraph.open(directory);
31+
graph = GraphFactory.open("src/test/resources/adb.yaml");
3832
}
3933

4034
@Override
4135
public Graph get() {
42-
LOGGER.info("Starting Graph database at directory: " + directory);
36+
LOGGER.info("Starting Graph database");
4337
return graph;
4438
}
4539
}

0 commit comments

Comments
 (0)