Skip to content

Commit

Permalink
Migrate to latests version for Spring dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
aureamunoz committed May 10, 2024
1 parent 152a01c commit 9990640
Show file tree
Hide file tree
Showing 34 changed files with 1,383 additions and 690 deletions.
8 changes: 4 additions & 4 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,10 @@
<javaparser.version>3.25.9</javaparser.version>
<hibernate-quarkus-local-cache.version>0.3.0</hibernate-quarkus-local-cache.version>
<flapdoodle.mongo.version>4.13.0</flapdoodle.mongo.version>
<quarkus-spring-api.version>5.2.SP7</quarkus-spring-api.version>
<quarkus-spring-data-api.version>2.1.SP2</quarkus-spring-data-api.version>
<quarkus-spring-security-api.version>5.4.Final</quarkus-spring-security-api.version>
<quarkus-spring-boot-api.version>2.1.SP1</quarkus-spring-boot-api.version>
<quarkus-spring-api.version>6.1.SP1</quarkus-spring-api.version>
<quarkus-spring-data-api.version>3.2</quarkus-spring-data-api.version>
<quarkus-spring-security-api.version>6.2</quarkus-spring-security-api.version>
<quarkus-spring-boot-api.version>3.2</quarkus-spring-boot-api.version>
<mockito.version>5.11.0</mockito.version>
<jna.version>5.8.0</jna.version><!-- should satisfy both testcontainers and mongodb -->
<antlr.version>4.13.0</antlr.version><!-- needs to align with same property in build-parent/pom.xml -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.ListCrudRepository;
import org.springframework.data.repository.ListPagingAndSortingRepository;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.Repository;
Expand All @@ -55,15 +57,22 @@ public final class DotNames {
.createSimple(Repository.class.getName());
public static final DotName SPRING_DATA_CRUD_REPOSITORY = DotName
.createSimple(CrudRepository.class.getName());

public static final DotName SPRING_DATA_LIST_CRUD_REPOSITORY = DotName
.createSimple(ListCrudRepository.class.getName());
public static final DotName SPRING_DATA_PAGING_REPOSITORY = DotName
.createSimple(PagingAndSortingRepository.class.getName());

public static final DotName SPRING_DATA_LIST_PAGING_REPOSITORY = DotName
.createSimple(ListPagingAndSortingRepository.class.getName());
public static final DotName SPRING_DATA_JPA_REPOSITORY = DotName
.createSimple(JpaRepository.class.getName());
public static final DotName SPRING_DATA_REPOSITORY_DEFINITION = DotName
.createSimple(RepositoryDefinition.class.getName());

public static final Set<DotName> SUPPORTED_REPOSITORIES = new HashSet<>(Arrays.asList(
SPRING_DATA_JPA_REPOSITORY, SPRING_DATA_PAGING_REPOSITORY, SPRING_DATA_CRUD_REPOSITORY, SPRING_DATA_REPOSITORY));
SPRING_DATA_JPA_REPOSITORY, SPRING_DATA_PAGING_REPOSITORY, SPRING_DATA_LIST_PAGING_REPOSITORY,
SPRING_DATA_CRUD_REPOSITORY, SPRING_DATA_LIST_CRUD_REPOSITORY, SPRING_DATA_REPOSITORY));

