diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 86e496e3f8..a8f1d5c103 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -57,6 +57,7 @@ spring-boot-persistence spring-boot-persistence-h2 spring-boot-persistence-mongodb + spring-data-arangodb spring-data-cassandra spring-data-cassandra-test spring-data-cassandra-reactive diff --git a/persistence-modules/spring-data-arangodb/README.md b/persistence-modules/spring-data-arangodb/README.md new file mode 100644 index 0000000000..632d9a256e --- /dev/null +++ b/persistence-modules/spring-data-arangodb/README.md @@ -0,0 +1,6 @@ +========= + +## Spring Data ArangoDB + + +### Relevant Articles: diff --git a/persistence-modules/spring-data-arangodb/pom.xml b/persistence-modules/spring-data-arangodb/pom.xml new file mode 100644 index 0000000000..562f06ae40 --- /dev/null +++ b/persistence-modules/spring-data-arangodb/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + spring-data-arangodb + spring-data-arangodb + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter + + + + com.arangodb + arangodb-spring-data + 3.5.0 + + + + \ No newline at end of file diff --git a/persistence-modules/spring-data-arangodb/src/live-test/resources/Dockerfile b/persistence-modules/spring-data-arangodb/src/live-test/resources/Dockerfile new file mode 100644 index 0000000000..8edb2bbbf6 --- /dev/null +++ b/persistence-modules/spring-data-arangodb/src/live-test/resources/Dockerfile @@ -0,0 +1,7 @@ +FROM arangodb:3.8.0 + +COPY init-session.js /docker-entrypoint-initdb.d/ + +EXPOSE 8529 + +ENV ARANGO_ROOT_PASSWORD=password diff --git a/persistence-modules/spring-data-arangodb/src/live-test/resources/init-session.js b/persistence-modules/spring-data-arangodb/src/live-test/resources/init-session.js new file mode 100644 index 0000000000..2e968884cc --- /dev/null +++ b/persistence-modules/spring-data-arangodb/src/live-test/resources/init-session.js @@ -0,0 +1 @@ +rs.initiate(); diff --git a/persistence-modules/spring-data-arangodb/src/live-test/resources/live-test-setup.sh b/persistence-modules/spring-data-arangodb/src/live-test/resources/live-test-setup.sh new file mode 100644 index 0000000000..b1a4cfb9d0 --- /dev/null +++ b/persistence-modules/spring-data-arangodb/src/live-test/resources/live-test-setup.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +docker image build -t spring-data-arangodb:live-test . + +docker run -p 8529:8529 -e ARANGO_ROOT_PASSWORD=password --name spring-data-arangodb-live-test spring-data-arangodb:live-test diff --git a/persistence-modules/spring-data-arangodb/src/live-test/resources/live-test-teardown.sh b/persistence-modules/spring-data-arangodb/src/live-test/resources/live-test-teardown.sh new file mode 100644 index 0000000000..2199cf7403 --- /dev/null +++ b/persistence-modules/spring-data-arangodb/src/live-test/resources/live-test-teardown.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +docker stop spring-data-arangodb-live-test +docker rm spring-data-arangodb-live-test diff --git a/persistence-modules/spring-data-arangodb/src/live-test/resources/live-test.sh b/persistence-modules/spring-data-arangodb/src/live-test/resources/live-test.sh new file mode 100644 index 0000000000..307a68a3bd --- /dev/null +++ b/persistence-modules/spring-data-arangodb/src/live-test/resources/live-test.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +mvn clean compile test -P live-all -f ../../../pom.xml diff --git a/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/ArangoDbSpringDataApplication.java b/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/ArangoDbSpringDataApplication.java new file mode 100644 index 0000000000..355001df06 --- /dev/null +++ b/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/ArangoDbSpringDataApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.arangodb; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ArangoDbSpringDataApplication { + + public static void main(String[] args) { + SpringApplication.run(ArangoDbSpringDataApplication.class, args); + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/configuration/ArangoDbConfiguration.java b/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/configuration/ArangoDbConfiguration.java new file mode 100644 index 0000000000..3aae10ce60 --- /dev/null +++ b/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/configuration/ArangoDbConfiguration.java @@ -0,0 +1,24 @@ +package com.baeldung.arangodb.configuration; + +import com.arangodb.ArangoDB; +import com.arangodb.springframework.annotation.EnableArangoRepositories; +import com.arangodb.springframework.config.ArangoConfiguration; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableArangoRepositories(basePackages = {"com.baeldung"}) +public class ArangoDbConfiguration implements ArangoConfiguration { + + @Override + public ArangoDB.Builder arango() { + return new ArangoDB.Builder() + .host("127.0.0.1", 8529) + .user("root") + .password("password"); + } + + @Override + public String database() { + return "baeldung-database"; + } +} diff --git a/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/model/Article.java b/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/model/Article.java new file mode 100644 index 0000000000..ea7ee1d2a6 --- /dev/null +++ b/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/model/Article.java @@ -0,0 +1,86 @@ +package com.baeldung.arangodb.model; + +import com.arangodb.springframework.annotation.ArangoId; +import com.arangodb.springframework.annotation.Document; +import com.arangodb.springframework.annotation.Relations; +import org.springframework.data.annotation.Id; + +import java.time.ZonedDateTime; +import java.util.Collection; + +@Document("articles") +public class Article { + + @Id + private String id; + + @ArangoId + private String arangoId; + + private String name; + private String author; + private ZonedDateTime publishDate; + private String htmlContent; + + @Relations(edges = ArticleLink.class, lazy = true) + private Collection authors; + + public Article() { + super(); + } + + public Article(String name, String author, ZonedDateTime publishDate, String htmlContent) { + this.name = name; + this.author = author; + this.publishDate = publishDate; + this.htmlContent = htmlContent; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getArangoId() { + return arangoId; + } + + public void setArangoId(String arangoId) { + this.arangoId = arangoId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public ZonedDateTime getPublishDate() { + return publishDate; + } + + public void setPublishDate(ZonedDateTime publishDate) { + this.publishDate = publishDate; + } + + public String getHtmlContent() { + return htmlContent; + } + + public void setHtmlContent(String htmlContent) { + this.htmlContent = htmlContent; + } +} diff --git a/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/model/ArticleLink.java b/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/model/ArticleLink.java new file mode 100644 index 0000000000..18a35815e1 --- /dev/null +++ b/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/model/ArticleLink.java @@ -0,0 +1,39 @@ +package com.baeldung.arangodb.model; + +import com.arangodb.springframework.annotation.Edge; +import com.arangodb.springframework.annotation.From; +import com.arangodb.springframework.annotation.To; + +@Edge +public class ArticleLink { + + @From + private Article article; + + @To + private Author author; + + public ArticleLink() { + } + + public ArticleLink(Article article, Author author) { + this.article = article; + this.author = author; + } + + public Article getArticle() { + return article; + } + + public void setArticle(Article article) { + this.article = article; + } + + public Author getAuthor() { + return author; + } + + public void setAuthor(Author author) { + this.author = author; + } +} diff --git a/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/model/Author.java b/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/model/Author.java new file mode 100644 index 0000000000..6e9fed3312 --- /dev/null +++ b/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/model/Author.java @@ -0,0 +1,49 @@ +package com.baeldung.arangodb.model; + +import com.arangodb.springframework.annotation.ArangoId; +import com.arangodb.springframework.annotation.Document; +import org.springframework.data.annotation.Id; + +@Document("articles") +public class Author { + + @Id + private String id; + + @ArangoId + private String arangoId; + + private String name; + + public Author() { + super(); + } + + public Author(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getArangoId() { + return arangoId; + } + + public void setArangoId(String arangoId) { + this.arangoId = arangoId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/repository/ArticleRepository.java b/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/repository/ArticleRepository.java new file mode 100644 index 0000000000..fdc434cae4 --- /dev/null +++ b/persistence-modules/spring-data-arangodb/src/main/java/com/baeldung/arangodb/repository/ArticleRepository.java @@ -0,0 +1,17 @@ +package com.baeldung.arangodb.repository; + +import com.arangodb.springframework.annotation.Query; +import com.arangodb.springframework.repository.ArangoRepository; +import com.baeldung.arangodb.model.Article; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface ArticleRepository extends ArangoRepository { + + Iterable
findByAuthor(String author); + + @Query("FOR a IN articles FILTER a.author == @author SORT a.publishDate ASC RETURN a") + Iterable
getByAuthor(@Param("author") String author); + +} diff --git a/persistence-modules/spring-data-arangodb/src/main/resources/arangodb.properties b/persistence-modules/spring-data-arangodb/src/main/resources/arangodb.properties new file mode 100644 index 0000000000..7f8ded478c --- /dev/null +++ b/persistence-modules/spring-data-arangodb/src/main/resources/arangodb.properties @@ -0,0 +1,3 @@ +arangodb.hosts=127.0.0.1:8529 +arangodb.user=root +arangodb.password=password \ No newline at end of file diff --git a/persistence-modules/spring-data-arangodb/src/test/java/com/baeldung/arangodb/ArticleRepositoryIntegrationTest.java b/persistence-modules/spring-data-arangodb/src/test/java/com/baeldung/arangodb/ArticleRepositoryIntegrationTest.java new file mode 100644 index 0000000000..1d4258688a --- /dev/null +++ b/persistence-modules/spring-data-arangodb/src/test/java/com/baeldung/arangodb/ArticleRepositoryIntegrationTest.java @@ -0,0 +1,113 @@ +package com.baeldung.arangodb; + +import com.baeldung.arangodb.model.Article; +import com.baeldung.arangodb.repository.ArticleRepository; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@SpringBootTest +public class ArticleRepositoryIntegrationTest { + + @Autowired + ArticleRepository articleRepository; + + @Test + public void givenNewArticle_whenSaveInArangoDb_thenDataIsCorrect() { + Article newArticle = new Article( + "ArangoDb with Spring Data", + "Baeldung Writer", + ZonedDateTime.now(), + "Some HTML content" + ); + + Article savedArticle = articleRepository.save(newArticle); + + assertNotNull(savedArticle.getId()); + assertNotNull(savedArticle.getArangoId()); + + assertEquals(savedArticle.getName(), newArticle.getName()); + assertEquals(savedArticle.getAuthor(), newArticle.getAuthor()); + assertEquals(savedArticle.getPublishDate(), newArticle.getPublishDate()); + assertEquals(savedArticle.getHtmlContent(), newArticle.getHtmlContent()); + } + + @Test + public void givenArticleId_whenReadFromArangoDb_thenDataIsCorrect() { + Article newArticle = new Article( + "ArangoDb with Spring Data", + "Baeldung Writer", + ZonedDateTime.now(), + "Some HTML content" + ); + + Article savedArticle = articleRepository.save(newArticle); + + String articleId = savedArticle.getId(); + + Optional
article = articleRepository.findById(articleId); + assertTrue(article.isPresent()); + + Article foundArticle = article.get(); + + assertEquals(foundArticle.getId(), articleId); + assertEquals(foundArticle.getArangoId(), savedArticle.getArangoId()); + assertEquals(foundArticle.getName(), savedArticle.getName()); + assertEquals(foundArticle.getAuthor(), savedArticle.getAuthor()); + assertEquals(foundArticle.getPublishDate(), savedArticle.getPublishDate()); + assertEquals(foundArticle.getHtmlContent(), savedArticle.getHtmlContent()); + } + + @Test + public void givenArticleId_whenDeleteFromArangoDb_thenDataIsGone() { + Article newArticle = new Article( + "ArangoDb with Spring Data", + "Baeldung Writer", + ZonedDateTime.now(), + "Some HTML content" + ); + + Article savedArticle = articleRepository.save(newArticle); + + String articleId = savedArticle.getId(); + + articleRepository.deleteById(articleId); + + Optional
article = articleRepository.findById(articleId); + assertFalse(article.isPresent()); + } + + @Test + public void givenAuthorName_whenGetByAuthor_thenListOfArticles() { + Article newArticle = new Article( + "ArangoDb with Spring Data", + "Baeldung Writer", + ZonedDateTime.now(), + "Some HTML content" + ); + articleRepository.save(newArticle); + + Iterable
articlesByAuthor = articleRepository.findByAuthor(newArticle.getAuthor()); + List
articlesByAuthorList = new ArrayList<>(); + articlesByAuthor.forEach(articlesByAuthorList::add); + + assertEquals(1, articlesByAuthorList.size()); + + Article foundArticle = articlesByAuthorList.get(0); + assertEquals(foundArticle.getName(), newArticle.getName()); + assertEquals(foundArticle.getAuthor(), newArticle.getAuthor()); + assertEquals(foundArticle.getPublishDate(), newArticle.getPublishDate()); + assertEquals(foundArticle.getHtmlContent(), newArticle.getHtmlContent()); + } + +}