public static final DotName SPRING_DATA_NO_REPOSITORY_BEAN = DotName
.createSimple(NoRepositoryBean.class.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import org.springframework.data.domain.Persistable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.ListCrudRepository;
import org.springframework.data.repository.ListPagingAndSortingRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.QueryByExampleExecutor;
Expand Down Expand Up @@ -80,7 +82,9 @@ void contributeClassesToIndex(BuildProducer<AdditionalIndexedClassesBuildItem> a
additionalIndexedClasses.produce(new AdditionalIndexedClassesBuildItem(
Repository.class.getName(),
CrudRepository.class.getName(),
ListCrudRepository.class.getName(),
PagingAndSortingRepository.class.getName(),
ListPagingAndSortingRepository.class.getName(),
JpaRepository.class.getName(),
QueryByExampleExecutor.class.getName()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package io.quarkus.spring.data.deployment;

import org.springframework.data.repository.ListCrudRepository;

public interface BookListCrudRepository extends ListCrudRepository<Book, Integer> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package io.quarkus.spring.data.deployment;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Arrays;
import java.util.List;

import jakarta.inject.Inject;
import jakarta.transaction.Transactional;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BookListCrudRepositoryTest {

@RegisterExtension
static final QuarkusUnitTest TEST = new QuarkusUnitTest().setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class)
.addAsResource("import_books.sql", "import.sql")
.addClasses(Book.class, BookListCrudRepository.class))
.withConfigurationResource("application.properties");

@Inject
BookListCrudRepository repo;

@Test
@Order(1)
@Transactional
public void shouldListAllBooks() {
List<Book> all = repo.findAll();
assertThat(all).isNotEmpty();
assertThat(all).hasSize(3);
assertThat(all.stream().map(Book::getName)).containsExactlyInAnyOrder("Talking to Strangers", "The Ascent of Money",
"A Short History of Everything");
}

@Test
@Order(2)
@Transactional
public void shouldListBooksWithIds() {
List<Integer> ids = Arrays.asList(1, 2);
List<Book> all = repo.findAllById(ids);
assertThat(all).isNotEmpty();
assertThat(all).hasSize(2);
assertThat(all.stream().map(Book::getName)).containsExactlyInAnyOrder("Talking to Strangers", "The Ascent of Money");
}

@Test
@Order(3)
@Transactional
public void shouldSaveBooks() {
Book harryPotterAndTheChamberOfSecrets = populateBook(4, "Harry Potter and the Chamber of Secrets");
Book harryPotterAndThePrisonerOfAzkaban = populateBook(5, "Harry Potter and the Prisoner of Azkaban");
Book harryPotterAndTheGlobetOfFire = populateBook(6, "Harry Potter and the Globet of Fire");
List<Book> books = Arrays.asList(harryPotterAndTheChamberOfSecrets, harryPotterAndThePrisonerOfAzkaban,
harryPotterAndTheGlobetOfFire);
List<Book> all = repo.saveAll(books);
assertThat(all).isNotEmpty();
assertThat(all).hasSize(3);
assertThat(all.stream().map(Book::getName)).containsExactlyInAnyOrder("Harry Potter and the Chamber of Secrets",
"Harry Potter and the Prisoner of Azkaban", "Harry Potter and the Globet of Fire");
}

private Book populateBook(Integer id, String title) {
Book book = new Book();
book.setBid(id);
book.setName(title);
return book;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package io.quarkus.spring.data.deployment;

import org.springframework.data.repository.ListPagingAndSortingRepository;

public interface BookListPagingAndSortingRepository extends ListPagingAndSortingRepository<Book, Integer> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package io.quarkus.spring.data.deployment;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;

import jakarta.inject.Inject;
import jakarta.transaction.Transactional;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import io.quarkus.test.QuarkusUnitTest;

public class BookPagingAndSortingRepositoryTest {

@RegisterExtension
static final QuarkusUnitTest TEST = new QuarkusUnitTest().setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class)
.addAsResource("import_hp_books.sql", "import.sql")
.addClasses(Book.class, BookListPagingAndSortingRepository.class))
.withConfigurationResource("application.properties");

@Inject
BookListPagingAndSortingRepository repo;

@Test
// @Order(1)
@Transactional
public void shouldReturnFirstPageOfTwoBooks() {
Pageable pageRequest = PageRequest.of(0, 2);
Page<Book> result = repo.findAll(pageRequest);

assertThat(result).isNotEmpty();
assertThat(result).hasSize(2);
assertThat(result.stream().map(Book::getBid)).containsExactly(1, 2);
}

@Test
@Transactional
public void shouldReturnSecondPageOfSizeTwoBooks() {
Pageable pageRequest = PageRequest.of(1, 2);
Page<Book> result = repo.findAll(pageRequest);

assertThat(result).isNotEmpty();
assertThat(result).hasSize(2);
assertThat(result.stream().map(Book::getBid)).containsExactly(3, 4);
}

@Test
@Transactional
public void shouldReturnLastPage() {
Pageable pageRequest = PageRequest.of(2, 2);
Page<Book> result = repo.findAll(pageRequest);

assertThat(result).isNotEmpty();
assertThat(result).hasSize(2);
assertThat(result.stream().map(Book::getBid)).containsExactly(5, 6);
}

@Test
@Transactional
void shouldReturnSortedByNameAscAndPagedResult() {
Pageable pageRequest = PageRequest.of(0, 3, Sort.by("name"));

Page<Book> result = repo.findAll(pageRequest);
assertThat(result).isNotEmpty();
assertThat(result).hasSize(3);
assertThat(result.stream().map(Book::getBid)).containsExactly(2, 7, 4);

}

@Test
@Transactional
void shouldReturnSortedByNameDescAndPagedResult() {
Pageable pageRequest = PageRequest.of(0, 5, Sort.by("name").descending());

Page<Book> result = repo.findAll(pageRequest);
assertThat(result).isNotEmpty();
assertThat(result).hasSize(5);
assertThat(result.stream().map(Book::getBid)).containsExactly(3, 1, 5, 6, 4);

}

@Test
@Transactional
void shouldReturnAllBooksSortedByNameDescResult() {
List<Book> result = repo.findAll(Sort.by("name").descending());
assertThat(result).isNotEmpty();
assertThat(result).hasSize(7);
assertThat(result.stream().map(Book::getBid)).containsExactly(3, 1, 5, 6, 4, 7, 2);

}

@Test
@Transactional
void shouldReturnAllBooksSortedByNameAscResult() {
List<Book> result = repo.findAll(Sort.by("name"));
assertThat(result).isNotEmpty();
assertThat(result).hasSize(7);
assertThat(result.stream().map(Book::getBid)).containsExactly(2, 7, 4, 6, 5, 1, 3);

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
INSERT INTO book(bid, name) VALUES (1, 'Harry Potter and the Philosophers Stone');
INSERT INTO book(bid, name) VALUES (2, 'Harry Potter and the Chamber of Secrets');
INSERT INTO book(bid, name) VALUES (3, 'Harry Potter and the Prisoner of Azkaban');
INSERT INTO book(bid, name) VALUES (4, 'Harry Potter and the Goblet of Fire');
INSERT INTO book(bid, name) VALUES (5, 'Harry Potter and the Order of the Phoenix');
INSERT INTO book(bid, name) VALUES (6, 'Harry Potter and the Half-Blood Prince');
INSERT INTO book(bid, name) VALUES (7, 'Harry Potter and the Deathly Hallows');
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package io.quarkus.spring.data.rest.deployment;

import static io.quarkus.spring.data.rest.deployment.RepositoryMethodsImplementor.CRUD_REPOSITORY_INTERFACE;
import static io.quarkus.spring.data.rest.deployment.RepositoryMethodsImplementor.JPA_REPOSITORY_INTERFACE;
import static io.quarkus.spring.data.rest.deployment.RepositoryMethodsImplementor.LIST_CRUD_REPOSITORY_INTERFACE;
import static io.quarkus.spring.data.rest.deployment.RepositoryMethodsImplementor.LIST_PAGING_AND_SORTING_REPOSITORY_INTERFACE;
import static io.quarkus.spring.data.rest.deployment.RepositoryMethodsImplementor.PAGING_AND_SORTING_REPOSITORY_INTERFACE;

import java.util.List;

import jakarta.persistence.Id;

import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.FieldInfo;
import org.jboss.jandex.IndexView;
import org.jboss.jandex.MethodInfo;
import org.jboss.jandex.Type;

import io.quarkus.deployment.bean.JavaBeanUtil;
import io.quarkus.gizmo.MethodDescriptor;

public class EntityClassHelper {

private final IndexView index;

public EntityClassHelper(IndexView index) {
this.index = index;
}

public FieldInfo getIdField(String className) {
return getIdField(index.getClassByName(DotName.createSimple(className)));
}

public FieldInfo getIdField(ClassInfo classInfo) {
ClassInfo tmpClassInfo = classInfo;
while (tmpClassInfo != null) {
for (FieldInfo field : tmpClassInfo.fields()) {
if (field.hasAnnotation(DotName.createSimple(Id.class.getName()))) {
return field;
}
}
if (tmpClassInfo.superName() != null) {
tmpClassInfo = index.getClassByName(tmpClassInfo.superName());
} else {
tmpClassInfo = null;
}
}
throw new IllegalArgumentException("Couldn't find id field of " + classInfo);
}

public MethodDescriptor getSetter(String className, FieldInfo field) {
return getSetter(index.getClassByName(DotName.createSimple(className)), field);
}

public MethodDescriptor getSetter(ClassInfo entityClass, FieldInfo field) {
MethodDescriptor setter = getMethod(entityClass, JavaBeanUtil.getSetterName(field.name()), field.type());
if (setter != null) {
return setter;
}
return MethodDescriptor.ofMethod(entityClass.toString(),
EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX + field.name(), void.class, field.type().name().toString());
}

public MethodDescriptor getMethod(ClassInfo entityClass, String name, Type... parameters) {
if (entityClass == null) {
return null;
}
MethodInfo methodInfo = entityClass.method(name, parameters);
if (methodInfo != null) {
return MethodDescriptor.of(methodInfo);
} else if (entityClass.superName() != null) {
return getMethod(index.getClassByName(entityClass.superName()), name, parameters);
}
return null;
}

public boolean isRepositoryInstanceOf(DotName target, String repositoryName) {
ClassInfo classByName = index.getClassByName(repositoryName);
List<Type> types = classByName.interfaceTypes();
return types.stream().anyMatch(type -> type.name().equals(target));
}

public boolean isCrudRepository(String repositoryName) {
return isRepositoryInstanceOf(CRUD_REPOSITORY_INTERFACE, repositoryName)
|| isRepositoryInstanceOf(LIST_CRUD_REPOSITORY_INTERFACE, repositoryName)
|| isRepositoryInstanceOf(JPA_REPOSITORY_INTERFACE, repositoryName);
}

public boolean isListCrudRepository(String repositoryName) {
return isRepositoryInstanceOf(LIST_CRUD_REPOSITORY_INTERFACE, repositoryName)
|| isRepositoryInstanceOf(JPA_REPOSITORY_INTERFACE, repositoryName);
}

public boolean isJpaRepository(String repositoryName) {
return isRepositoryInstanceOf(JPA_REPOSITORY_INTERFACE, repositoryName);
}

public boolean isPagingAndSortingRepository(String repositoryName) {
return isRepositoryInstanceOf(PAGING_AND_SORTING_REPOSITORY_INTERFACE, repositoryName)
|| isRepositoryInstanceOf(LIST_PAGING_AND_SORTING_REPOSITORY_INTERFACE, repositoryName)
|| isRepositoryInstanceOf(JPA_REPOSITORY_INTERFACE, repositoryName);
}

public boolean isListPagingAndSortingRepository(String repositoryName) {
return isRepositoryInstanceOf(LIST_PAGING_AND_SORTING_REPOSITORY_INTERFACE, repositoryName)
|| isRepositoryInstanceOf(JPA_REPOSITORY_INTERFACE, repositoryName);
}

public boolean containsPagedRepository(List<ClassInfo> repositories) {
return repositories.stream().anyMatch(r -> isPagingAndSortingRepository(r.name().toString()));
}
}
Loading

0 comments on commit 9990640

Please sign in to comment.