├── .github ├── CODEOWNERS ├── dependabot.yml └── workflows │ └── gradle-wrapper-updater.yml ├── jooq ├── settings.gradle ├── src │ ├── main │ │ ├── resources │ │ │ ├── application.properties │ │ │ └── mysql-schema.sql │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── jooq │ │ │ ├── user │ │ │ ├── User.java │ │ │ ├── UserRepository.java │ │ │ └── UserJooqRepository.java │ │ │ └── JooqApplication.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── jooq │ │ └── TestJooqApplication.java └── .gitignore ├── data-jpa-audit ├── src │ └── main │ │ ├── resources │ │ └── application.properties │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── data │ │ ├── user │ │ ├── UserRepository.java │ │ └── User.java │ │ ├── DataAuditApplication.java │ │ └── audit │ │ └── AuditConfiguration.java ├── settings.gradle.kts ├── .gitignore └── build.gradle.kts ├── graphql ├── settings.gradle.kts ├── src │ ├── main │ │ ├── resources │ │ │ ├── application.properties │ │ │ └── graphql │ │ │ │ └── schema.graphqls │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── graphql │ │ │ ├── book │ │ │ ├── BookRepository.java │ │ │ ├── Book.java │ │ │ ├── BookResource.java │ │ │ └── BookRepositoryImpl.java │ │ │ ├── GraphqlApplication.java │ │ │ └── configuration │ │ │ └── ScalarConfiguration.java │ └── test │ │ ├── java │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── graphql │ │ │ ├── GraphqlApplicationTests.java │ │ │ └── TestGraphqlApplication.java │ │ └── resources │ │ └── graphql-test │ │ └── books.graphql ├── .gitignore └── build.gradle.kts ├── modulith ├── settings.gradle ├── .gitattributes ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── modulith │ │ │ ├── course │ │ │ ├── CourseEnded.java │ │ │ ├── CourseRepository.java │ │ │ ├── CourseManagement.java │ │ │ ├── Course.java │ │ │ └── CourseEventsConfiguration.java │ │ │ ├── student │ │ │ ├── StudentInactivated.java │ │ │ ├── StudentRepository.java │ │ │ ├── StudentManagement.java │ │ │ ├── Student.java │ │ │ └── StudentEventsConfiguration.java │ │ │ ├── ModulithApplication.java │ │ │ └── subscription │ │ │ ├── Subscription.java │ │ │ ├── SubscriptionRepository.java │ │ │ └── SubscriptionManagement.java │ └── test │ │ ├── java │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── modulith │ │ │ ├── TestModulithApplication.java │ │ │ ├── TestcontainersConfiguration.java │ │ │ ├── ModuleTests.java │ │ │ ├── student │ │ │ └── StudentManagementTests.java │ │ │ └── course │ │ │ └── CourseManagementTests.java │ │ └── resources │ │ └── schema.sql ├── docs │ ├── all-docs.adoc │ ├── module-subscription.adoc │ ├── module-course.puml │ ├── module-student.puml │ ├── module-course.adoc │ ├── module-student.adoc │ ├── components.puml │ └── module-subscription.puml ├── .gitignore └── build.gradle.kts ├── batch-skip-step ├── src │ └── main │ │ ├── resources │ │ └── application.properties │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── batch │ │ ├── user │ │ ├── User.java │ │ └── UserFile.java │ │ └── BatchSkipStepApplication.java ├── settings.gradle.kts ├── .gitignore └── build.gradle.kts ├── data-rest-validation ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── data │ │ │ └── rest │ │ │ ├── book │ │ │ ├── BookRepository.java │ │ │ ├── AuthorRepository.java │ │ │ ├── Book.java │ │ │ ├── BookValidatorConfiguration.java │ │ │ ├── Author.java │ │ │ └── BeforeCreateBookValidator.java │ │ │ └── DataRestValidationApplication.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── data │ │ └── rest │ │ └── TestDataRestValidationApplication.java ├── settings.gradle.kts ├── .gitignore └── build.gradle.kts ├── batch-rest-repository ├── src │ └── main │ │ ├── resources │ │ └── application.properties │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── batch │ │ └── rest │ │ ├── BatchRestRepositoryApplication.java │ │ └── user │ │ └── User.java ├── settings.gradle.kts ├── .gitignore └── build.gradle.kts ├── data-domain-events ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── data │ │ │ └── de │ │ │ ├── book │ │ │ ├── BookRepository.java │ │ │ ├── BookPurchaseEvent.java │ │ │ ├── BookResource.java │ │ │ └── Book.java │ │ │ ├── DataDomainEventsApplication.java │ │ │ └── availability │ │ │ ├── BookAvailabilityRepository.java │ │ │ ├── BookAvailability.java │ │ │ └── BookAvailabilityManagement.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── data │ │ └── de │ │ └── TestDataDomainEventsApplication.java ├── settings.gradle.kts ├── .gitignore └── build.gradle.kts ├── data-envers-audit ├── src │ └── main │ │ ├── resources │ │ └── application.properties │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── data │ │ └── envers │ │ ├── book │ │ ├── BookRepository.java │ │ └── Book.java │ │ └── DataEnversAuditApplication.java ├── settings.gradle.kts ├── .gitignore └── build.gradle.kts ├── data-mongodb-audit ├── src │ └── main │ │ ├── resources │ │ └── application.properties │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── data │ │ └── mongodb │ │ ├── user │ │ ├── UserRepository.java │ │ └── User.java │ │ ├── DataMongodbAuditApplication.java │ │ └── audit │ │ └── MongoAuditConfiguration.java ├── settings.gradle.kts ├── .gitignore └── build.gradle.kts ├── test-rest-assured ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── test │ │ │ └── restassured │ │ │ ├── user │ │ │ ├── UserRequest.java │ │ │ ├── UserReadOnly.java │ │ │ ├── UserRepository.java │ │ │ └── User.java │ │ │ └── TestRestAssuredApplication.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── test │ │ └── restassured │ │ ├── user │ │ └── UserCreationTestExecutionListener.java │ │ └── TestTestRestAssuredApplication.java ├── settings.gradle ├── .gitignore └── build.gradle.kts ├── data-jdbc-audit ├── settings.gradle.kts ├── .gitattributes ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── data │ │ │ └── jdbc │ │ │ ├── user │ │ │ ├── UserRepository.java │ │ │ └── User.java │ │ │ ├── DataJdbcAuditApplication.java │ │ │ └── audit │ │ │ └── AuditConfiguration.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── data │ │ └── jdbc │ │ ├── TestDataJdbcAuditApplication.java │ │ └── TestcontainersConfiguration.java ├── .gitignore └── build.gradle.kts ├── data-jpa-event ├── settings.gradle.kts ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── data │ │ │ └── event │ │ │ ├── user │ │ │ ├── UserRepository.java │ │ │ ├── UserBeforeSaveEvent.java │ │ │ ├── UserEventPublisher.java │ │ │ ├── User.java │ │ │ └── UserValidation.java │ │ │ └── DataJpaEventApplication.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── data │ │ └── event │ │ ├── TestDataJpaEventApplication.java │ │ └── TestcontainersConfiguration.java ├── .gitignore └── build.gradle.kts ├── data-jpa-filtered-query ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── data │ │ │ └── jpa │ │ │ ├── country │ │ │ ├── CountryRepository.java │ │ │ └── Country.java │ │ │ ├── user │ │ │ ├── UserRepository.java │ │ │ └── User.java │ │ │ ├── DataJpaFilteredQueryApplication.java │ │ │ └── jpa │ │ │ ├── JpaConfiguration.java │ │ │ └── JpaCustomBaseRepository.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── data │ │ └── jpa │ │ └── TestDataJpaFilteredQueryApplication.java ├── settings.gradle.kts ├── .gitignore └── build.gradle.kts ├── data-mongodb-tc-data-load ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── data │ │ │ └── mongodb │ │ │ └── tc │ │ │ └── dataload │ │ │ ├── user │ │ │ ├── User.java │ │ │ └── UserRepository.java │ │ │ └── DataMongodbTcDataLoadApplication.java │ └── test │ │ └── resources │ │ └── users.json ├── settings.gradle.kts ├── .gitignore └── build.gradle.kts ├── data-mongodb-transactional ├── src │ └── main │ │ ├── resources │ │ └── application.properties │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── data │ │ └── mongodb │ │ └── tm │ │ ├── user │ │ ├── UserRepository.java │ │ ├── UpdateUserStatus.java │ │ ├── UserResource.java │ │ └── User.java │ │ ├── DataMongodbTransactionalApplication.java │ │ └── transaction │ │ └── MongoTransactionManagerConfiguration.java ├── settings.gradle.kts ├── .gitignore └── build.gradle.kts ├── test-execution-listeners ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── test │ │ │ ├── TestExecutionListenersApplication.java │ │ │ └── user │ │ │ ├── UserRepository.java │ │ │ └── User.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── test │ │ └── user │ │ ├── UserCreationTestExecutionListener.java │ │ ├── UserDeletionTestExecutionListener.java │ │ └── UserStatusUpdateTestExecutionListener.java ├── settings.gradle ├── .gitignore └── build.gradle.kts ├── web-rest-client ├── settings.gradle ├── .gitattributes ├── src │ └── main │ │ ├── resources │ │ └── application.properties │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── web │ │ └── restclient │ │ ├── post │ │ ├── Post.java │ │ └── PostRepository.java │ │ ├── user │ │ ├── User.java │ │ └── UserRepository.java │ │ └── WebRestClientApplication.java ├── .gitignore └── build.gradle.kts ├── data-mongodb-full-text-search ├── src │ └── main │ │ ├── resources │ │ └── application.properties │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── data │ │ └── mongodb │ │ ├── character │ │ ├── CharacterSearchRepository.java │ │ ├── CharacterRepository.java │ │ ├── Character.java │ │ └── CharacterSearchRepositoryImpl.java │ │ └── DataMongodbFullTextSearchApplication.java ├── settings.gradle.kts ├── .gitignore └── build.gradle.kts ├── data-redis-cache ├── settings.gradle.kts ├── .gitattributes ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── dataredis │ │ │ └── cache │ │ │ ├── DataRedisCacheApplication.java │ │ │ ├── customer │ │ │ ├── CustomerRepository.java │ │ │ └── Customer.java │ │ │ └── cache │ │ │ └── CacheConfiguration.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── dataredis │ │ └── cache │ │ ├── TestDataRedisCacheApplication.java │ │ └── TestcontainersConfiguration.java ├── .gitignore └── build.gradle.kts ├── supplemental-ui └── partials │ ├── edit-this-page.hbs │ ├── footer-content.hbs │ └── header-content.hbs ├── cloud-jdbc-env-repo ├── settings.gradle.kts ├── src │ ├── main │ │ ├── resources │ │ │ ├── application.yml │ │ │ ├── META-INF │ │ │ │ └── spring.factories │ │ │ └── bootstrap.yml │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── cloud │ │ │ └── jdbcenvrepo │ │ │ ├── greet │ │ │ ├── GreetProperties.java │ │ │ ├── GreetConfiguration.java │ │ │ └── GreetResource.java │ │ │ └── CloudJdbcEnvRepoApplication.java │ └── test │ │ ├── resources │ │ └── init-script.sql │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── cloud │ │ └── jdbcenvrepo │ │ └── CloudJdbcEnvRepoApplicationTests.java ├── .gitignore └── build.gradle.kts ├── web-thymeleaf-xss ├── settings.gradle.kts ├── .gitattributes ├── src │ ├── main │ │ ├── resources │ │ │ ├── application.properties │ │ │ └── templates │ │ │ │ └── greet.html │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── web │ │ │ └── xss │ │ │ ├── WebThymeleafXssApplication.java │ │ │ ├── greet │ │ │ └── GreetResource.java │ │ │ └── security │ │ │ └── SecurityConfiguration.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── web │ │ └── xss │ │ ├── WebThymeleafXssApplicationTests.java │ │ └── greet │ │ └── GreetResourceTests.java ├── .gitignore └── build.gradle.kts ├── test-slice-tests-rest ├── settings.gradle ├── .gitattributes ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── test │ │ │ └── slices │ │ │ ├── user │ │ │ ├── Name.java │ │ │ ├── UserWithoutId.java │ │ │ ├── UserRepository.java │ │ │ ├── User.java │ │ │ └── UserResource.java │ │ │ ├── TestSliceTestsApplication.java │ │ │ └── security │ │ │ └── WebSecurityConfiguration.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── test │ │ └── slices │ │ ├── TestTestSliceTestsApplication.java │ │ └── TestcontainersConfiguration.java ├── .gitignore └── build.gradle.kts ├── data-repository-definition ├── settings.gradle.kts ├── .gitattributes ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── data │ │ │ └── repositorydefinition │ │ │ ├── note │ │ │ ├── Note.java │ │ │ └── NoteRepository.java │ │ │ └── DataRepositoryDefinitionApplication.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── data │ │ └── repositorydefinition │ │ ├── TestDataRepositoryDefinitionApplication.java │ │ └── TestcontainersConfiguration.java ├── .gitignore └── build.gradle.kts ├── data-rest-composite-id ├── settings.gradle.kts ├── .gitattributes ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── datarest │ │ │ └── compositeid │ │ │ ├── book │ │ │ ├── AuthorRepository.java │ │ │ ├── BookRepository.java │ │ │ ├── AuthorIdReferencedConverter.java │ │ │ ├── BookRepositoryRestConfigurer.java │ │ │ ├── BookIdConverter.java │ │ │ ├── Author.java │ │ │ └── AuthorIdConverter.java │ │ │ └── DataRestCompositeIdApplication.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── datarest │ │ └── compositeid │ │ ├── TestDataRestCompositeIdApplication.java │ │ └── TestcontainersConfiguration.java ├── .gitignore └── build.gradle.kts ├── data-jdbc-schema-generation ├── settings.gradle.kts ├── .gitattributes ├── src │ ├── main │ │ ├── resources │ │ │ ├── application.properties │ │ │ └── db │ │ │ │ └── changelog │ │ │ │ ├── db.changelog-master.yaml │ │ │ │ └── user.yaml │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── boot │ │ │ └── jdbcscgm │ │ │ ├── book │ │ │ ├── BookRepository.java │ │ │ ├── AuthorRepository.java │ │ │ ├── Author.java │ │ │ └── Book.java │ │ │ └── DataJdbcSchemaGenerationApplication.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── boot │ │ └── jdbcscgm │ │ ├── TestDataJdbcSchemaGenerationApplication.java │ │ ├── TestcontainersConfiguration.java │ │ └── book │ │ └── BookRepositoryTests.java ├── .gitignore └── build.gradle.kts ├── data-jpa-hibernate-cache ├── settings.gradle.kts ├── .gitattributes ├── src │ ├── main │ │ ├── resources │ │ │ ├── ehcache.xml │ │ │ └── application.properties │ │ └── java │ │ │ └── zin │ │ │ └── rashidi │ │ │ └── datajpa │ │ │ └── hibernatecache │ │ │ ├── customer │ │ │ ├── CustomerRepository.java │ │ │ └── Customer.java │ │ │ └── DataJpaHibernateCacheApplication.java │ └── test │ │ └── java │ │ └── zin │ │ └── rashidi │ │ └── datajpa │ │ └── hibernatecache │ │ ├── TestDataJpaHibernateCacheApplication.java │ │ └── TestcontainersConfiguration.java ├── .gitignore └── build.gradle.kts ├── docs ├── antora.yml └── modules │ └── ROOT │ └── pages │ └── index.adoc ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── antora-playbook.yml ├── .gitignore ├── settings.gradle.kts └── LICENSE /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | @rashidi 2 | -------------------------------------------------------------------------------- /jooq/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'jooq' 2 | -------------------------------------------------------------------------------- /jooq/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data-jpa-audit/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /graphql/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "graphql" -------------------------------------------------------------------------------- /graphql/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modulith/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'modulith' 2 | -------------------------------------------------------------------------------- /batch-skip-step/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data-rest-validation/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /batch-rest-repository/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data-domain-events/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data-envers-audit/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data-mongodb-audit/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test-rest-assured/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /batch-skip-step/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "batch-skip-step" -------------------------------------------------------------------------------- /data-jdbc-audit/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-jdbc-audit" -------------------------------------------------------------------------------- /data-jpa-audit/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-jpa-audit" -------------------------------------------------------------------------------- /data-jpa-event/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-jpa-event" -------------------------------------------------------------------------------- /data-jpa-filtered-query/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data-mongodb-tc-data-load/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data-mongodb-transactional/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test-execution-listeners/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /web-rest-client/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'web-rest-client' 2 | -------------------------------------------------------------------------------- /data-domain-events/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-domain-events" -------------------------------------------------------------------------------- /data-envers-audit/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-envers-audit" -------------------------------------------------------------------------------- /data-mongodb-audit/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-mongodb-audit" -------------------------------------------------------------------------------- /data-mongodb-full-text-search/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data-redis-cache/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-redis-cache" 2 | -------------------------------------------------------------------------------- /supplemental-ui/partials/edit-this-page.hbs: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /test-rest-assured/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'test-rest-assured' 2 | -------------------------------------------------------------------------------- /batch-rest-repository/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "batch-rest-repository" -------------------------------------------------------------------------------- /cloud-jdbc-env-repo/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "cloud-jdbc-env-repo" -------------------------------------------------------------------------------- /data-rest-validation/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-rest-validation" -------------------------------------------------------------------------------- /web-thymeleaf-xss/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "web-thymeleaf-xss" 2 | -------------------------------------------------------------------------------- /data-jpa-filtered-query/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-jpa-filtered-query" -------------------------------------------------------------------------------- /test-slice-tests-rest/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'test-slice-tests-rest' 2 | -------------------------------------------------------------------------------- /data-mongodb-tc-data-load/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-mongodb-tc-data-load" -------------------------------------------------------------------------------- /data-mongodb-transactional/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-mongodb-transactional" -------------------------------------------------------------------------------- /data-repository-definition/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-repository-definition" -------------------------------------------------------------------------------- /data-rest-composite-id/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-rest-composite-id" 2 | -------------------------------------------------------------------------------- /modulith/.gitattributes: -------------------------------------------------------------------------------- 1 | /gradlew text eol=lf 2 | *.bat text eol=crlf 3 | *.jar binary 4 | -------------------------------------------------------------------------------- /test-execution-listeners/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'test-execution-listeners' 2 | -------------------------------------------------------------------------------- /cloud-jdbc-env-repo/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | app: 2 | greet: 3 | name: Default -------------------------------------------------------------------------------- /data-jdbc-audit/.gitattributes: -------------------------------------------------------------------------------- 1 | /gradlew text eol=lf 2 | *.bat text eol=crlf 3 | *.jar binary 4 | -------------------------------------------------------------------------------- /data-jdbc-schema-generation/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-jdbc-schema-generation" -------------------------------------------------------------------------------- /data-jpa-hibernate-cache/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-jpa-hibernate-cache" 2 | -------------------------------------------------------------------------------- /data-redis-cache/.gitattributes: -------------------------------------------------------------------------------- 1 | /gradlew text eol=lf 2 | *.bat text eol=crlf 3 | *.jar binary 4 | -------------------------------------------------------------------------------- /web-rest-client/.gitattributes: -------------------------------------------------------------------------------- 1 | /gradlew text eol=lf 2 | *.bat text eol=crlf 3 | *.jar binary 4 | -------------------------------------------------------------------------------- /web-thymeleaf-xss/.gitattributes: -------------------------------------------------------------------------------- 1 | /gradlew text eol=lf 2 | *.bat text eol=crlf 3 | *.jar binary 4 | -------------------------------------------------------------------------------- /data-jdbc-audit/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=data-jdbc-audit 2 | -------------------------------------------------------------------------------- /data-jpa-event/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=data-jpa-event 2 | -------------------------------------------------------------------------------- /data-mongodb-full-text-search/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "data-mongodb-full-text-search" -------------------------------------------------------------------------------- /data-redis-cache/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=data-redis-cache 2 | -------------------------------------------------------------------------------- /data-rest-composite-id/.gitattributes: -------------------------------------------------------------------------------- 1 | /gradlew text eol=lf 2 | *.bat text eol=crlf 3 | *.jar binary 4 | -------------------------------------------------------------------------------- /test-slice-tests-rest/.gitattributes: -------------------------------------------------------------------------------- 1 | /gradlew text eol=lf 2 | *.bat text eol=crlf 3 | *.jar binary 4 | -------------------------------------------------------------------------------- /web-rest-client/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=web-rest-client 2 | -------------------------------------------------------------------------------- /data-jdbc-schema-generation/.gitattributes: -------------------------------------------------------------------------------- 1 | /gradlew text eol=lf 2 | *.bat text eol=crlf 3 | *.jar binary 4 | -------------------------------------------------------------------------------- /data-jpa-hibernate-cache/.gitattributes: -------------------------------------------------------------------------------- 1 | /gradlew text eol=lf 2 | *.bat text eol=crlf 3 | *.jar binary 4 | -------------------------------------------------------------------------------- /data-repository-definition/.gitattributes: -------------------------------------------------------------------------------- 1 | /gradlew text eol=lf 2 | *.bat text eol=crlf 3 | *.jar binary 4 | -------------------------------------------------------------------------------- /web-thymeleaf-xss/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=web-thymeleaf-xss 2 | -------------------------------------------------------------------------------- /data-rest-composite-id/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=data-rest-composite-id -------------------------------------------------------------------------------- /test-slice-tests-rest/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=test-slice-tests-rest 2 | -------------------------------------------------------------------------------- /data-repository-definition/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=data-repository-definition 2 | -------------------------------------------------------------------------------- /docs/antora.yml: -------------------------------------------------------------------------------- 1 | name: main 2 | title: Spring Boot Tutorials 3 | version: master 4 | nav: 5 | - modules/ROOT/nav.adoc 6 | -------------------------------------------------------------------------------- /data-jdbc-schema-generation/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=data-jdbc-schema-generation 2 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.configuration-cache=true 2 | org.gradle.caching=true 3 | org.gradle.jvmargs=-Xmx4g -XX:+UseZGC 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rashidi/spring-boot-tutorials/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /modulith/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=modulith 2 | spring.modulith.events.jdbc.schema-initialization.enabled=true -------------------------------------------------------------------------------- /data-jdbc-schema-generation/src/main/resources/db/changelog/db.changelog-master.yaml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - include: 3 | file: db/changelog/user.yaml -------------------------------------------------------------------------------- /data-mongodb-tc-data-load/src/test/resources/users.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "_class": "zin.rashidi.data.mongodb.tc.dataload.user.User", 3 | "name": "Rashidi Zin", 4 | "username": "rashidi.zin" 5 | }] -------------------------------------------------------------------------------- /jooq/src/main/java/zin/rashidi/boot/jooq/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.jooq.user; 2 | 3 | /** 4 | * @author Rashidi Zin 5 | */ 6 | record User(Integer id, String name, String username) { 7 | } 8 | -------------------------------------------------------------------------------- /test-slice-tests-rest/src/main/java/zin/rashidi/boot/test/slices/user/Name.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.slices.user; 2 | 3 | /** 4 | * @author Rashidi Zin 5 | */ 6 | record Name(String first, String last) { 7 | } 8 | -------------------------------------------------------------------------------- /test-rest-assured/src/main/java/zin/rashidi/boot/test/restassured/user/UserRequest.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.restassured.user; 2 | 3 | /** 4 | * @author Rashidi Zin 5 | */ 6 | record UserRequest(String name, String username) { 7 | } 8 | -------------------------------------------------------------------------------- /web-rest-client/src/main/java/zin/rashidi/boot/web/restclient/post/Post.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.web.restclient.post; 2 | 3 | /** 4 | * @author Rashidi Zin 5 | */ 6 | record Post(Long id, Long userId, String title, String body) { 7 | } 8 | -------------------------------------------------------------------------------- /data-jpa-hibernate-cache/src/main/resources/ehcache.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 5 | 6 | 7 | -------------------------------------------------------------------------------- /jooq/src/main/resources/mysql-schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS USERS( 2 | `id` INT AUTO_INCREMENT PRIMARY KEY, 3 | `name` TEXT NOT NULL, 4 | `username` VARCHAR(60) NOT NULL UNIQUE 5 | ); -------------------------------------------------------------------------------- /batch-skip-step/src/main/java/zin/rashidi/boot/batch/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.batch.user; 2 | 3 | import org.springframework.data.annotation.Id; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | record User(@Id Long id, String name, String username) { 9 | } 10 | -------------------------------------------------------------------------------- /cloud-jdbc-env-repo/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.cloud.bootstrap.BootstrapConfiguration=\ 2 | org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ 3 | org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration 4 | -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/course/CourseEnded.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.course; 2 | 3 | import org.jmolecules.event.annotation.DomainEvent; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | @DomainEvent 9 | public record CourseEnded(Long id) {} 10 | -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/student/StudentInactivated.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.student; 2 | 3 | import org.jmolecules.event.annotation.DomainEvent; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | @DomainEvent 9 | public record StudentInactivated(Long id) {} -------------------------------------------------------------------------------- /jooq/src/main/java/zin/rashidi/boot/jooq/user/UserRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.jooq.user; 2 | 3 | import java.util.Optional; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | interface UserRepository { 9 | 10 | Optional findByUsername(String username); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /web-rest-client/src/main/java/zin/rashidi/boot/web/restclient/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.web.restclient.user; 2 | 3 | import java.net.URI; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | record User(Long id, String name, String username, String email, URI website) { 9 | } 10 | -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/student/StudentRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.student; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | interface StudentRepository extends CrudRepository {} 9 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gradle 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | - package-ecosystem: github-actions 9 | directory: "/" 10 | schedule: 11 | interval: weekly 12 | open-pull-requests-limit: 10 13 | -------------------------------------------------------------------------------- /data-jdbc-audit/src/main/java/zin/rashidi/boot/data/jdbc/user/UserRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jdbc.user; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | interface UserRepository extends CrudRepository { 9 | } 10 | -------------------------------------------------------------------------------- /data-jpa-audit/src/main/java/zin/rashidi/boot/data/user/UserRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.user; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | interface UserRepository extends JpaRepository { 9 | } 10 | -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/course/CourseRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.course; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | interface CourseRepository extends CrudRepository { 9 | } 10 | -------------------------------------------------------------------------------- /data-repository-definition/src/main/java/zin/rashidi/data/repositorydefinition/note/Note.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.repositorydefinition.note; 2 | 3 | import org.springframework.data.annotation.Id; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | record Note(@Id Long id, String title, String content) { 9 | } 10 | -------------------------------------------------------------------------------- /graphql/src/main/java/zin/rashidi/boot/graphql/book/BookRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.graphql.book; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | interface BookRepository { 9 | 10 | List findAll(); 11 | 12 | Book findByTitle(String title); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /data-jdbc-schema-generation/src/main/java/zin/rashidi/boot/jdbcscgm/book/BookRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.jdbcscgm.book; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | interface BookRepository extends CrudRepository { 9 | } 10 | -------------------------------------------------------------------------------- /test-slice-tests-rest/src/main/java/zin/rashidi/boot/test/slices/user/UserWithoutId.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.slices.user; 2 | 3 | import zin.rashidi.boot.test.slices.user.User.Status; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | record UserWithoutId(String name, String username, Status status) { 9 | } 10 | -------------------------------------------------------------------------------- /data-domain-events/src/main/java/zin/rashidi/boot/data/de/book/BookRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.de.book; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | public interface BookRepository extends JpaRepository { 9 | } 10 | -------------------------------------------------------------------------------- /data-jdbc-schema-generation/src/main/java/zin/rashidi/boot/jdbcscgm/book/AuthorRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.jdbcscgm.book; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | interface AuthorRepository extends CrudRepository { 9 | } 10 | -------------------------------------------------------------------------------- /web-rest-client/src/main/java/zin/rashidi/boot/web/restclient/user/UserRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.web.restclient.user; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | interface UserRepository { 9 | 10 | List findAll(); 11 | 12 | User findById(Long id); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /data-jpa-filtered-query/src/main/java/zin/rashidi/boot/data/jpa/country/CountryRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jpa.country; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | interface CountryRepository extends JpaRepository { 9 | } 10 | -------------------------------------------------------------------------------- /web-thymeleaf-xss/src/main/resources/templates/greet.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Greeting 6 | 7 | 8 |

9 | 10 | -------------------------------------------------------------------------------- /batch-skip-step/src/main/java/zin/rashidi/boot/batch/user/UserFile.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.batch.user; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | record UserFile(Long id, String name, String username) { 10 | } 11 | -------------------------------------------------------------------------------- /graphql/src/test/java/zin/rashidi/boot/graphql/GraphqlApplicationTests.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.graphql; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class GraphqlApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-jpa-filtered-query/src/main/java/zin/rashidi/boot/data/jpa/user/UserRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jpa.user; 2 | 3 | import java.util.UUID; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | interface UserRepository extends JpaRepository { 11 | } 12 | -------------------------------------------------------------------------------- /data-jpa-hibernate-cache/src/main/java/zin/rashidi/datajpa/hibernatecache/customer/CustomerRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datajpa.hibernatecache.customer; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | interface CustomerRepository extends JpaRepository { 9 | } 10 | -------------------------------------------------------------------------------- /data-jpa-event/src/main/java/zin/rashidi/data/event/user/UserRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.event.user; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | interface UserRepository extends JpaRepository { 9 | 10 | boolean existsByUsername(String username); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /web-thymeleaf-xss/src/test/java/zin/rashidi/web/xss/WebThymeleafXssApplicationTests.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.web.xss; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class WebThymeleafXssApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-mongodb-audit/src/main/java/zin/rashidi/boot/data/mongodb/user/UserRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb.user; 2 | 3 | import org.bson.types.ObjectId; 4 | import org.springframework.data.mongodb.repository.MongoRepository; 5 | 6 | /** 7 | * @author Rashidi Zin 8 | */ 9 | interface UserRepository extends MongoRepository { 10 | } 11 | -------------------------------------------------------------------------------- /cloud-jdbc-env-repo/src/main/java/zin/rashidi/boot/cloud/jdbcenvrepo/greet/GreetProperties.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.cloud.jdbcenvrepo.greet; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | @ConfigurationProperties(prefix = "app.greet") 9 | record GreetProperties(String name) { 10 | } 11 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionSha256Sum=72f44c9f8ebcb1af43838f45ee5c4aa9c5444898b3468ab3f4af7b6076c5bc3f 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip 5 | networkTimeout=10000 6 | validateDistributionUrl=true 7 | zipStoreBase=GRADLE_USER_HOME 8 | zipStorePath=wrapper/dists 9 | -------------------------------------------------------------------------------- /data-mongodb-transactional/src/main/java/zin/rashidi/boot/data/mongodb/tm/user/UserRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb.tm.user; 2 | 3 | import org.bson.types.ObjectId; 4 | import org.springframework.data.mongodb.repository.MongoRepository; 5 | 6 | /** 7 | * @author Rashidi Zin 8 | */ 9 | interface UserRepository extends MongoRepository { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /data-jpa-hibernate-cache/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=data-jpa-hibernate-cache 2 | spring.jpa.properties.hibernate.cache.region.factory_class=jcache 3 | spring.jpa.properties.hibernate.cache.jcache.uri=/ehcache.xml 4 | spring.jpa.properties.hibernate.cache.jcache.provider=org.ehcache.jsr107.EhcacheCachingProvider 5 | spring.jpa.properties.hibernate.cache.use_second_level_cache=true -------------------------------------------------------------------------------- /data-jdbc-schema-generation/src/main/java/zin/rashidi/boot/jdbcscgm/book/Author.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.jdbcscgm.book; 2 | 3 | import org.springframework.data.annotation.Id; 4 | import org.springframework.data.relational.core.mapping.Table; 5 | 6 | /** 7 | * @author Rashidi Zin 8 | */ 9 | @Table 10 | class Author { 11 | 12 | @Id 13 | private Long id; 14 | private String name; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /data-jpa-event/src/test/java/zin/rashidi/data/event/TestDataJpaEventApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.event; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | 5 | public class TestDataJpaEventApplication { 6 | 7 | public static void main(String[] args) { 8 | SpringApplication.from(DataJpaEventApplication::main).with(TestcontainersConfiguration.class).run(args); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /modulith/src/test/java/zin/rashidi/boot/modulith/TestModulithApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | 5 | public class TestModulithApplication { 6 | 7 | public static void main(String[] args) { 8 | SpringApplication.from(ModulithApplication::main).with(TestcontainersConfiguration.class).run(args); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /graphql/src/test/resources/graphql-test/books.graphql: -------------------------------------------------------------------------------- 1 | query books($title: String) { 2 | findByTitle(title: $title) { 3 | title 4 | isbn { 5 | ean 6 | registrationGroup 7 | registrant 8 | publication 9 | digit 10 | } 11 | author { 12 | name { 13 | first 14 | last 15 | } 16 | } 17 | } 18 | 19 | findAll { 20 | title 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /data-jdbc-audit/src/test/java/zin/rashidi/boot/data/jdbc/TestDataJdbcAuditApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jdbc; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | 5 | public class TestDataJdbcAuditApplication { 6 | 7 | public static void main(String[] args) { 8 | SpringApplication.from(DataJdbcAuditApplication::main).with(TestcontainersConfiguration.class).run(args); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /data-mongodb-full-text-search/src/main/java/zin/rashidi/boot/data/mongodb/character/CharacterSearchRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb.character; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.domain.Sort; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | interface CharacterSearchRepository { 11 | 12 | List findByText(String text, Sort sort); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /jooq/src/main/java/zin/rashidi/boot/jooq/JooqApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.jooq; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class JooqApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(JooqApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-redis-cache/src/test/java/zin/rashidi/dataredis/cache/TestDataRedisCacheApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.dataredis.cache; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | 5 | public class TestDataRedisCacheApplication { 6 | 7 | public static void main(String[] args) { 8 | SpringApplication.from(DataRedisCacheApplication::main).with(TestcontainersConfiguration.class).run(args); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /modulith/docs/all-docs.adoc: -------------------------------------------------------------------------------- 1 | == ModulithApplication 2 | plantuml::components.puml[,,format=svg] 3 | 4 | == Course 5 | plantuml::module-course.puml[,,format=svg] 6 | include::module-course.adoc[] 7 | 8 | == Student 9 | plantuml::module-student.puml[,,format=svg] 10 | include::module-student.adoc[] 11 | 12 | == Subscription 13 | plantuml::module-subscription.puml[,,format=svg] 14 | include::module-subscription.adoc[] 15 | 16 | -------------------------------------------------------------------------------- /modulith/docs/module-subscription.adoc: -------------------------------------------------------------------------------- 1 | [%autowidth.stretch, cols="h,a"] 2 | |=== 3 | |Base package 4 | |`zin.rashidi.boot.modulith.subscription` 5 | |Spring components 6 | |_Repositories_ 7 | 8 | * `z.r.b.m.s.SubscriptionRepository` 9 | 10 | _Event listeners_ 11 | 12 | * `z.r.b.m.s.SubscriptionManagement` 13 | |Events listened to 14 | |* `z.r.b.m.c.CourseEnded` (async) 15 | * `z.r.b.m.s.StudentInactivated` (async) 16 | |=== 17 | -------------------------------------------------------------------------------- /graphql/src/main/java/zin/rashidi/boot/graphql/GraphqlApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.graphql; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class GraphqlApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(GraphqlApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /graphql/src/main/java/zin/rashidi/boot/graphql/book/Book.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.graphql.book; 2 | 3 | /** 4 | * @author Rashidi Zin 5 | */ 6 | record Book(Isbn isbn, String title, Author author) { 7 | 8 | record Author(Name name) { 9 | 10 | record Name(String first, String last) {} 11 | 12 | } 13 | 14 | record Isbn(long ean, long registrationGroup, long registrant, long publication, int digit) {} 15 | 16 | } 17 | -------------------------------------------------------------------------------- /test-slice-tests-rest/src/test/java/zin/rashidi/boot/test/slices/TestTestSliceTestsApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.slices; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | 5 | public class TestTestSliceTestsApplication { 6 | 7 | public static void main(String[] args) { 8 | SpringApplication.from(TestSliceTestsApplication::main).with(TestcontainersConfiguration.class).run(args); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /data-envers-audit/src/main/java/zin/rashidi/boot/data/envers/book/BookRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.envers.book; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.repository.history.RevisionRepository; 5 | 6 | /** 7 | * @author Rashidi Zin 8 | */ 9 | public interface BookRepository extends JpaRepository, RevisionRepository { 10 | } 11 | -------------------------------------------------------------------------------- /data-rest-composite-id/src/main/java/zin/rashidi/datarest/compositeid/book/AuthorRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datarest.compositeid.book; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 5 | 6 | /** 7 | * @author Rashidi Zin 8 | */ 9 | @RepositoryRestResource 10 | interface AuthorRepository extends JpaRepository { 11 | } 12 | -------------------------------------------------------------------------------- /data-jpa-event/src/main/java/zin/rashidi/data/event/DataJpaEventApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.event; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataJpaEventApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataJpaEventApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-mongodb-tc-data-load/src/main/java/zin/rashidi/data/mongodb/tc/dataload/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.mongodb.tc.dataload.user; 2 | 3 | import org.bson.types.ObjectId; 4 | import org.springframework.data.annotation.Id; 5 | import org.springframework.data.mongodb.core.mapping.Document; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | @Document 11 | record User(@Id ObjectId id, String username, String name) { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/ModulithApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ModulithApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ModulithApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /batch-skip-step/src/main/java/zin/rashidi/boot/batch/BatchSkipStepApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.batch; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class BatchSkipStepApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(BatchSkipStepApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-jpa-audit/src/main/java/zin/rashidi/boot/data/DataAuditApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataAuditApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataAuditApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-mongodb-tc-data-load/src/main/java/zin/rashidi/data/mongodb/tc/dataload/user/UserRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.mongodb.tc.dataload.user; 2 | 3 | import org.bson.types.ObjectId; 4 | import org.springframework.data.mongodb.repository.MongoRepository; 5 | 6 | /** 7 | * @author Rashidi Zin 8 | */ 9 | interface UserRepository extends MongoRepository { 10 | 11 | User findByUsername(String username); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-rest-validation/src/main/java/zin/rashidi/boot/data/rest/book/BookRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.rest.book; 2 | 3 | import java.util.UUID; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | @RepositoryRestResource 12 | interface BookRepository extends JpaRepository { 13 | } 14 | -------------------------------------------------------------------------------- /data-rest-validation/src/main/java/zin/rashidi/boot/data/rest/book/AuthorRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.rest.book; 2 | 3 | import java.util.UUID; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | @RepositoryRestResource 12 | interface AuthorRepository extends JpaRepository { 13 | } 14 | -------------------------------------------------------------------------------- /data-jdbc-audit/src/main/java/zin/rashidi/boot/data/jdbc/DataJdbcAuditApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jdbc; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataJdbcAuditApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataJdbcAuditApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-jpa-hibernate-cache/src/test/java/zin/rashidi/datajpa/hibernatecache/TestDataJpaHibernateCacheApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datajpa.hibernatecache; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | 5 | public class TestDataJpaHibernateCacheApplication { 6 | 7 | public static void main(String[] args) { 8 | SpringApplication.from(DataJpaHibernateCacheApplication::main).with(TestcontainersConfiguration.class).run(args); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /data-rest-composite-id/src/test/java/zin/rashidi/datarest/compositeid/TestDataRestCompositeIdApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datarest.compositeid; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | 5 | public class TestDataRestCompositeIdApplication { 6 | 7 | public static void main(String[] args) { 8 | SpringApplication.from(DataRestCompositeIdApplication::main).with(TestcontainersConfiguration.class).run(args); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /data-domain-events/src/main/java/zin/rashidi/boot/data/de/DataDomainEventsApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.de; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataDomainEventsApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataDomainEventsApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-jdbc-schema-generation/src/test/java/zin/rashidi/boot/jdbcscgm/TestDataJdbcSchemaGenerationApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.jdbcscgm; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | 5 | public class TestDataJdbcSchemaGenerationApplication { 6 | 7 | public static void main(String[] args) { 8 | SpringApplication.from(DataJdbcSchemaGenerationApplication::main).with(TestcontainersConfiguration.class).run(args); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /data-redis-cache/src/main/java/zin/rashidi/dataredis/cache/DataRedisCacheApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.dataredis.cache; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataRedisCacheApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataRedisCacheApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /web-thymeleaf-xss/src/main/java/zin/rashidi/web/xss/WebThymeleafXssApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.web.xss; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class WebThymeleafXssApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(WebThymeleafXssApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /cloud-jdbc-env-repo/src/main/java/zin/rashidi/boot/cloud/jdbcenvrepo/greet/GreetConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.cloud.jdbcenvrepo.greet; 2 | 3 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | /** 7 | * @author Rashidi Zin 8 | */ 9 | @Configuration 10 | @EnableConfigurationProperties(GreetProperties.class) 11 | class GreetConfiguration { 12 | } 13 | -------------------------------------------------------------------------------- /cloud-jdbc-env-repo/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: demo 4 | cloud: 5 | config: 6 | server: 7 | bootstrap: true 8 | jdbc: 9 | sql: SELECT `KEY`, `VALUE` from PROPERTIES where APPLICATION=? and PROFILE=? and LABEL=? 10 | sql-without-profile: SELECT `KEY`, `VALUE` from PROPERTIES where APPLICATION=? and PROFILE='default' and LABEL=? 11 | profiles: 12 | active: jdbc 13 | 14 | -------------------------------------------------------------------------------- /data-envers-audit/src/main/java/zin/rashidi/boot/data/envers/DataEnversAuditApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.envers; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataEnversAuditApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataEnversAuditApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-domain-events/src/main/java/zin/rashidi/boot/data/de/availability/BookAvailabilityRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.de.availability; 2 | 3 | import java.util.Optional; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | interface BookAvailabilityRepository extends JpaRepository { 11 | 12 | Optional findByIsbn(Long isbn); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /data-mongodb-audit/src/main/java/zin/rashidi/boot/data/mongodb/DataMongodbAuditApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataMongodbAuditApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataMongodbAuditApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /cloud-jdbc-env-repo/src/test/resources/init-script.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `PROPERTIES` 2 | ( 3 | `KEY` VARCHAR(128), 4 | `VALUE` VARCHAR(128), 5 | `APPLICATION` VARCHAR(128), 6 | `PROFILE` VARCHAR(128), 7 | `LABEL` VARCHAR(128), 8 | PRIMARY KEY (`KEY`, `APPLICATION`, `LABEL`) 9 | ); 10 | 11 | INSERT INTO PROPERTIES (`APPLICATION`, `PROFILE`, `LABEL`, `KEY`, `VALUE`) 12 | VALUES ('demo', 'default', 'master', 'app.greet.name', 'Demo'); 13 | -------------------------------------------------------------------------------- /data-rest-validation/src/main/java/zin/rashidi/boot/data/rest/DataRestValidationApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.rest; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataRestValidationApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataRestValidationApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /modulith/docs/module-course.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | set separator none 3 | title Course 4 | 5 | top to bottom direction 6 | 7 | !include 8 | !include 9 | !include 10 | 11 | Container_Boundary("ModulithApplication.ModulithApplication_boundary", "ModulithApplication", $tags="") { 12 | Component(ModulithApplication.ModulithApplication.Course, "Course", $techn="Module", $descr="", $tags="", $link="") 13 | } 14 | 15 | 16 | SHOW_LEGEND(true) 17 | @enduml -------------------------------------------------------------------------------- /modulith/docs/module-student.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | set separator none 3 | title Student 4 | 5 | top to bottom direction 6 | 7 | !include 8 | !include 9 | !include 10 | 11 | Container_Boundary("ModulithApplication.ModulithApplication_boundary", "ModulithApplication", $tags="") { 12 | Component(ModulithApplication.ModulithApplication.Student, "Student", $techn="Module", $descr="", $tags="", $link="") 13 | } 14 | 15 | 16 | SHOW_LEGEND(true) 17 | @enduml -------------------------------------------------------------------------------- /web-rest-client/src/main/java/zin/rashidi/boot/web/restclient/WebRestClientApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.web.restclient; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class WebRestClientApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(WebRestClientApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /batch-rest-repository/src/main/java/zin/rashidi/boot/batch/rest/BatchRestRepositoryApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.batch.rest; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class BatchRestRepositoryApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(BatchRestRepositoryApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /test-rest-assured/src/main/java/zin/rashidi/boot/test/restassured/user/UserReadOnly.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.restassured.user; 2 | 3 | import org.bson.types.ObjectId; 4 | 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 6 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | record UserReadOnly(@JsonSerialize(using = ToStringSerializer.class) ObjectId id, String name, String username) { 12 | } 13 | -------------------------------------------------------------------------------- /test-slice-tests-rest/src/main/java/zin/rashidi/boot/test/slices/TestSliceTestsApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.slices; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class TestSliceTestsApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(TestSliceTestsApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /batch-rest-repository/src/main/java/zin/rashidi/boot/batch/rest/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.batch.rest.user; 2 | 3 | import org.springframework.data.mongodb.core.mapping.Document; 4 | import org.springframework.data.mongodb.core.mapping.MongoId; 5 | 6 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | @Document 12 | @JsonIgnoreProperties(ignoreUnknown = true) 13 | record User(@MongoId Long id, String username) { 14 | } 15 | -------------------------------------------------------------------------------- /cloud-jdbc-env-repo/src/main/java/zin/rashidi/boot/cloud/jdbcenvrepo/CloudJdbcEnvRepoApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.cloud.jdbcenvrepo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class CloudJdbcEnvRepoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(CloudJdbcEnvRepoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-repository-definition/src/main/java/zin/rashidi/data/repositorydefinition/note/NoteRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.repositorydefinition.note; 2 | 3 | import org.springframework.data.repository.RepositoryDefinition; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | @RepositoryDefinition(domainClass = Note.class, idClass = Long.class) 11 | interface NoteRepository { 12 | 13 | List findByTitleContainingIgnoreCase(String title); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /data-repository-definition/src/test/java/zin/rashidi/data/repositorydefinition/TestDataRepositoryDefinitionApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.repositorydefinition; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | 5 | public class TestDataRepositoryDefinitionApplication { 6 | 7 | public static void main(String[] args) { 8 | SpringApplication.from(DataRepositoryDefinitionApplication::main).with(TestcontainersConfiguration.class).run(args); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /data-rest-composite-id/src/main/java/zin/rashidi/datarest/compositeid/book/BookRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datarest.compositeid.book; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 5 | import zin.rashidi.datarest.compositeid.book.Book.Isbn; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | @RepositoryRestResource 11 | interface BookRepository extends JpaRepository { 12 | } 13 | -------------------------------------------------------------------------------- /graphql/src/test/java/zin/rashidi/boot/graphql/TestGraphqlApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.graphql; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.test.context.TestConfiguration; 5 | 6 | @TestConfiguration(proxyBeanMethods = false) 7 | public class TestGraphqlApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.from(GraphqlApplication::main).with(TestGraphqlApplication.class).run(args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /test-execution-listeners/src/main/java/zin/rashidi/boot/test/TestExecutionListenersApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class TestExecutionListenersApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(TestExecutionListenersApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /test-rest-assured/src/main/java/zin/rashidi/boot/test/restassured/TestRestAssuredApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.restassured; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class TestRestAssuredApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(TestRestAssuredApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /antora-playbook.yml: -------------------------------------------------------------------------------- 1 | site: 2 | title: Spring Boot Tutorials 3 | url: https://rashidi.github.io/spring-boot-tutorials 4 | start_page: main::index.adoc 5 | robots: allow 6 | 7 | content: 8 | sources: 9 | - url: . 10 | start_path: docs 11 | 12 | ui: 13 | bundle: 14 | url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable 15 | snapshot: true 16 | supplemental_files: ./supplemental-ui 17 | 18 | runtime: 19 | fetch: true 20 | -------------------------------------------------------------------------------- /data-jpa-event/src/main/java/zin/rashidi/data/event/user/UserBeforeSaveEvent.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.event.user; 2 | 3 | import org.springframework.context.ApplicationEvent; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | class UserBeforeSaveEvent extends ApplicationEvent { 9 | 10 | public UserBeforeSaveEvent(User source) { 11 | super(source); 12 | } 13 | 14 | @Override 15 | public User getSource() { 16 | return (User) super.getSource(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /data-jpa-filtered-query/src/main/java/zin/rashidi/boot/data/jpa/DataJpaFilteredQueryApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jpa; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataJpaFilteredQueryApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataJpaFilteredQueryApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-jpa-hibernate-cache/src/main/java/zin/rashidi/datajpa/hibernatecache/DataJpaHibernateCacheApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datajpa.hibernatecache; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataJpaHibernateCacheApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataJpaHibernateCacheApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-rest-composite-id/src/main/java/zin/rashidi/datarest/compositeid/DataRestCompositeIdApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datarest.compositeid; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataRestCompositeIdApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataRestCompositeIdApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-jdbc-schema-generation/src/main/java/zin/rashidi/boot/jdbcscgm/DataJdbcSchemaGenerationApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.jdbcscgm; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataJdbcSchemaGenerationApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataJdbcSchemaGenerationApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /graphql/src/main/resources/graphql/schema.graphqls: -------------------------------------------------------------------------------- 1 | scalar Long 2 | 3 | type Query { 4 | findAll: [Book] 5 | findByTitle(title: String): Book 6 | } 7 | 8 | type Book { 9 | isbn: Isbn 10 | title: String 11 | author: Author 12 | } 13 | 14 | type Isbn { 15 | ean: Long 16 | registrationGroup: Int 17 | registrant: Int 18 | publication: Int 19 | digit: Int 20 | } 21 | 22 | type Author { 23 | name: Name 24 | } 25 | 26 | type Name { 27 | first: String 28 | last: String 29 | } 30 | -------------------------------------------------------------------------------- /data-domain-events/src/main/java/zin/rashidi/boot/data/de/book/BookPurchaseEvent.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.de.book; 2 | 3 | import org.springframework.context.ApplicationEvent; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | public class BookPurchaseEvent extends ApplicationEvent { 9 | 10 | public BookPurchaseEvent(Book source) { 11 | super(source); 12 | } 13 | 14 | @Override 15 | public Book getSource() { 16 | return (Book) super.getSource(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /data-mongodb-full-text-search/src/main/java/zin/rashidi/boot/data/mongodb/DataMongodbFullTextSearchApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataMongodbFullTextSearchApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataMongodbFullTextSearchApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-mongodb-tc-data-load/src/main/java/zin/rashidi/data/mongodb/tc/dataload/DataMongodbTcDataLoadApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.mongodb.tc.dataload; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataMongodbTcDataLoadApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataMongodbTcDataLoadApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-mongodb-transactional/src/main/java/zin/rashidi/boot/data/mongodb/tm/DataMongodbTransactionalApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb.tm; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataMongodbTransactionalApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataMongodbTransactionalApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /test-execution-listeners/src/main/java/zin/rashidi/boot/test/user/UserRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.user; 2 | 3 | import java.util.stream.Stream; 4 | 5 | import org.bson.types.ObjectId; 6 | import org.springframework.data.mongodb.repository.MongoRepository; 7 | 8 | import zin.rashidi.boot.test.user.User.Status; 9 | 10 | /** 11 | * @author Rashidi Zin 12 | */ 13 | interface UserRepository extends MongoRepository { 14 | 15 | Stream findByStatus(Status status); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /data-jpa-filtered-query/src/main/java/zin/rashidi/boot/data/jpa/jpa/JpaConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jpa.jpa; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 5 | 6 | /** 7 | * @author Rashidi Zin 8 | */ 9 | @Configuration 10 | @EnableJpaRepositories( 11 | basePackages = "zin.rashidi.boot.data.jpa", 12 | repositoryBaseClass = JpaCustomBaseRepository.class 13 | ) 14 | class JpaConfiguration { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /data-repository-definition/src/main/java/zin/rashidi/data/repositorydefinition/DataRepositoryDefinitionApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.repositorydefinition; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DataRepositoryDefinitionApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DataRepositoryDefinitionApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /test-rest-assured/src/main/java/zin/rashidi/boot/test/restassured/user/UserRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.restassured.user; 2 | 3 | import java.util.Optional; 4 | 5 | import org.bson.types.ObjectId; 6 | import org.springframework.data.mongodb.repository.MongoRepository; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | interface UserRepository extends MongoRepository { 12 | 13 | boolean existsByUsername(String username); 14 | 15 | Optional findByUsername(String username); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /data-jdbc-schema-generation/src/main/java/zin/rashidi/boot/jdbcscgm/book/Book.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.jdbcscgm.book; 2 | 3 | import org.springframework.data.annotation.Id; 4 | import org.springframework.data.relational.core.mapping.MappedCollection; 5 | import org.springframework.data.relational.core.mapping.Table; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | @Table 11 | class Book { 12 | 13 | @Id 14 | private Long isbn; 15 | private String title; 16 | 17 | @MappedCollection 18 | private Author author; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /data-rest-validation/src/main/java/zin/rashidi/boot/data/rest/book/Book.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.rest.book; 2 | 3 | import jakarta.persistence.*; 4 | 5 | import java.util.UUID; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | 11 | @Entity 12 | class Book { 13 | 14 | @Id 15 | @GeneratedValue 16 | private UUID id; 17 | 18 | private String title; 19 | 20 | @JoinColumn 21 | @ManyToOne(optional = false) 22 | private Author author; 23 | 24 | public Author getAuthor() { 25 | return author; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /supplemental-ui/partials/footer-content.hbs: -------------------------------------------------------------------------------- 1 |
2 |

Spring Boot Tutorials by Rashidi Zin

3 |

4 | Java version 5 | Spring Boot version 6 | License - Unlicense 7 |

8 | -------------------------------------------------------------------------------- /test-rest-assured/src/main/java/zin/rashidi/boot/test/restassured/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.restassured.user; 2 | 3 | import org.bson.types.ObjectId; 4 | import org.springframework.data.mongodb.core.mapping.Document; 5 | 6 | /** 7 | * @author Rashidi Zin 8 | */ 9 | @Document 10 | class User { 11 | 12 | private ObjectId id; 13 | private final String name; 14 | private final String username; 15 | 16 | public User(String name, String username) { 17 | this.name = name; 18 | this.username = username; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /data-rest-composite-id/src/main/java/zin/rashidi/datarest/compositeid/book/AuthorIdReferencedConverter.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datarest.compositeid.book; 2 | 3 | import org.springframework.core.convert.converter.Converter; 4 | import org.springframework.data.convert.ReadingConverter; 5 | 6 | /** 7 | * @author Rashidi Zin 8 | */ 9 | @ReadingConverter 10 | class AuthorIdReferencedConverter implements Converter { 11 | 12 | @Override 13 | public Author.Id convert(String source) { 14 | return new Author.Id().id(Long.parseLong(source)); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /graphql/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /jooq/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /.github/workflows/gradle-wrapper-updater.yml: -------------------------------------------------------------------------------- 1 | name: Gradle Wrapper Update 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * 5" 6 | 7 | jobs: 8 | update-gradle-wrapper: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v6 13 | 14 | - name: Set up JDK 15 | uses: actions/setup-java@v5 16 | with: 17 | java-version: '25' 18 | distribution: 'temurin' 19 | 20 | - name: Update Gradle Wrapper 21 | uses: gradle-update/update-gradle-wrapper-action@v2 22 | with: 23 | labels: dependencies 24 | merge-method: SQUASH 25 | -------------------------------------------------------------------------------- /modulith/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /batch-skip-step/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-envers-audit/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-jdbc-audit/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-jpa-audit/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-jpa-event/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-redis-cache/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /modulith/docs/module-course.adoc: -------------------------------------------------------------------------------- 1 | [%autowidth.stretch, cols="h,a"] 2 | |=== 3 | |Base package 4 | |`zin.rashidi.boot.modulith.course` 5 | |Spring components 6 | |_Services_ 7 | 8 | * `z.r.b.m.c.CourseManagement` 9 | 10 | _Repositories_ 11 | 12 | * `z.r.b.m.c.CourseRepository` 13 | 14 | _Event listeners_ 15 | 16 | * `o.s.c.ApplicationListener` 17 | 18 | _Others_ 19 | 20 | * `z.r.b.m.c.CourseEventsConfiguration` 21 | |Published events 22 | |* `z.r.b.m.c.CourseEnded` created by: 23 | ** `z.r.b.m.c.CourseEventsConfiguration.courseEnded(…)` 24 | 25 | |Events listened to 26 | |* `org.springframework.context.ApplicationEvent` 27 | |=== 28 | -------------------------------------------------------------------------------- /test-rest-assured/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /web-rest-client/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /web-thymeleaf-xss/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /batch-rest-repository/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /cloud-jdbc-env-repo/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-domain-events/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-mongodb-audit/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-rest-composite-id/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-rest-validation/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /test-slice-tests-rest/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /web-thymeleaf-xss/src/main/java/zin/rashidi/web/xss/greet/GreetResource.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.web.xss.greet; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.ui.Model; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RequestParam; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | @Controller 12 | class GreetResource { 13 | 14 | @GetMapping("/greet") 15 | public String greet(@RequestParam String name, Model model) { 16 | model.addAttribute("name", name); 17 | 18 | return "greet"; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /data-jpa-filtered-query/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-jpa-hibernate-cache/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-mongodb-tc-data-load/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-mongodb-transactional/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-repository-definition/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /test-execution-listeners/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-mongodb-full-text-search/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /data-jpa-hibernate-cache/src/main/java/zin/rashidi/datajpa/hibernatecache/customer/Customer.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datajpa.hibernatecache.customer; 2 | 3 | import jakarta.persistence.Entity; 4 | import jakarta.persistence.GeneratedValue; 5 | import jakarta.persistence.Id; 6 | import org.hibernate.annotations.Cache; 7 | 8 | import static org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE; 9 | 10 | /** 11 | * @author Rashidi Zin 12 | */ 13 | @Entity 14 | @Cache(usage = READ_WRITE, region = "customer") 15 | class Customer { 16 | 17 | @Id 18 | @GeneratedValue 19 | private Long id; 20 | 21 | private String name; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /modulith/docs/module-student.adoc: -------------------------------------------------------------------------------- 1 | [%autowidth.stretch, cols="h,a"] 2 | |=== 3 | |Base package 4 | |`zin.rashidi.boot.modulith.student` 5 | |Spring components 6 | |_Services_ 7 | 8 | * `z.r.b.m.s.StudentManagement` 9 | 10 | _Repositories_ 11 | 12 | * `z.r.b.m.s.StudentRepository` 13 | 14 | _Event listeners_ 15 | 16 | * `o.s.c.ApplicationListener` 17 | 18 | _Others_ 19 | 20 | * `z.r.b.m.s.StudentEventsConfiguration` 21 | |Published events 22 | |* `z.r.b.m.s.StudentInactivated` created by: 23 | ** `z.r.b.m.s.StudentEventsConfiguration.studentInactivated(…)` 24 | 25 | |Events listened to 26 | |* `org.springframework.context.ApplicationEvent` 27 | |=== 28 | -------------------------------------------------------------------------------- /data-mongodb-full-text-search/src/main/java/zin/rashidi/boot/data/mongodb/character/CharacterRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb.character; 2 | 3 | import java.util.List; 4 | 5 | import org.bson.types.ObjectId; 6 | import org.springframework.data.domain.Sort; 7 | import org.springframework.data.mongodb.core.query.TextCriteria; 8 | import org.springframework.data.mongodb.repository.MongoRepository; 9 | 10 | /** 11 | * @author Rashidi Zin 12 | */ 13 | interface CharacterRepository extends MongoRepository, CharacterSearchRepository { 14 | 15 | List findAllBy(TextCriteria criteria, Sort sort); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /graphql/src/main/java/zin/rashidi/boot/graphql/configuration/ScalarConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.graphql.configuration; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.graphql.execution.RuntimeWiringConfigurer; 6 | 7 | import static graphql.scalars.ExtendedScalars.GraphQLLong; 8 | 9 | /** 10 | * @author Rashidi Zin 11 | */ 12 | @Configuration 13 | class ScalarConfiguration { 14 | 15 | @Bean 16 | public RuntimeWiringConfigurer runtimeWiringConfigurer() { 17 | return builder -> builder.scalar(GraphQLLong); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/course/CourseManagement.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.course; 2 | 3 | import org.springframework.stereotype.Service; 4 | import org.springframework.transaction.annotation.Transactional; 5 | 6 | /** 7 | * @author Rashidi Zin 8 | */ 9 | @Service 10 | @Transactional(readOnly = true) 11 | class CourseManagement { 12 | 13 | private final CourseRepository courses; 14 | 15 | CourseManagement(CourseRepository courses) { 16 | this.courses = courses; 17 | } 18 | 19 | @Transactional 20 | public void updateCourse(Course course) { 21 | courses.save(course); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /data-jdbc-audit/src/main/java/zin/rashidi/boot/data/jdbc/audit/AuditConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jdbc.audit; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.data.domain.AuditorAware; 6 | import org.springframework.data.jdbc.repository.config.EnableJdbcAuditing; 7 | 8 | import java.util.Optional; 9 | 10 | /** 11 | * @author Rashidi Zin 12 | */ 13 | @Configuration 14 | @EnableJdbcAuditing 15 | class AuditConfiguration { 16 | 17 | @Bean 18 | public AuditorAware auditorAware() { 19 | return () -> Optional.of("Mr. Auditor"); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /modulith/src/test/resources/schema.sql: -------------------------------------------------------------------------------- 1 | -- Course table 2 | CREATE TABLE course ( 3 | id SERIAL PRIMARY KEY, 4 | name TEXT NOT NULL, 5 | status VARCHAR(20) NOT NULL 6 | ); 7 | 8 | -- Student table 9 | CREATE TABLE student ( 10 | id SERIAL PRIMARY KEY, 11 | name TEXT NOT NULL, 12 | status VARCHAR(20) NOT NULL 13 | ); 14 | 15 | -- Subscription table 16 | CREATE TABLE subscription ( 17 | id SERIAL PRIMARY KEY, 18 | student_id BIGINT NOT NULL, 19 | course_id BIGINT NOT NULL, 20 | status VARCHAR(20) NOT NULL, 21 | UNIQUE (student_id, course_id), 22 | FOREIGN KEY (student_id) REFERENCES student(id), 23 | FOREIGN KEY (course_id) REFERENCES course(id) 24 | ); 25 | -------------------------------------------------------------------------------- /data-jdbc-schema-generation/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | 39 | ### Liquibase generated files ### 40 | **/user.yaml 41 | -------------------------------------------------------------------------------- /data-jpa-audit/src/main/java/zin/rashidi/boot/data/audit/AuditConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.audit; 2 | 3 | import java.util.Optional; 4 | 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.data.domain.AuditorAware; 8 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 9 | 10 | /** 11 | * @author Rashidi Zin 12 | */ 13 | @Configuration 14 | @EnableJpaAuditing 15 | class AuditConfiguration { 16 | 17 | @Bean 18 | public AuditorAware auditorAwareRef() { 19 | return () -> Optional.of("Mr. Auditor"); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /data-jpa-filtered-query/src/main/java/zin/rashidi/boot/data/jpa/country/Country.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jpa.country; 2 | 3 | import jakarta.persistence.Entity; 4 | import jakarta.persistence.Id; 5 | 6 | /** 7 | * @author Rashidi Zin 8 | */ 9 | @Entity 10 | class Country { 11 | 12 | @Id 13 | String isoCode; 14 | 15 | String name; 16 | 17 | protected Country() { 18 | } 19 | 20 | public Country(String isoCode, String name) { 21 | this.isoCode = isoCode; 22 | this.name = name; 23 | } 24 | 25 | public String isoCode() { 26 | return isoCode; 27 | } 28 | 29 | public String name() { 30 | return name; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /data-redis-cache/src/main/java/zin/rashidi/dataredis/cache/customer/CustomerRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.dataredis.cache.customer; 2 | 3 | import org.springframework.cache.annotation.Cacheable; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | /** 10 | * @author Rashidi Zin 11 | */ 12 | interface CustomerRepository extends JpaRepository { 13 | 14 | @Override 15 | @Cacheable(cacheNames = "customers", key = "#root.methodName") 16 | List findAll(); 17 | 18 | @Override 19 | @Cacheable(cacheNames = "customerById") 20 | Optional findById(Long id); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /data-jpa-event/src/main/java/zin/rashidi/data/event/user/UserEventPublisher.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.event.user; 2 | 3 | import jakarta.persistence.PrePersist; 4 | import org.springframework.context.ApplicationEventPublisher; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | @Component 11 | class UserEventPublisher { 12 | 13 | private final ApplicationEventPublisher publisher; 14 | 15 | UserEventPublisher(ApplicationEventPublisher publisher) { 16 | this.publisher = publisher; 17 | } 18 | 19 | @PrePersist 20 | public void beforeSave(User user) { 21 | publisher.publishEvent(new UserBeforeSaveEvent(user)); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /data-jpa-event/src/test/java/zin/rashidi/data/event/TestcontainersConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.event; 2 | 3 | import org.springframework.boot.test.context.TestConfiguration; 4 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 5 | import org.springframework.context.annotation.Bean; 6 | import org.testcontainers.containers.PostgreSQLContainer; 7 | import org.testcontainers.utility.DockerImageName; 8 | 9 | @TestConfiguration(proxyBeanMethods = false) 10 | class TestcontainersConfiguration { 11 | 12 | @Bean 13 | @ServiceConnection 14 | PostgreSQLContainer postgresContainer() { 15 | return new PostgreSQLContainer<>(DockerImageName.parse("postgres:latest")); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /data-mongodb-audit/src/main/java/zin/rashidi/boot/data/mongodb/audit/MongoAuditConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb.audit; 2 | 3 | import java.util.Optional; 4 | 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.data.domain.AuditorAware; 8 | import org.springframework.data.mongodb.config.EnableMongoAuditing; 9 | 10 | /** 11 | * @author Rashidi Zin 12 | */ 13 | @Configuration 14 | @EnableMongoAuditing 15 | class MongoAuditConfiguration { 16 | 17 | @Bean 18 | public AuditorAware auditorAwareRef() { 19 | return () -> Optional.of("Mr. Auditor"); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /web-rest-client/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-web") 22 | testImplementation("org.springframework.boot:spring-boot-starter-test") 23 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 24 | } 25 | 26 | tasks.named("test") { 27 | useJUnitPlatform() 28 | } -------------------------------------------------------------------------------- /data-jdbc-audit/src/test/java/zin/rashidi/boot/data/jdbc/TestcontainersConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jdbc; 2 | 3 | import org.springframework.boot.test.context.TestConfiguration; 4 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 5 | import org.springframework.context.annotation.Bean; 6 | import org.testcontainers.containers.PostgreSQLContainer; 7 | import org.testcontainers.utility.DockerImageName; 8 | 9 | @TestConfiguration(proxyBeanMethods = false) 10 | class TestcontainersConfiguration { 11 | 12 | @Bean 13 | @ServiceConnection 14 | PostgreSQLContainer postgresContainer() { 15 | return new PostgreSQLContainer<>(DockerImageName.parse("postgres:latest")); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /web-rest-client/src/main/java/zin/rashidi/boot/web/restclient/post/PostRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.web.restclient.post; 2 | 3 | import org.springframework.web.bind.annotation.PathVariable; 4 | import org.springframework.web.service.annotation.GetExchange; 5 | import org.springframework.web.service.annotation.HttpExchange; 6 | 7 | import java.util.List; 8 | 9 | import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; 10 | 11 | /** 12 | * @author Rashidi Zin 13 | */ 14 | @HttpExchange(url = "/posts", accept = APPLICATION_JSON_VALUE) 15 | interface PostRepository { 16 | 17 | @GetExchange 18 | List findAll(); 19 | 20 | @GetExchange("/{id}") 21 | Post findById(@PathVariable Long id); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /data-rest-composite-id/src/main/java/zin/rashidi/datarest/compositeid/book/BookRepositoryRestConfigurer.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datarest.compositeid.book; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.core.convert.support.ConfigurableConversionService; 5 | import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | @Configuration 11 | class BookRepositoryRestConfigurer implements RepositoryRestConfigurer { 12 | 13 | @Override 14 | public void configureConversionService(ConfigurableConversionService conversionService) { 15 | conversionService.addConverter(new AuthorIdReferencedConverter()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/student/StudentManagement.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.student; 2 | 3 | import org.springframework.stereotype.Service; 4 | import org.springframework.transaction.annotation.Transactional; 5 | 6 | import static zin.rashidi.boot.modulith.student.Student.Status.INACTIVE; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | @Service 12 | class StudentManagement { 13 | 14 | private final StudentRepository students; 15 | 16 | StudentManagement(StudentRepository students) { 17 | this.students = students; 18 | } 19 | 20 | @Transactional 21 | public Student inactive(Student student) { 22 | return students.save(student.status(INACTIVE)); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /test-slice-tests-rest/src/main/java/zin/rashidi/boot/test/slices/user/UserRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.slices.user; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.jpa.repository.NativeQuery; 5 | 6 | import java.util.Optional; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | interface UserRepository extends JpaRepository { 12 | 13 | @NativeQuery( 14 | name = "User.findByUsername", 15 | value = "SELECT CONCAT_WS(' ', first, last) as name, username, status FROM users WHERE username = ?1", 16 | sqlResultSetMapping = "User.WithoutId" 17 | ) 18 | Optional findByUsername(String username); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | ### Ignore Gradle files in submodules ### 39 | **/gradlew* 40 | **/gradle/ 41 | ### Antora ### 42 | build/site/ 43 | 44 | ### Jules ### 45 | *.log -------------------------------------------------------------------------------- /data-mongodb-transactional/src/main/java/zin/rashidi/boot/data/mongodb/tm/user/UpdateUserStatus.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb.tm.user; 2 | 3 | import static zin.rashidi.boot.data.mongodb.tm.user.User.Status.ACTIVE; 4 | 5 | import org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.transaction.event.TransactionalEventListener; 8 | 9 | /** 10 | * @author Rashidi Zin 11 | */ 12 | @Component 13 | class UpdateUserStatus { 14 | 15 | @TransactionalEventListener 16 | public void onBeforeSave(BeforeSaveEvent event) { 17 | var user = event.getSource(); 18 | 19 | user.setStatus(ACTIVE); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /data-jdbc-schema-generation/src/test/java/zin/rashidi/boot/jdbcscgm/TestcontainersConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.jdbcscgm; 2 | 3 | import org.springframework.boot.test.context.TestConfiguration; 4 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 5 | import org.springframework.context.annotation.Bean; 6 | import org.testcontainers.containers.PostgreSQLContainer; 7 | import org.testcontainers.utility.DockerImageName; 8 | 9 | @TestConfiguration(proxyBeanMethods = false) 10 | public class TestcontainersConfiguration { 11 | 12 | @Bean 13 | @ServiceConnection 14 | PostgreSQLContainer postgresContainer() { 15 | return new PostgreSQLContainer<>(DockerImageName.parse("postgres:latest")); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /data-jpa-hibernate-cache/src/test/java/zin/rashidi/datajpa/hibernatecache/TestcontainersConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datajpa.hibernatecache; 2 | 3 | import org.springframework.boot.test.context.TestConfiguration; 4 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 5 | import org.springframework.context.annotation.Bean; 6 | import org.testcontainers.containers.PostgreSQLContainer; 7 | import org.testcontainers.utility.DockerImageName; 8 | 9 | @TestConfiguration(proxyBeanMethods = false) 10 | public class TestcontainersConfiguration { 11 | 12 | @Bean 13 | @ServiceConnection 14 | PostgreSQLContainer postgresContainer() { 15 | return new PostgreSQLContainer<>(DockerImageName.parse("postgres:latest")); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /data-redis-cache/src/main/java/zin/rashidi/dataredis/cache/cache/CacheConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.dataredis.cache.cache; 2 | 3 | import org.springframework.cache.annotation.EnableCaching; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.data.redis.cache.RedisCacheManager; 7 | import org.springframework.data.redis.connection.RedisConnectionFactory; 8 | 9 | /** 10 | * @author Rashidi Zin 11 | */ 12 | @Configuration 13 | @EnableCaching 14 | class CacheConfiguration { 15 | 16 | @Bean 17 | public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) { 18 | return RedisCacheManager.create(connectionFactory); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /data-redis-cache/src/main/java/zin/rashidi/dataredis/cache/customer/Customer.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.dataredis.cache.customer; 2 | 3 | import jakarta.persistence.Entity; 4 | import jakarta.persistence.GeneratedValue; 5 | import jakarta.persistence.Id; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @author Rashidi Zin 11 | */ 12 | @Entity 13 | class Customer implements Serializable { 14 | 15 | @Id 16 | @GeneratedValue 17 | private Long id; 18 | 19 | private String name; 20 | 21 | @Override 22 | public final boolean equals(Object o) { 23 | return o instanceof Customer another && this.id.equals(another.id); 24 | } 25 | 26 | @Override 27 | public int hashCode() { 28 | return id.hashCode(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /data-rest-validation/src/main/java/zin/rashidi/boot/data/rest/book/BookValidatorConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.rest.book; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener; 5 | import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | @Configuration 11 | class BookValidatorConfiguration implements RepositoryRestConfigurer { 12 | 13 | @Override 14 | public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) { 15 | validatingListener.addValidator("beforeCreate", new BeforeCreateBookValidator()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /test-slice-tests-rest/src/test/java/zin/rashidi/boot/test/slices/TestcontainersConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.slices; 2 | 3 | import org.springframework.boot.test.context.TestConfiguration; 4 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 5 | import org.springframework.context.annotation.Bean; 6 | import org.testcontainers.containers.PostgreSQLContainer; 7 | import org.testcontainers.utility.DockerImageName; 8 | 9 | @TestConfiguration(proxyBeanMethods = false) 10 | public class TestcontainersConfiguration { 11 | 12 | @Bean 13 | @ServiceConnection 14 | PostgreSQLContainer postgresContainer() { 15 | return new PostgreSQLContainer<>(DockerImageName.parse("postgres:latest")); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /data-rest-composite-id/src/test/java/zin/rashidi/datarest/compositeid/TestcontainersConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datarest.compositeid; 2 | 3 | import org.springframework.boot.test.context.TestConfiguration; 4 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 5 | import org.springframework.context.annotation.Bean; 6 | import org.testcontainers.containers.PostgreSQLContainer; 7 | import org.testcontainers.utility.DockerImageName; 8 | 9 | @TestConfiguration(proxyBeanMethods = false) 10 | public class TestcontainersConfiguration { 11 | 12 | @Bean 13 | @ServiceConnection 14 | PostgreSQLContainer postgresContainer() { 15 | return new PostgreSQLContainer<>(DockerImageName.parse("postgres:latest")); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /data-mongodb-full-text-search/src/main/java/zin/rashidi/boot/data/mongodb/character/Character.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb.character; 2 | 3 | import org.bson.types.ObjectId; 4 | import org.springframework.data.annotation.Id; 5 | import org.springframework.data.mongodb.core.index.TextIndexed; 6 | import org.springframework.data.mongodb.core.mapping.Document; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | @Document 12 | class Character { 13 | 14 | @Id 15 | private ObjectId id; 16 | 17 | @TextIndexed 18 | private final String name; 19 | 20 | @TextIndexed 21 | private final String publisher; 22 | 23 | public Character(String name, String publisher) { 24 | this.name = name; 25 | this.publisher = publisher; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/subscription/Subscription.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.subscription; 2 | 3 | import org.springframework.data.annotation.Id; 4 | 5 | import static zin.rashidi.boot.modulith.subscription.Subscription.Status.ACTIVE; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | class Subscription { 11 | 12 | @Id 13 | private Long id; 14 | private final Long studentId; 15 | private final Long courseId; 16 | private final Status status; 17 | 18 | public Subscription(Long studentId, Long courseId) { 19 | this.studentId = studentId; 20 | this.courseId = courseId; 21 | this.status = ACTIVE; 22 | } 23 | 24 | enum Status { 25 | ACTIVE, COMPLETED, DORMANT, CANCELLED 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /data-repository-definition/src/test/java/zin/rashidi/data/repositorydefinition/TestcontainersConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.repositorydefinition; 2 | 3 | import org.springframework.boot.test.context.TestConfiguration; 4 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 5 | import org.springframework.context.annotation.Bean; 6 | import org.testcontainers.containers.PostgreSQLContainer; 7 | import org.testcontainers.utility.DockerImageName; 8 | 9 | @TestConfiguration(proxyBeanMethods = false) 10 | public class TestcontainersConfiguration { 11 | 12 | @Bean 13 | @ServiceConnection 14 | PostgreSQLContainer postgresContainer() { 15 | return new PostgreSQLContainer<>(DockerImageName.parse("postgres:latest")); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /data-jpa-event/src/main/java/zin/rashidi/data/event/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.event.user; 2 | 3 | import jakarta.persistence.Entity; 4 | import jakarta.persistence.EntityListeners; 5 | import jakarta.persistence.GeneratedValue; 6 | import jakarta.persistence.Id; 7 | import jakarta.persistence.Table; 8 | 9 | /** 10 | * @author Rashidi Zin 11 | */ 12 | @Entity 13 | @Table(name = "users") 14 | @EntityListeners(UserEventPublisher.class) 15 | class User { 16 | 17 | @Id 18 | @GeneratedValue 19 | private Long id; 20 | private String username; 21 | 22 | protected User() { 23 | } 24 | 25 | public User(String username) { 26 | this.username = username; 27 | } 28 | 29 | public String getUsername() { 30 | return username; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/subscription/SubscriptionRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.subscription; 2 | 3 | import org.springframework.data.jdbc.repository.query.Modifying; 4 | import org.springframework.data.jdbc.repository.query.Query; 5 | import org.springframework.data.repository.CrudRepository; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | interface SubscriptionRepository extends CrudRepository { 11 | 12 | @Modifying 13 | @Query("UPDATE subscription SET status = 'CANCELLED' WHERE course_id = :courseId") 14 | int cancelByCourseId(Long courseId); 15 | 16 | @Modifying 17 | @Query("UPDATE subscription SET status = 'CANCELLED' WHERE student_id = :studentId") 18 | int cancelByStudentId(Long studentId); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /cloud-jdbc-env-repo/src/main/java/zin/rashidi/boot/cloud/jdbcenvrepo/greet/GreetResource.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.cloud.jdbcenvrepo.greet; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RequestParam; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | @RestController 11 | class GreetResource { 12 | 13 | private final GreetProperties properties; 14 | 15 | GreetResource(GreetProperties properties) { 16 | this.properties = properties; 17 | } 18 | 19 | @GetMapping("/greet") 20 | public String greet(@RequestParam String greeting) { 21 | return "%s, my name is %s".formatted(greeting, properties.name()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /modulith/src/test/java/zin/rashidi/boot/modulith/TestcontainersConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith; 2 | 3 | import org.springframework.boot.test.context.TestConfiguration; 4 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 5 | import org.springframework.context.annotation.Bean; 6 | import org.testcontainers.containers.PostgreSQLContainer; 7 | import org.testcontainers.utility.DockerImageName; 8 | 9 | @TestConfiguration(proxyBeanMethods = false) 10 | public class TestcontainersConfiguration { 11 | 12 | @Bean 13 | @ServiceConnection 14 | PostgreSQLContainer postgresContainer() { 15 | return new PostgreSQLContainer<>(DockerImageName.parse("postgres:latest")) 16 | .withInitScripts("schema.sql", "schema-data.sql"); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /data-jpa-event/src/main/java/zin/rashidi/data/event/user/UserValidation.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.data.event.user; 2 | 3 | import org.springframework.context.event.EventListener; 4 | import org.springframework.stereotype.Component; 5 | 6 | /** 7 | * @author Rashidi Zin 8 | */ 9 | @Component 10 | class UserValidation { 11 | 12 | private final UserRepository repository; 13 | 14 | UserValidation(UserRepository repository) { 15 | this.repository = repository; 16 | } 17 | 18 | @EventListener 19 | void usernameIsUnique(UserBeforeSaveEvent event) { 20 | var usernameExisted = repository.existsByUsername(event.getSource().getUsername()); 21 | 22 | if (usernameExisted) { 23 | throw new IllegalArgumentException("Username is already taken"); 24 | } 25 | 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /data-rest-validation/src/main/java/zin/rashidi/boot/data/rest/book/Author.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.rest.book; 2 | 3 | import java.util.Set; 4 | import java.util.UUID; 5 | 6 | import jakarta.persistence.Entity; 7 | import jakarta.persistence.GeneratedValue; 8 | import jakarta.persistence.Id; 9 | import jakarta.persistence.OneToMany; 10 | 11 | /** 12 | * @author Rashidi Zin 13 | */ 14 | @Entity 15 | class Author { 16 | 17 | @Id 18 | @GeneratedValue 19 | private UUID id; 20 | 21 | private String name; 22 | 23 | private Status status; 24 | 25 | @OneToMany(mappedBy = "author") 26 | private Set books; 27 | 28 | enum Status { 29 | 30 | ACTIVE, 31 | 32 | INACTIVE 33 | 34 | } 35 | 36 | public Status getStatus() { 37 | return status; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /test-rest-assured/src/test/java/zin/rashidi/boot/test/restassured/user/UserCreationTestExecutionListener.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.restassured.user; 2 | 3 | import org.springframework.data.mongodb.core.MongoOperations; 4 | import org.springframework.test.context.TestContext; 5 | import org.springframework.test.context.support.AbstractTestExecutionListener; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | class UserCreationTestExecutionListener extends AbstractTestExecutionListener { 11 | 12 | @Override 13 | public void beforeTestClass(TestContext testContext) { 14 | var mongo = testContext.getApplicationContext().getBean(MongoOperations.class); 15 | 16 | mongo.save(new User("Zaid Zin", "zaid.zin")); 17 | } 18 | 19 | @Override 20 | public int getOrder() { 21 | return HIGHEST_PRECEDENCE; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /data-mongodb-audit/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-mongodb") 22 | testImplementation("org.springframework.boot:spring-boot-starter-test") 23 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 24 | testImplementation("org.testcontainers:junit-jupiter") 25 | testImplementation("org.testcontainers:mongodb") 26 | } 27 | 28 | tasks.named("test") { 29 | useJUnitPlatform() 30 | } -------------------------------------------------------------------------------- /data-rest-composite-id/src/main/java/zin/rashidi/datarest/compositeid/book/BookIdConverter.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datarest.compositeid.book; 2 | 3 | import org.springframework.data.rest.webmvc.spi.BackendIdConverter; 4 | import org.springframework.stereotype.Component; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | @Component 12 | class BookIdConverter implements BackendIdConverter { 13 | 14 | @Override 15 | public Serializable fromRequestId(String id, Class entityType) { 16 | return new Book.Isbn(id); 17 | } 18 | 19 | @Override 20 | public String toRequestId(Serializable id, Class entityType) { 21 | return id.toString(); 22 | } 23 | 24 | @Override 25 | public boolean supports(Class aClass) { 26 | return Book.class.isAssignableFrom(aClass); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /graphql/src/main/java/zin/rashidi/boot/graphql/book/BookResource.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.graphql.book; 2 | 3 | import org.springframework.graphql.data.method.annotation.Argument; 4 | import org.springframework.graphql.data.method.annotation.QueryMapping; 5 | import org.springframework.stereotype.Controller; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author Rashidi Zin 11 | */ 12 | @Controller 13 | class BookResource { 14 | 15 | private final BookRepository repository; 16 | 17 | BookResource(BookRepository repository) { 18 | this.repository = repository; 19 | } 20 | 21 | @QueryMapping 22 | public List findAll() { 23 | return repository.findAll(); 24 | } 25 | 26 | @QueryMapping 27 | public Book findByTitle(@Argument String title) { 28 | return repository.findByTitle(title); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /test-execution-listeners/src/test/java/zin/rashidi/boot/test/user/UserCreationTestExecutionListener.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.user; 2 | 3 | import org.springframework.data.mongodb.core.MongoOperations; 4 | import org.springframework.test.context.TestContext; 5 | import org.springframework.test.context.support.AbstractTestExecutionListener; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | class UserCreationTestExecutionListener extends AbstractTestExecutionListener { 11 | 12 | @Override 13 | public void beforeTestClass(TestContext testContext) { 14 | var mongo = testContext.getApplicationContext().getBean(MongoOperations.class); 15 | 16 | mongo.save(new User("Rashidi Zin", "rashidi.zin")); 17 | } 18 | 19 | @Override 20 | public int getOrder() { 21 | return HIGHEST_PRECEDENCE; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /data-domain-events/src/test/java/zin/rashidi/boot/data/de/TestDataDomainEventsApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.de; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.test.context.TestConfiguration; 5 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 6 | import org.springframework.context.annotation.Bean; 7 | import org.testcontainers.containers.MySQLContainer; 8 | 9 | @TestConfiguration(proxyBeanMethods = false) 10 | public class TestDataDomainEventsApplication { 11 | 12 | @Bean 13 | @ServiceConnection 14 | MySQLContainer mysqlContainer() { 15 | return new MySQLContainer<>("mysql:lts"); 16 | } 17 | 18 | public static void main(String[] args) { 19 | SpringApplication.from(DataDomainEventsApplication::main).with(TestDataDomainEventsApplication.class).run(args); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /data-rest-validation/src/main/java/zin/rashidi/boot/data/rest/book/BeforeCreateBookValidator.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.rest.book; 2 | 3 | import static zin.rashidi.boot.data.rest.book.Author.Status.INACTIVE; 4 | 5 | import org.springframework.validation.Errors; 6 | import org.springframework.validation.Validator; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | class BeforeCreateBookValidator implements Validator { 12 | 13 | @Override 14 | public boolean supports(Class clazz) { 15 | return Book.class.isAssignableFrom(clazz); 16 | } 17 | 18 | @Override 19 | public void validate(Object target, Errors errors) { 20 | Book book = (Book) target; 21 | 22 | if (book.getAuthor().getStatus() == INACTIVE) { 23 | errors.rejectValue("author", "author.inactive", "Author is inactive"); 24 | } 25 | 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/course/Course.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.course; 2 | 3 | import org.springframework.data.annotation.Id; 4 | 5 | import static zin.rashidi.boot.modulith.course.Course.Status.ACTIVE; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | class Course { 11 | 12 | @Id 13 | private Long id; 14 | private final String name; 15 | private Status status; 16 | 17 | Course(String name) { 18 | this.name = name; 19 | this.status = ACTIVE; 20 | } 21 | 22 | public Long id() { 23 | return id; 24 | } 25 | 26 | public Course status(Status status) { 27 | this.status = status; 28 | return this; 29 | } 30 | 31 | public Status status() { 32 | return status; 33 | } 34 | 35 | enum Status { 36 | ACTIVE, DORMANT, ENDED 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /test-execution-listeners/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-mongodb") 22 | testImplementation("org.springframework.boot:spring-boot-starter-test") 23 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 24 | testImplementation("org.testcontainers:junit-jupiter") 25 | testImplementation("org.testcontainers:mongodb") 26 | } 27 | 28 | tasks.named("test") { 29 | useJUnitPlatform() 30 | } -------------------------------------------------------------------------------- /data-mongodb-full-text-search/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-mongodb") 22 | testImplementation("org.springframework.boot:spring-boot-starter-test") 23 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 24 | testImplementation("org.testcontainers:junit-jupiter") 25 | testImplementation("org.testcontainers:mongodb") 26 | } 27 | 28 | tasks.named("test") { 29 | useJUnitPlatform() 30 | } -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/student/Student.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.student; 2 | 3 | import org.springframework.data.annotation.Id; 4 | 5 | import static zin.rashidi.boot.modulith.student.Student.Status.ACTIVE; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | class Student { 11 | 12 | @Id 13 | private Long id; 14 | private final String name; 15 | private Status status; 16 | 17 | public Student(String name) { 18 | this.name = name; 19 | this.status = ACTIVE; 20 | } 21 | 22 | public Long id() { 23 | return id; 24 | } 25 | 26 | public Status status() { 27 | return status; 28 | } 29 | 30 | public Student status(Status status) { 31 | this.status = status; 32 | return this; 33 | } 34 | 35 | enum Status { 36 | ACTIVE, INACTIVE 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /jooq/src/test/java/zin/rashidi/boot/jooq/TestJooqApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.jooq; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.test.context.TestConfiguration; 5 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 6 | import org.springframework.context.annotation.Bean; 7 | import org.testcontainers.containers.MySQLContainer; 8 | import org.testcontainers.utility.DockerImageName; 9 | 10 | @TestConfiguration(proxyBeanMethods = false) 11 | public class TestJooqApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.from(JooqApplication::main).with(TestJooqApplication.class).run(args); 15 | } 16 | 17 | @Bean 18 | @ServiceConnection 19 | MySQLContainer mysqlContainer() { 20 | return new MySQLContainer<>(DockerImageName.parse("mysql:lts")); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /data-rest-composite-id/src/main/java/zin/rashidi/datarest/compositeid/book/Author.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datarest.compositeid.book; 2 | 3 | import jakarta.persistence.*; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | @Entity 11 | class Author { 12 | 13 | @EmbeddedId 14 | private Id id = new Id(); 15 | 16 | @Embedded 17 | private Name name; 18 | 19 | @Embeddable 20 | static class Id implements Serializable { 21 | 22 | @GeneratedValue 23 | private Long id; 24 | 25 | public Long id() { 26 | return id; 27 | } 28 | 29 | public Id id(Long id) { 30 | this.id = id; 31 | return this; 32 | } 33 | 34 | } 35 | 36 | @Embeddable 37 | record Name(@Column(name = "first_name") String first, @Column(name = "last_name") String last) { } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /data-domain-events/src/main/java/zin/rashidi/boot/data/de/book/BookResource.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.de.book; 2 | 3 | import org.springframework.transaction.annotation.Transactional; 4 | import org.springframework.web.bind.annotation.DeleteMapping; 5 | import org.springframework.web.bind.annotation.PathVariable; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | @RestController 12 | class BookResource { 13 | 14 | private final BookRepository repository; 15 | 16 | BookResource(BookRepository repository) { 17 | this.repository = repository; 18 | } 19 | 20 | @Transactional 21 | @DeleteMapping("/books/{id}/purchase") 22 | public void purchase(@PathVariable Long id) { 23 | repository.findById(id).map(Book::purchase).ifPresent(repository::delete); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /data-jpa-audit/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 22 | runtimeOnly("com.mysql:mysql-connector-j") 23 | testImplementation("org.springframework.boot:spring-boot-starter-test") 24 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 25 | testImplementation("org.testcontainers:junit-jupiter") 26 | testImplementation("org.testcontainers:mysql") 27 | } 28 | 29 | tasks.named("test") { 30 | useJUnitPlatform() 31 | } -------------------------------------------------------------------------------- /test-execution-listeners/src/main/java/zin/rashidi/boot/test/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.user; 2 | 3 | import static zin.rashidi.boot.test.user.User.Status.ACTIVE; 4 | 5 | import org.bson.types.ObjectId; 6 | import org.springframework.data.mongodb.core.mapping.Document; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | @Document 12 | class User { 13 | 14 | private ObjectId id; 15 | private final String name; 16 | private final String username; 17 | private Status status = ACTIVE; 18 | 19 | public User(String name, String username) { 20 | this.name = name; 21 | this.username = username; 22 | } 23 | 24 | public User status(Status status) { 25 | this.status = status; 26 | return this; 27 | } 28 | 29 | enum Status { 30 | 31 | ACTIVE, 32 | 33 | INACTIVE 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /data-jpa-filtered-query/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 22 | runtimeOnly("com.mysql:mysql-connector-j") 23 | testImplementation("org.springframework.boot:spring-boot-starter-test") 24 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 25 | testImplementation("org.testcontainers:junit-jupiter") 26 | testImplementation("org.testcontainers:mysql") 27 | } 28 | 29 | tasks.named("test") { 30 | useJUnitPlatform() 31 | } -------------------------------------------------------------------------------- /data-mongodb-transactional/src/main/java/zin/rashidi/boot/data/mongodb/tm/transaction/MongoTransactionManagerConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb.tm.transaction; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.data.mongodb.MongoDatabaseFactory; 6 | import org.springframework.data.mongodb.MongoTransactionManager; 7 | import org.springframework.transaction.PlatformTransactionManager; 8 | import org.springframework.transaction.annotation.EnableTransactionManagement; 9 | 10 | /** 11 | * @author Rashidi Zin 12 | */ 13 | @Configuration 14 | @EnableTransactionManagement 15 | class MongoTransactionManagerConfiguration { 16 | 17 | @Bean 18 | public PlatformTransactionManager transactionManager(MongoDatabaseFactory factory) { 19 | return new MongoTransactionManager(factory); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /graphql/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("com.graphql-java:graphql-java-extended-scalars:24.0") 22 | implementation("org.springframework.boot:spring-boot-starter-graphql") 23 | implementation("org.springframework.boot:spring-boot-starter-web") 24 | testImplementation("org.springframework.boot:spring-boot-starter-test") 25 | testImplementation("org.springframework:spring-webflux") 26 | testImplementation("org.springframework.graphql:spring-graphql-test") 27 | } 28 | 29 | tasks.named("test") { 30 | useJUnitPlatform() 31 | } -------------------------------------------------------------------------------- /data-mongodb-tc-data-load/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-mongodb") 22 | testImplementation("org.springframework.boot:spring-boot-starter-test") 23 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 24 | testImplementation("org.testcontainers:junit-jupiter") 25 | testImplementation("org.testcontainers:mongodb") 26 | testImplementation("com.fasterxml.jackson.core:jackson-databind") 27 | } 28 | 29 | tasks.named("test") { 30 | useJUnitPlatform() 31 | } -------------------------------------------------------------------------------- /data-mongodb-transactional/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-mongodb") 22 | implementation("org.springframework.boot:spring-boot-starter-web") 23 | testImplementation("org.springframework.boot:spring-boot-starter-test") 24 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 25 | testImplementation("org.testcontainers:junit-jupiter") 26 | testImplementation("org.testcontainers:mongodb") 27 | } 28 | 29 | tasks.named("test") { 30 | useJUnitPlatform() 31 | } -------------------------------------------------------------------------------- /data-rest-composite-id/src/main/java/zin/rashidi/datarest/compositeid/book/AuthorIdConverter.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.datarest.compositeid.book; 2 | 3 | import org.springframework.data.rest.webmvc.spi.BackendIdConverter; 4 | import org.springframework.stereotype.Component; 5 | 6 | import java.io.Serializable; 7 | 8 | import static java.lang.Long.parseLong; 9 | 10 | /** 11 | * @author Rashidi Zin 12 | */ 13 | @Component 14 | class AuthorIdConverter implements BackendIdConverter { 15 | 16 | @Override 17 | public Serializable fromRequestId(String id, Class entityType) { 18 | return new Author.Id().id(parseLong(id)); 19 | } 20 | 21 | @Override 22 | public String toRequestId(Serializable id, Class entityType) { 23 | return ((Author.Id) id).id().toString(); 24 | } 25 | 26 | @Override 27 | public boolean supports(Class aClass) { 28 | return Author.class.isAssignableFrom(aClass); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /jooq/src/main/java/zin/rashidi/boot/jooq/user/UserJooqRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.jooq.user; 2 | 3 | import org.jooq.DSLContext; 4 | import org.springframework.stereotype.Repository; 5 | 6 | import java.util.Optional; 7 | 8 | import static zin.rashidi.boot.jooq.Tables.USERS; 9 | 10 | /** 11 | * @author Rashidi Zin 12 | */ 13 | @Repository 14 | class UserJooqRepository implements UserRepository { 15 | 16 | private final DSLContext dsl; 17 | 18 | UserJooqRepository(DSLContext dsl) { 19 | this.dsl = dsl; 20 | } 21 | 22 | @Override 23 | public Optional findByUsername(String username) { 24 | return dsl.selectFrom(USERS).where(USERS.USERNAME.eq(username)) 25 | .withReadOnly() 26 | .maxRows(1) 27 | .stream() 28 | .map(record -> new User(record.getId(), record.getName(), record.getUsername())) 29 | .findFirst(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /test-execution-listeners/src/test/java/zin/rashidi/boot/test/user/UserDeletionTestExecutionListener.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.user; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.data.mongodb.core.MongoOperations; 6 | import org.springframework.test.context.TestContext; 7 | import org.springframework.test.context.support.AbstractTestExecutionListener; 8 | 9 | /** 10 | * @author Rashidi Zin 11 | */ 12 | class UserDeletionTestExecutionListener extends AbstractTestExecutionListener { 13 | 14 | private static final Logger log = LoggerFactory.getLogger(UserDeletionTestExecutionListener.class); 15 | 16 | @Override 17 | public void afterTestClass(TestContext testContext) { 18 | var mongo = testContext.getApplicationContext().getBean(MongoOperations.class); 19 | 20 | mongo.dropCollection(User.class); 21 | 22 | log.info("user collection dropped"); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /data-redis-cache/src/test/java/zin/rashidi/dataredis/cache/TestcontainersConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.dataredis.cache; 2 | 3 | import com.redis.testcontainers.RedisContainer; 4 | import org.springframework.boot.test.context.TestConfiguration; 5 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 6 | import org.springframework.context.annotation.Bean; 7 | import org.testcontainers.containers.PostgreSQLContainer; 8 | import org.testcontainers.utility.DockerImageName; 9 | 10 | @TestConfiguration(proxyBeanMethods = false) 11 | public class TestcontainersConfiguration { 12 | 13 | @Bean 14 | @ServiceConnection 15 | PostgreSQLContainer postgresContainer() { 16 | return new PostgreSQLContainer<>(DockerImageName.parse("postgres:latest")); 17 | } 18 | 19 | @Bean 20 | @ServiceConnection(name = "redis") 21 | RedisContainer redisContainer() { 22 | return new RedisContainer(DockerImageName.parse("redis:latest")); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /data-envers-audit/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 22 | implementation("org.springframework.data:spring-data-envers") 23 | runtimeOnly("com.mysql:mysql-connector-j") 24 | testImplementation("org.springframework.boot:spring-boot-starter-test") 25 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 26 | testImplementation("org.testcontainers:junit-jupiter") 27 | testImplementation("org.testcontainers:mysql") 28 | } 29 | 30 | tasks.named("test") { 31 | useJUnitPlatform() 32 | } -------------------------------------------------------------------------------- /data-jdbc-audit/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-jdbc") 22 | runtimeOnly("org.postgresql:postgresql") 23 | testImplementation("org.springframework.boot:spring-boot-starter-test") 24 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 25 | testImplementation("org.testcontainers:junit-jupiter") 26 | testImplementation("org.testcontainers:postgresql") 27 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 28 | } 29 | 30 | tasks.named("test") { 31 | useJUnitPlatform() 32 | } -------------------------------------------------------------------------------- /data-jpa-event/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 22 | runtimeOnly("org.postgresql:postgresql") 23 | testImplementation("org.springframework.boot:spring-boot-starter-test") 24 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 25 | testImplementation("org.testcontainers:junit-jupiter") 26 | testImplementation("org.testcontainers:postgresql") 27 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 28 | } 29 | 30 | tasks.named("test") { 31 | useJUnitPlatform() 32 | } -------------------------------------------------------------------------------- /data-domain-events/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 22 | implementation("org.springframework.boot:spring-boot-starter-web") 23 | runtimeOnly("com.mysql:mysql-connector-j") 24 | testImplementation("org.springframework.boot:spring-boot-starter-test") 25 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 26 | testImplementation("org.testcontainers:junit-jupiter") 27 | testImplementation("org.testcontainers:mysql") 28 | } 29 | 30 | tasks.named("test") { 31 | useJUnitPlatform() 32 | } -------------------------------------------------------------------------------- /data-repository-definition/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-jdbc") 22 | runtimeOnly("org.postgresql:postgresql") 23 | testImplementation("org.springframework.boot:spring-boot-starter-test") 24 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 25 | testImplementation("org.testcontainers:junit-jupiter") 26 | testImplementation("org.testcontainers:postgresql") 27 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 28 | } 29 | 30 | tasks.named("test") { 31 | useJUnitPlatform() 32 | } -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/course/CourseEventsConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.course; 2 | 3 | import org.springframework.context.ApplicationEventPublisher; 4 | import org.springframework.context.ApplicationListener; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.data.relational.core.mapping.event.AfterSaveEvent; 8 | 9 | import static zin.rashidi.boot.modulith.course.Course.Status.ENDED; 10 | 11 | /** 12 | * @author Rashidi Zin 13 | */ 14 | @Configuration 15 | class CourseEventsConfiguration { 16 | 17 | @Bean 18 | public ApplicationListener> courseEnded(ApplicationEventPublisher publisher) { 19 | return event -> { 20 | if (ENDED == event.getEntity().status()) { 21 | publisher.publishEvent(new CourseEnded(event.getEntity().id())); 22 | } 23 | }; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "spring-boot-tutorials" 2 | 3 | include("batch-rest-repository") 4 | include("batch-skip-step") 5 | include("cloud-jdbc-env-repo") 6 | include("data-domain-events") 7 | include("data-envers-audit") 8 | include("data-jdbc-audit") 9 | include("data-jdbc-schema-generation") 10 | include("data-jpa-audit") 11 | include("data-jpa-event") 12 | include("data-jpa-filtered-query") 13 | include("data-jpa-hibernate-cache") 14 | include("data-mongodb-audit") 15 | include("data-mongodb-full-text-search") 16 | include("data-mongodb-tc-data-load") 17 | include("data-mongodb-transactional") 18 | include("data-redis-cache") 19 | include("data-repository-definition") 20 | include("data-rest-composite-id") 21 | include("data-rest-validation") 22 | include("graphql") 23 | include("jooq") 24 | include("modulith") 25 | include("test-execution-listeners") 26 | include("test-rest-assured") 27 | include("test-slice-tests-rest") 28 | include("web-rest-client") 29 | include("web-thymeleaf-xss") -------------------------------------------------------------------------------- /data-jdbc-audit/src/main/java/zin/rashidi/boot/data/jdbc/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jdbc.user; 2 | 3 | import org.springframework.data.annotation.*; 4 | import org.springframework.data.relational.core.mapping.Table; 5 | 6 | import java.time.Instant; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | @Table("users") 12 | class User { 13 | 14 | @Id 15 | private Long id; 16 | 17 | @CreatedDate 18 | private Instant created; 19 | 20 | @CreatedBy 21 | private String createdBy; 22 | 23 | @LastModifiedDate 24 | private Instant lastModified; 25 | 26 | @LastModifiedBy 27 | private String lastModifiedBy; 28 | 29 | private final String name; 30 | private String username; 31 | 32 | User(String name, String username) { 33 | this.name = name; 34 | this.username = username; 35 | } 36 | 37 | public User username(String username) { 38 | this.username = username; 39 | return this; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/student/StudentEventsConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.student; 2 | 3 | import org.springframework.context.ApplicationEventPublisher; 4 | import org.springframework.context.ApplicationListener; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.data.relational.core.mapping.event.AfterSaveEvent; 8 | 9 | import static zin.rashidi.boot.modulith.student.Student.Status.INACTIVE; 10 | 11 | /** 12 | * @author Rashidi Zin 13 | */ 14 | @Configuration 15 | class StudentEventsConfiguration { 16 | 17 | @Bean 18 | public ApplicationListener> studentInactivated(ApplicationEventPublisher publisher) { 19 | return event -> { 20 | if (INACTIVE == event.getEntity().status()) 21 | publisher.publishEvent(new StudentInactivated(event.getEntity().id())); 22 | }; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /test-rest-assured/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-mongodb") 22 | implementation("org.springframework.boot:spring-boot-starter-web") 23 | testImplementation("org.springframework.boot:spring-boot-starter-test") 24 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 25 | testImplementation("org.testcontainers:junit-jupiter") 26 | testImplementation("org.testcontainers:mongodb") 27 | testImplementation("io.rest-assured:rest-assured") 28 | } 29 | 30 | tasks.named("test") { 31 | useJUnitPlatform() 32 | } -------------------------------------------------------------------------------- /test-rest-assured/src/test/java/zin/rashidi/boot/test/restassured/TestTestRestAssuredApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.restassured; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.test.context.TestConfiguration; 5 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 6 | import org.springframework.context.annotation.Bean; 7 | import org.testcontainers.containers.MongoDBContainer; 8 | import org.testcontainers.utility.DockerImageName; 9 | 10 | @TestConfiguration(proxyBeanMethods = false) 11 | public class TestTestRestAssuredApplication { 12 | 13 | @Bean 14 | @ServiceConnection 15 | MongoDBContainer mongoDbContainer() { 16 | return new MongoDBContainer(DockerImageName.parse("mongo:latest")); 17 | } 18 | 19 | public static void main(String[] args) { 20 | SpringApplication.from(TestRestAssuredApplication::main).with(TestTestRestAssuredApplication.class).run(args); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /data-jpa-filtered-query/src/main/java/zin/rashidi/boot/data/jpa/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jpa.user; 2 | 3 | import java.util.UUID; 4 | 5 | import jakarta.persistence.Entity; 6 | import jakarta.persistence.GeneratedValue; 7 | import jakarta.persistence.Id; 8 | 9 | /** 10 | * @author Rashidi Zin 11 | */ 12 | @Entity 13 | public class User { 14 | 15 | @Id 16 | @GeneratedValue 17 | private UUID id; 18 | 19 | private String name; 20 | 21 | private Status status; 22 | 23 | protected User() { 24 | } 25 | 26 | public User(String name, Status status) { 27 | this.name = name; 28 | this.status = status; 29 | } 30 | 31 | public UUID id() { 32 | return id; 33 | } 34 | 35 | public String name() { 36 | return name; 37 | } 38 | 39 | public Status status() { 40 | return status; 41 | } 42 | 43 | public enum Status { 44 | 45 | ACTIVE, 46 | 47 | INACTIVE 48 | 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /data-jpa-filtered-query/src/test/java/zin/rashidi/boot/data/jpa/TestDataJpaFilteredQueryApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jpa; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.test.context.TestConfiguration; 5 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 6 | import org.springframework.context.annotation.Bean; 7 | import org.testcontainers.containers.MySQLContainer; 8 | import org.testcontainers.utility.DockerImageName; 9 | 10 | @TestConfiguration(proxyBeanMethods = false) 11 | public class TestDataJpaFilteredQueryApplication { 12 | 13 | @Bean 14 | @ServiceConnection 15 | MySQLContainer mysqlContainer() { 16 | return new MySQLContainer<>(DockerImageName.parse("mysql:lts")); 17 | } 18 | 19 | public static void main(String[] args) { 20 | SpringApplication.from(DataJpaFilteredQueryApplication::main).with(TestDataJpaFilteredQueryApplication.class).run(args); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /modulith/src/main/java/zin/rashidi/boot/modulith/subscription/SubscriptionManagement.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.subscription; 2 | 3 | import org.springframework.modulith.events.ApplicationModuleListener; 4 | import org.springframework.stereotype.Component; 5 | import zin.rashidi.boot.modulith.course.CourseEnded; 6 | import zin.rashidi.boot.modulith.student.StudentInactivated; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | @Component 12 | class SubscriptionManagement { 13 | 14 | private final SubscriptionRepository subscriptions; 15 | 16 | SubscriptionManagement(SubscriptionRepository subscriptions) { 17 | this.subscriptions = subscriptions; 18 | } 19 | 20 | @ApplicationModuleListener 21 | void cancelByCourse(CourseEnded course) { 22 | subscriptions.cancelByCourseId(course.id()); 23 | } 24 | 25 | @ApplicationModuleListener 26 | void cancelByStudent(StudentInactivated student) { 27 | subscriptions.cancelByStudentId(student.id()); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /test-slice-tests-rest/src/main/java/zin/rashidi/boot/test/slices/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.slices.user; 2 | 3 | import jakarta.persistence.*; 4 | 5 | /** 6 | * @author Rashidi Zin 7 | */ 8 | @Entity 9 | @Table( 10 | name = "users", 11 | uniqueConstraints = @UniqueConstraint(name = "uniqueUsername", columnNames = "username") 12 | ) 13 | @SqlResultSetMapping(name = "User.WithoutId", classes = { 14 | @ConstructorResult(targetClass = UserWithoutId.class, columns = { 15 | @ColumnResult(name = "name", type = String.class), 16 | @ColumnResult(name = "username", type = String.class), 17 | @ColumnResult(name = "status", type = User.Status.class) 18 | }) 19 | }) 20 | class User { 21 | 22 | @Id 23 | @GeneratedValue 24 | private Long id; 25 | 26 | @Embedded 27 | private Name name; 28 | private String username; 29 | private Status status; 30 | 31 | enum Status { 32 | ACTIVE, DORMANT 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /data-mongodb-transactional/src/main/java/zin/rashidi/boot/data/mongodb/tm/user/UserResource.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb.tm.user; 2 | 3 | import static org.springframework.http.HttpStatus.CREATED; 4 | 5 | import org.springframework.transaction.annotation.Transactional; 6 | import org.springframework.web.bind.annotation.PostMapping; 7 | import org.springframework.web.bind.annotation.RequestBody; 8 | import org.springframework.web.bind.annotation.ResponseStatus; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | /** 12 | * @author Rashidi Zin 13 | */ 14 | @RestController 15 | class UserResource { 16 | 17 | private final UserRepository repository; 18 | 19 | UserResource(UserRepository repository) { 20 | this.repository = repository; 21 | } 22 | 23 | @PostMapping("/users") 24 | @ResponseStatus(CREATED) 25 | @Transactional 26 | public User add(@RequestBody User user) { 27 | return repository.save(user); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /test-slice-tests-rest/src/main/java/zin/rashidi/boot/test/slices/security/WebSecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.slices.security; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 6 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 7 | import org.springframework.security.web.SecurityFilterChain; 8 | 9 | import static org.springframework.security.config.Customizer.withDefaults; 10 | 11 | /** 12 | * @author Rashidi Zin 13 | */ 14 | @Configuration 15 | @EnableWebSecurity 16 | class WebSecurityConfiguration { 17 | 18 | @Bean 19 | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 20 | return http 21 | .httpBasic(withDefaults()) 22 | .authorizeHttpRequests(requests -> requests.anyRequest().authenticated()) 23 | .build(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /web-thymeleaf-xss/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion = JavaLanguageVersion.of(25) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-security") 22 | implementation("org.springframework.boot:spring-boot-starter-thymeleaf") 23 | implementation("org.springframework.boot:spring-boot-starter-web") 24 | implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity6") 25 | testImplementation("org.springframework.boot:spring-boot-starter-test") 26 | testImplementation("org.springframework.security:spring-security-test") 27 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 28 | } 29 | 30 | tasks.withType { 31 | useJUnitPlatform() 32 | } 33 | -------------------------------------------------------------------------------- /modulith/docs/components.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | set separator none 3 | title ModulithApplication 4 | 5 | top to bottom direction 6 | 7 | !include 8 | !include 9 | !include 10 | 11 | Container_Boundary("ModulithApplication.ModulithApplication_boundary", "ModulithApplication", $tags="") { 12 | Component(ModulithApplication.ModulithApplication.Course, "Course", $techn="Module", $descr="", $tags="", $link="") 13 | Component(ModulithApplication.ModulithApplication.Student, "Student", $techn="Module", $descr="", $tags="", $link="") 14 | Component(ModulithApplication.ModulithApplication.Subscription, "Subscription", $techn="Module", $descr="", $tags="", $link="") 15 | } 16 | 17 | Rel(ModulithApplication.ModulithApplication.Subscription, ModulithApplication.ModulithApplication.Student, "listens to", $techn="", $tags="", $link="") 18 | Rel(ModulithApplication.ModulithApplication.Subscription, ModulithApplication.ModulithApplication.Course, "listens to", $techn="", $tags="", $link="") 19 | 20 | SHOW_LEGEND(true) 21 | @enduml -------------------------------------------------------------------------------- /data-jpa-hibernate-cache/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion = JavaLanguageVersion.of(25) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.ehcache:ehcache::jakarta") 22 | implementation("org.hibernate.orm:hibernate-jcache") 23 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 24 | runtimeOnly("org.postgresql:postgresql") 25 | testImplementation("org.springframework.boot:spring-boot-starter-test") 26 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 27 | testImplementation("org.testcontainers:junit-jupiter") 28 | testImplementation("org.testcontainers:postgresql") 29 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 30 | } 31 | 32 | tasks.withType { 33 | useJUnitPlatform() 34 | } 35 | -------------------------------------------------------------------------------- /modulith/docs/module-subscription.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | set separator none 3 | title Subscription 4 | 5 | top to bottom direction 6 | 7 | !include 8 | !include 9 | !include 10 | 11 | Container_Boundary("ModulithApplication.ModulithApplication_boundary", "ModulithApplication", $tags="") { 12 | Component(ModulithApplication.ModulithApplication.Course, "Course", $techn="Module", $descr="", $tags="", $link="") 13 | Component(ModulithApplication.ModulithApplication.Student, "Student", $techn="Module", $descr="", $tags="", $link="") 14 | Component(ModulithApplication.ModulithApplication.Subscription, "Subscription", $techn="Module", $descr="", $tags="", $link="") 15 | } 16 | 17 | Rel(ModulithApplication.ModulithApplication.Subscription, ModulithApplication.ModulithApplication.Student, "listens to", $techn="", $tags="", $link="") 18 | Rel(ModulithApplication.ModulithApplication.Subscription, ModulithApplication.ModulithApplication.Course, "listens to", $techn="", $tags="", $link="") 19 | 20 | SHOW_LEGEND(true) 21 | @enduml -------------------------------------------------------------------------------- /data-jdbc-schema-generation/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-jdbc") 22 | implementation("org.liquibase:liquibase-core") 23 | runtimeOnly("org.postgresql:postgresql") 24 | testImplementation("org.springframework.boot:spring-boot-starter-test") 25 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 26 | testImplementation("org.testcontainers:junit-jupiter") 27 | testImplementation("org.testcontainers:postgresql") 28 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 29 | } 30 | 31 | tasks.named("test") { 32 | useJUnitPlatform() 33 | } -------------------------------------------------------------------------------- /data-rest-composite-id/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion = JavaLanguageVersion.of(25) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 22 | implementation("org.springframework.boot:spring-boot-starter-data-rest") 23 | runtimeOnly("org.postgresql:postgresql") 24 | testImplementation("org.springframework.boot:spring-boot-starter-test") 25 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 26 | testImplementation("org.testcontainers:junit-jupiter") 27 | testImplementation("org.testcontainers:postgresql") 28 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 29 | } 30 | 31 | tasks.withType { 32 | useJUnitPlatform() 33 | } 34 | -------------------------------------------------------------------------------- /modulith/src/test/java/zin/rashidi/boot/modulith/ModuleTests.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith; 2 | 3 | import org.junit.jupiter.api.DisplayName; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.modulith.core.ApplicationModules; 6 | import org.springframework.modulith.docs.Documenter; 7 | 8 | import static org.springframework.modulith.docs.Documenter.Options.defaults; 9 | 10 | /** 11 | * @author Rashidi Zin 12 | */ 13 | class ModuleTests { 14 | 15 | private final ApplicationModules modules = ApplicationModules.of(ModulithApplication.class); 16 | 17 | @Test 18 | @DisplayName("Verify architecture") 19 | void verify() { 20 | modules.verify(); 21 | } 22 | 23 | @Test 24 | @DisplayName("Generate documentation") 25 | void document() { 26 | new Documenter(modules, defaults().withOutputFolder("docs")) 27 | .writeModulesAsPlantUml() 28 | .writeDocumentation(Documenter.DiagramOptions.defaults(), Documenter.CanvasOptions.defaults().revealInternals()); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /data-envers-audit/src/main/java/zin/rashidi/boot/data/envers/book/Book.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.envers.book; 2 | 3 | import org.hibernate.envers.Audited; 4 | 5 | import jakarta.persistence.Entity; 6 | import jakarta.persistence.GeneratedValue; 7 | import jakarta.persistence.Id; 8 | 9 | /** 10 | * @author Rashidi Zin 11 | */ 12 | @Entity 13 | @Audited 14 | public class Book { 15 | 16 | @Id 17 | @GeneratedValue 18 | private Long id; 19 | 20 | private String author; 21 | 22 | private String title; 23 | 24 | public Long getId() { 25 | return id; 26 | } 27 | 28 | public void setId(Long id) { 29 | this.id = id; 30 | } 31 | 32 | public String getAuthor() { 33 | return author; 34 | } 35 | 36 | public void setAuthor(String author) { 37 | this.author = author; 38 | } 39 | 40 | public String getTitle() { 41 | return title; 42 | } 43 | 44 | public void setTitle(String title) { 45 | this.title = title; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test-slice-tests-rest/src/main/java/zin/rashidi/boot/test/slices/user/UserResource.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.slices.user; 2 | 3 | import org.springframework.web.bind.annotation.*; 4 | 5 | import static org.springframework.http.HttpStatus.NOT_FOUND; 6 | import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; 7 | 8 | /** 9 | * @author Rashidi Zin 10 | */ 11 | @RestController 12 | class UserResource { 13 | 14 | private final UserRepository repository; 15 | 16 | UserResource(UserRepository repository) { 17 | this.repository = repository; 18 | } 19 | 20 | @GetMapping(value = "/users/{username}", produces = APPLICATION_JSON_VALUE) 21 | public UserWithoutId findByUsername(@PathVariable String username) { 22 | return repository.findByUsername(username).orElseThrow(InvalidUserException::new); 23 | } 24 | 25 | @ExceptionHandler(InvalidUserException.class) 26 | @ResponseStatus(NOT_FOUND) 27 | public void handleInvalidUserException() {} 28 | 29 | static class InvalidUserException extends RuntimeException {} 30 | 31 | } 32 | -------------------------------------------------------------------------------- /data-redis-cache/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion = JavaLanguageVersion.of(25) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 22 | implementation("org.springframework.boot:spring-boot-starter-data-redis") 23 | runtimeOnly("org.postgresql:postgresql") 24 | testImplementation("org.springframework.boot:spring-boot-starter-test") 25 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 26 | testImplementation("org.testcontainers:junit-jupiter") 27 | testImplementation("org.testcontainers:postgresql") 28 | testImplementation("com.redis:testcontainers-redis") 29 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 30 | } 31 | 32 | tasks.named("test") { 33 | useJUnitPlatform() 34 | } 35 | -------------------------------------------------------------------------------- /batch-skip-step/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-batch") 22 | implementation("org.springframework.boot:spring-boot-starter-data-jdbc") 23 | implementation("com.fasterxml.jackson.core:jackson-databind") 24 | runtimeOnly("com.mysql:mysql-connector-j") 25 | testImplementation("org.springframework.boot:spring-boot-starter-test") 26 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 27 | testImplementation("org.springframework.batch:spring-batch-test") 28 | testImplementation("org.testcontainers:junit-jupiter") 29 | testImplementation("org.testcontainers:mysql") 30 | } 31 | 32 | tasks.named("test") { 33 | useJUnitPlatform() 34 | } -------------------------------------------------------------------------------- /data-rest-validation/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 22 | implementation("org.springframework.boot:spring-boot-starter-data-mongodb") 23 | implementation("org.springframework.boot:spring-boot-starter-data-rest") 24 | runtimeOnly("com.mysql:mysql-connector-j") 25 | testImplementation("org.springframework.boot:spring-boot-starter-test") 26 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 27 | testImplementation("org.testcontainers:junit-jupiter") 28 | testImplementation("org.testcontainers:mongodb") 29 | testImplementation("org.testcontainers:mysql") 30 | } 31 | 32 | tasks.named("test") { 33 | useJUnitPlatform() 34 | } -------------------------------------------------------------------------------- /data-domain-events/src/main/java/zin/rashidi/boot/data/de/availability/BookAvailability.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.de.availability; 2 | 3 | import jakarta.persistence.Entity; 4 | import jakarta.persistence.GeneratedValue; 5 | import jakarta.persistence.Id; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | @Entity 11 | class BookAvailability { 12 | 13 | @Id 14 | @GeneratedValue 15 | private Long id; 16 | 17 | private Long isbn; 18 | 19 | private Integer total; 20 | 21 | public Long getId() { 22 | return id; 23 | } 24 | 25 | public void setId(Long id) { 26 | this.id = id; 27 | } 28 | 29 | public Long getIsbn() { 30 | return isbn; 31 | } 32 | 33 | public void setIsbn(Long isbn) { 34 | this.isbn = isbn; 35 | } 36 | 37 | public Integer getTotal() { 38 | return total; 39 | } 40 | 41 | public void setTotal(Integer total) { 42 | this.total = total; 43 | } 44 | 45 | public BookAvailability reduceTotal() { 46 | this.total--; 47 | return this; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /web-thymeleaf-xss/src/main/java/zin/rashidi/web/xss/security/SecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.web.xss.security; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 6 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 7 | import org.springframework.security.web.SecurityFilterChain; 8 | 9 | import static org.springframework.security.web.header.writers.XXssProtectionHeaderWriter.HeaderValue.ENABLED_MODE_BLOCK; 10 | 11 | /** 12 | * @author Rashidi Zin 13 | */ 14 | @Configuration 15 | @EnableWebSecurity 16 | class SecurityConfiguration { 17 | 18 | @Bean 19 | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 20 | return http 21 | .headers(headers -> headers 22 | .contentSecurityPolicy(policy -> policy.policyDirectives("default-src 'self'")) 23 | .xssProtection(xss -> xss.headerValue(ENABLED_MODE_BLOCK)) 24 | ) 25 | .build(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /data-jpa-filtered-query/src/main/java/zin/rashidi/boot/data/jpa/jpa/JpaCustomBaseRepository.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.jpa.jpa; 2 | 3 | import static zin.rashidi.boot.data.jpa.user.User.Status.ACTIVE; 4 | 5 | import java.util.List; 6 | import java.util.stream.Stream; 7 | 8 | import org.springframework.data.jpa.repository.support.JpaEntityInformation; 9 | import org.springframework.data.jpa.repository.support.SimpleJpaRepository; 10 | import org.springframework.util.ReflectionUtils; 11 | 12 | import jakarta.persistence.EntityManager; 13 | 14 | /** 15 | * @author Rashidi Zin 16 | */ 17 | class JpaCustomBaseRepository extends SimpleJpaRepository { 18 | 19 | public JpaCustomBaseRepository(JpaEntityInformation entityInformation, EntityManager entityManager) { 20 | super(entityInformation, entityManager); 21 | } 22 | 23 | @Override 24 | public List findAll() { 25 | var hasStatusField = Stream.of(ReflectionUtils.getDeclaredMethods(getDomainClass())).anyMatch(field -> field.getName().equals("status")); 26 | return hasStatusField ? findAll((root, _, _) -> root.get("status").in(ACTIVE)) : super.findAll(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /test-execution-listeners/src/test/java/zin/rashidi/boot/test/user/UserStatusUpdateTestExecutionListener.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.test.user; 2 | 3 | import static org.springframework.data.mongodb.core.query.Criteria.where; 4 | import static org.springframework.data.mongodb.core.query.Query.query; 5 | import static zin.rashidi.boot.test.user.User.Status.INACTIVE; 6 | 7 | import org.springframework.data.mongodb.core.MongoOperations; 8 | import org.springframework.test.context.TestContext; 9 | import org.springframework.test.context.support.AbstractTestExecutionListener; 10 | 11 | /** 12 | * @author Rashidi Zin 13 | */ 14 | class UserStatusUpdateTestExecutionListener extends AbstractTestExecutionListener { 15 | 16 | @Override 17 | public void beforeTestClass(TestContext testContext) { 18 | var mongo = testContext.getApplicationContext().getBean(MongoOperations.class); 19 | var findByUsername = mongo.findOne(query(where("username").is("rashidi.zin")), User.class); 20 | 21 | mongo.save(findByUsername.status(INACTIVE)); 22 | } 23 | 24 | @Override 25 | public int getOrder() { 26 | return 1; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /data-rest-validation/src/test/java/zin/rashidi/boot/data/rest/TestDataRestValidationApplication.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.rest; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.test.context.TestConfiguration; 5 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 6 | import org.springframework.context.annotation.Bean; 7 | import org.testcontainers.containers.MongoDBContainer; 8 | import org.testcontainers.containers.MySQLContainer; 9 | import org.testcontainers.utility.DockerImageName; 10 | 11 | @TestConfiguration(proxyBeanMethods = false) 12 | public class TestDataRestValidationApplication { 13 | 14 | @Bean 15 | @ServiceConnection 16 | MongoDBContainer mongoDbContainer() { 17 | return new MongoDBContainer(DockerImageName.parse("mongo:latest")); 18 | } 19 | 20 | @Bean 21 | @ServiceConnection 22 | MySQLContainer mysqlContainer() { 23 | return new MySQLContainer<>(DockerImageName.parse("mysql:lts")); 24 | } 25 | 26 | public static void main(String[] args) { 27 | SpringApplication.from(DataRestValidationApplication::main).with(TestDataRestValidationApplication.class).run(args); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /batch-rest-repository/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-batch") 22 | implementation("org.springframework.boot:spring-boot-starter-data-mongodb") 23 | implementation("com.fasterxml.jackson.core:jackson-databind") 24 | runtimeOnly("com.mysql:mysql-connector-j") 25 | testImplementation("org.springframework.boot:spring-boot-starter-test") 26 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 27 | testImplementation("org.springframework.batch:spring-batch-test") 28 | testImplementation("org.testcontainers:junit-jupiter") 29 | testImplementation("org.testcontainers:mongodb") 30 | testImplementation("org.testcontainers:mysql") 31 | } 32 | 33 | tasks.named("test") { 34 | useJUnitPlatform() 35 | } -------------------------------------------------------------------------------- /data-domain-events/src/main/java/zin/rashidi/boot/data/de/availability/BookAvailabilityManagement.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.de.availability; 2 | 3 | import static org.springframework.transaction.annotation.Propagation.REQUIRES_NEW; 4 | 5 | import org.springframework.stereotype.Service; 6 | import org.springframework.transaction.annotation.Transactional; 7 | import org.springframework.transaction.event.TransactionalEventListener; 8 | 9 | import zin.rashidi.boot.data.de.book.BookPurchaseEvent; 10 | 11 | /** 12 | * @author Rashidi Zin 13 | */ 14 | @Service 15 | class BookAvailabilityManagement { 16 | 17 | private final BookAvailabilityRepository repository; 18 | 19 | BookAvailabilityManagement(BookAvailabilityRepository repository) { 20 | this.repository = repository; 21 | } 22 | 23 | @TransactionalEventListener 24 | @Transactional(propagation = REQUIRES_NEW) 25 | public void updateTotal(BookPurchaseEvent event) { 26 | var book = event.getSource(); 27 | 28 | repository.findByIsbn(book.getIsbn()) 29 | .map(BookAvailability::reduceTotal) 30 | .ifPresent(repository::save); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /graphql/src/main/java/zin/rashidi/boot/graphql/book/BookRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.graphql.book; 2 | 3 | import org.springframework.stereotype.Repository; 4 | import zin.rashidi.boot.graphql.book.Book.Author; 5 | import zin.rashidi.boot.graphql.book.Book.Author.Name; 6 | import zin.rashidi.boot.graphql.book.Book.Isbn; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author Rashidi Zin 12 | */ 13 | @Repository 14 | class BookRepositoryImpl implements BookRepository { 15 | 16 | @Override 17 | public List findAll() { 18 | return List.of( 19 | new Book(new Isbn(9780132350884L, 978, 0, 13235088, 4), "Clean Code", new Author(new Name("Robert", "Martin"))), 20 | new Book(new Isbn(9780201633610L, 978, 0, 20163361, 0), "Design Patterns", new Author(new Name("Erich", "Gamma"))), 21 | new Book(new Isbn(9780132350884L, 978, 0, 13235088, 4), "The Hobbit", new Author(new Name("J.R.R.", "Tolkien"))) 22 | ); 23 | } 24 | 25 | @Override 26 | public Book findByTitle(String title) { 27 | return findAll().stream().filter(book -> book.title().equalsIgnoreCase(title)).findFirst().orElse(null); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /test-slice-tests-rest/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 22 | implementation("org.springframework.boot:spring-boot-starter-web") 23 | implementation("org.springframework.boot:spring-boot-starter-security") 24 | testImplementation("org.springframework.security:spring-security-test") 25 | runtimeOnly("org.postgresql:postgresql") 26 | testImplementation("org.springframework.boot:spring-boot-starter-test") 27 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 28 | testImplementation("org.springframework.batch:spring-batch-test") 29 | testImplementation("org.testcontainers:junit-jupiter") 30 | testImplementation("org.testcontainers:postgresql") 31 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 32 | } 33 | 34 | tasks.named("test") { 35 | useJUnitPlatform() 36 | } -------------------------------------------------------------------------------- /data-mongodb-full-text-search/src/main/java/zin/rashidi/boot/data/mongodb/character/CharacterSearchRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb.character; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.domain.Sort; 6 | import org.springframework.data.mongodb.core.MongoOperations; 7 | import org.springframework.data.mongodb.core.index.TextIndexDefinition; 8 | import org.springframework.data.mongodb.core.query.TextCriteria; 9 | import org.springframework.data.mongodb.core.query.TextQuery; 10 | 11 | /** 12 | * @author Rashidi Zin 13 | */ 14 | class CharacterSearchRepositoryImpl implements CharacterSearchRepository { 15 | 16 | private final MongoOperations operations; 17 | 18 | CharacterSearchRepositoryImpl(MongoOperations operations) { 19 | this.operations = operations; 20 | } 21 | 22 | @Override 23 | public List findByText(String text, Sort sort) { 24 | operations.indexOps(Character.class) 25 | .createIndex(TextIndexDefinition.builder().onFields("name", "publisher").build()); 26 | 27 | var parameters = text.split(" "); 28 | var query = TextQuery.queryText(new TextCriteria().matchingAny(parameters)).with(sort); 29 | 30 | return operations.find(query, Character.class); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = Spring Boot: Samples & Tutorials 2 | :nofooter: 3 | :icons: font 4 | :url-quickref: https://github.com/rashidi/spring-boot-tutorials 5 | 6 | Samples and tutorials for https://spring.io/projects/spring-boot[Spring Boot] modules such as, but not limited to, 7 | Spring Data, Spring Batch, Spring Cloud, Spring Security, Spring GraphQL, and Spring Test. Each tutorial is equipped 8 | with source code in individual submodules and can be found on {url-quickref}[GitHub]. 9 | 10 | == Motivation 11 | 12 | While it is common to find https://spring.io/projects/spring-boot[Spring Boot] tutorials on the Internet, it is 13 | challenging to find tutorials that are up-to-date and include automated tests to demonstrate the implementation and 14 | ensure stability. 15 | 16 | == Commitment 17 | 18 | Continual improvement is fundamental in software development. This repository is committed in ensuring adherence to 19 | best practices and keeping all dependencies up-to-date. The quality of these tutorials and the knowledge imparted is, 20 | and always will be, my primary goal. 21 | 22 | With the help of https://github.com/dependabot[Dependabot], each tutorial is also kept up-to-date with the latest 23 | dependencies. Currently, we are using Java https://adoptium.net/en-GB/temurin/releases/?version=25[Temurin 25] 24 | -------------------------------------------------------------------------------- /modulith/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | java { 11 | toolchain { 12 | languageVersion.set(JavaLanguageVersion.of(25)) 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | implementation(platform("org.springframework.modulith:spring-modulith-bom:1.4.4")) 22 | 23 | implementation("org.springframework.boot:spring-boot-starter-data-jdbc") 24 | implementation("org.springframework.modulith:spring-modulith-starter-core") 25 | implementation("org.springframework.modulith:spring-modulith-starter-jdbc") 26 | runtimeOnly("org.postgresql:postgresql") 27 | testImplementation("org.springframework.boot:spring-boot-starter-test") 28 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 29 | testImplementation("org.springframework.modulith:spring-modulith-starter-test") 30 | testImplementation("org.testcontainers:junit-jupiter") 31 | testImplementation("org.testcontainers:postgresql") 32 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 33 | } 34 | 35 | tasks.named("test") { 36 | useJUnitPlatform() 37 | } -------------------------------------------------------------------------------- /data-mongodb-transactional/src/main/java/zin/rashidi/boot/data/mongodb/tm/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb.tm.user; 2 | 3 | import org.bson.types.ObjectId; 4 | import org.springframework.data.annotation.Id; 5 | import org.springframework.data.mongodb.core.mapping.Document; 6 | 7 | /** 8 | * @author Rashidi Zin 9 | */ 10 | @Document 11 | class User { 12 | 13 | @Id 14 | private ObjectId id; 15 | private String name; 16 | private String username; 17 | private Status status; 18 | 19 | public ObjectId getId() { 20 | return id; 21 | } 22 | 23 | public void setId(ObjectId id) { 24 | this.id = id; 25 | } 26 | 27 | public String getName() { 28 | return name; 29 | } 30 | 31 | public void setName(String name) { 32 | this.name = name; 33 | } 34 | 35 | public String getUsername() { 36 | return username; 37 | } 38 | 39 | public void setUsername(String username) { 40 | this.username = username; 41 | } 42 | 43 | public Status getStatus() { 44 | return status; 45 | } 46 | 47 | public void setStatus(Status status) { 48 | this.status = status; 49 | } 50 | 51 | enum Status { 52 | 53 | ACTIVE, 54 | 55 | INACTIVE 56 | 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /data-jpa-audit/src/main/java/zin/rashidi/boot/data/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.user; 2 | 3 | import jakarta.persistence.*; 4 | import org.springframework.data.annotation.CreatedBy; 5 | import org.springframework.data.annotation.CreatedDate; 6 | import org.springframework.data.annotation.LastModifiedBy; 7 | import org.springframework.data.annotation.LastModifiedDate; 8 | import org.springframework.data.jpa.domain.support.AuditingEntityListener; 9 | 10 | import java.time.Instant; 11 | 12 | /** 13 | * @author Rashidi Zin 14 | */ 15 | @Entity 16 | @Table(name = "users") 17 | @EntityListeners(AuditingEntityListener.class) 18 | class User { 19 | 20 | @Id 21 | @GeneratedValue 22 | private Long id; 23 | 24 | private String name; 25 | private String username; 26 | 27 | @CreatedBy 28 | private String createdBy; 29 | 30 | @CreatedDate 31 | private Instant created; 32 | 33 | @LastModifiedBy 34 | private String modifiedBy; 35 | 36 | @LastModifiedDate 37 | private Instant modified; 38 | 39 | protected User() {} 40 | 41 | User(String name, String username) { 42 | this.name = name; 43 | this.username = username; 44 | } 45 | 46 | public void setUsername(String username) { 47 | this.username = username; 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /data-domain-events/src/main/java/zin/rashidi/boot/data/de/book/Book.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.de.book; 2 | 3 | import org.springframework.data.domain.AbstractAggregateRoot; 4 | 5 | import jakarta.persistence.Entity; 6 | import jakarta.persistence.GeneratedValue; 7 | import jakarta.persistence.Id; 8 | 9 | /** 10 | * @author Rashidi Zin 11 | */ 12 | @Entity 13 | public class Book extends AbstractAggregateRoot { 14 | 15 | @Id 16 | @GeneratedValue 17 | private Long id; 18 | private String title; 19 | private String author; 20 | private Long isbn; 21 | 22 | public Long getId() { 23 | return id; 24 | } 25 | 26 | public void setId(Long id) { 27 | this.id = id; 28 | } 29 | 30 | public String getTitle() { 31 | return title; 32 | } 33 | 34 | public void setTitle(String title) { 35 | this.title = title; 36 | } 37 | 38 | public String getAuthor() { 39 | return author; 40 | } 41 | 42 | public void setAuthor(String author) { 43 | this.author = author; 44 | } 45 | 46 | public Long getIsbn() { 47 | return isbn; 48 | } 49 | 50 | public void setIsbn(Long isbn) { 51 | this.isbn = isbn; 52 | } 53 | 54 | public Book purchase() { 55 | registerEvent(new BookPurchaseEvent(this)); 56 | return this; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /cloud-jdbc-env-repo/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | id("org.springframework.boot") version "3.5.7" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | group = "zin.rashidi.boot" 8 | version = "0.0.1-SNAPSHOT" 9 | 10 | val springCloudVersion = "2025.0.0" 11 | 12 | java { 13 | toolchain { 14 | languageVersion.set(JavaLanguageVersion.of(25)) 15 | } 16 | } 17 | 18 | configurations { 19 | compileOnly { 20 | extendsFrom(configurations.annotationProcessor.get()) 21 | } 22 | } 23 | 24 | repositories { 25 | mavenCentral() 26 | } 27 | 28 | dependencies { 29 | implementation(platform("org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}")) 30 | 31 | implementation("org.springframework.boot:spring-boot-starter-data-jdbc") 32 | implementation("org.springframework.cloud:spring-cloud-starter-bootstrap") 33 | implementation("org.springframework.cloud:spring-cloud-config-server") 34 | runtimeOnly("com.mysql:mysql-connector-j") 35 | annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") 36 | testImplementation("org.springframework.boot:spring-boot-starter-test") 37 | testImplementation("org.springframework.boot:spring-boot-testcontainers") 38 | testImplementation("org.testcontainers:junit-jupiter") 39 | testImplementation("org.testcontainers:mysql") 40 | } 41 | 42 | tasks.named("test") { 43 | useJUnitPlatform() 44 | } -------------------------------------------------------------------------------- /data-mongodb-audit/src/main/java/zin/rashidi/boot/data/mongodb/user/User.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.data.mongodb.user; 2 | 3 | import java.time.Instant; 4 | 5 | import org.bson.types.ObjectId; 6 | import org.springframework.data.annotation.CreatedBy; 7 | import org.springframework.data.annotation.CreatedDate; 8 | import org.springframework.data.annotation.Id; 9 | import org.springframework.data.annotation.LastModifiedBy; 10 | import org.springframework.data.annotation.LastModifiedDate; 11 | import org.springframework.data.mongodb.core.mapping.Document; 12 | 13 | /** 14 | * @author Rashidi Zin 15 | */ 16 | @Document 17 | class User { 18 | 19 | @Id 20 | private ObjectId id; 21 | 22 | private String name; 23 | 24 | private String username; 25 | 26 | @CreatedBy 27 | private String createdBy; 28 | 29 | @CreatedDate 30 | private Instant created; 31 | 32 | @LastModifiedBy 33 | private String modifiedBy; 34 | 35 | @LastModifiedDate 36 | private Instant modified; 37 | 38 | public ObjectId id() { 39 | return id; 40 | } 41 | 42 | public User name(String name) { 43 | this.name = name; 44 | return this; 45 | } 46 | 47 | public User username(String username) { 48 | this.username = username; 49 | return this; 50 | } 51 | 52 | public Instant modified() { 53 | return modified; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /data-jdbc-schema-generation/src/main/resources/db/changelog/user.yaml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | id: '1744500868871' 4 | author: Spring Data Relational 5 | objectQuotingStrategy: LEGACY 6 | changes: 7 | - createTable: 8 | columns: 9 | - column: 10 | autoIncrement: true 11 | constraints: 12 | nullable: true 13 | primaryKey: true 14 | name: id 15 | type: BIGINT 16 | - column: 17 | constraints: 18 | nullable: true 19 | name: name 20 | type: VARCHAR(255 BYTE) 21 | - column: 22 | constraints: 23 | nullable: false 24 | name: book 25 | type: BIGINT 26 | tableName: author 27 | - createTable: 28 | columns: 29 | - column: 30 | autoIncrement: true 31 | constraints: 32 | nullable: true 33 | primaryKey: true 34 | name: isbn 35 | type: BIGINT 36 | - column: 37 | constraints: 38 | nullable: true 39 | name: title 40 | type: VARCHAR(255 BYTE) 41 | tableName: book 42 | - addForeignKeyConstraint: 43 | baseColumnNames: book 44 | baseTableName: author 45 | constraintName: book_isbn_fk 46 | referencedColumnNames: isbn 47 | referencedTableName: book 48 | 49 | -------------------------------------------------------------------------------- /modulith/src/test/java/zin/rashidi/boot/modulith/student/StudentManagementTests.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.student; 2 | 3 | import org.junit.jupiter.api.DisplayName; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.annotation.Import; 7 | import org.springframework.modulith.test.ApplicationModuleTest; 8 | import org.springframework.modulith.test.Scenario; 9 | import org.springframework.test.util.ReflectionTestUtils; 10 | import zin.rashidi.boot.modulith.TestcontainersConfiguration; 11 | 12 | import static org.assertj.core.api.Assertions.assertThat; 13 | 14 | /** 15 | * @author Rashidi Zin 16 | */ 17 | @Import(TestcontainersConfiguration.class) 18 | @ApplicationModuleTest 19 | class StudentManagementTests { 20 | 21 | @Autowired 22 | private StudentManagement students; 23 | 24 | @Test 25 | @DisplayName("When the student with id 4 is inactivated Then StudentInactivated event will be triggered with student id 4") 26 | void inactive(Scenario scenario) { 27 | var student = new Student("Bob Johnson"); 28 | ReflectionTestUtils.setField(student, "id", 4L); 29 | 30 | scenario.stimulate(() -> students.inactive(student)) 31 | .andWaitForEventOfType(StudentInactivated.class) 32 | .toArriveAndVerify(inActivatedStudent -> assertThat(inActivatedStudent).extracting("id").isEqualTo(4L)); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /supplemental-ui/partials/header-content.hbs: -------------------------------------------------------------------------------- 1 |
2 | 25 |
26 | -------------------------------------------------------------------------------- /cloud-jdbc-env-repo/src/test/java/zin/rashidi/boot/cloud/jdbcenvrepo/CloudJdbcEnvRepoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.cloud.jdbcenvrepo; 2 | 3 | import org.junit.jupiter.api.DisplayName; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.boot.test.web.client.TestRestTemplate; 8 | import org.testcontainers.containers.MySQLContainer; 9 | import org.testcontainers.junit.jupiter.Container; 10 | import org.testcontainers.junit.jupiter.Testcontainers; 11 | 12 | import static org.assertj.core.api.Assertions.assertThat; 13 | import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; 14 | 15 | @Testcontainers 16 | @SpringBootTest(properties = "spring.datasource.url=jdbc:tc:mysql:lts:///test?TC_INITSCRIPT=init-script.sql", webEnvironment = RANDOM_PORT) 17 | class CloudJdbcEnvRepoApplicationTests { 18 | 19 | @Container 20 | private static final MySQLContainer MYSQL = new MySQLContainer<>("mysql:lts"); 21 | 22 | @Autowired 23 | private TestRestTemplate restClient; 24 | 25 | @Test 26 | @DisplayName("Given app.greet.name is configured to Demo in the database When I call greet Then I should get Hello, my name is Demo") 27 | void greet() { 28 | var response = restClient.getForEntity("/greet?greeting={0}", String.class, "Hello"); 29 | 30 | assertThat(response.getBody()).isEqualTo("Hello, my name is Demo"); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /web-thymeleaf-xss/src/test/java/zin/rashidi/web/xss/greet/GreetResourceTests.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.web.xss.greet; 2 | 3 | import org.junit.jupiter.api.DisplayName; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 7 | import org.springframework.context.annotation.ComponentScan.Filter; 8 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 9 | import org.springframework.test.web.servlet.assertj.MockMvcTester; 10 | 11 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; 12 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 13 | 14 | /** 15 | * @author Rashidi Zin 16 | */ 17 | @WebMvcTest(controllers = GreetResource.class, includeFilters = @Filter(classes = EnableWebSecurity.class)) 18 | class GreetResourceTests { 19 | 20 | @Autowired 21 | private MockMvcTester mvc; 22 | 23 | @Test 24 | @DisplayName("Given XSS protection is enabled Then response header should contain information about X-XSS-Protection and Content-Security-Policy") 25 | void headers() { 26 | mvc.get() 27 | .uri("/greet?name={name}", "rashidi") 28 | .assertThat() 29 | .matches(status().isOk()) 30 | .matches(header().string("Content-Security-Policy", "default-src 'self'")) 31 | .matches(header().string("X-XSS-Protection", "1; mode=block")); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /modulith/src/test/java/zin/rashidi/boot/modulith/course/CourseManagementTests.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.modulith.course; 2 | 3 | import org.junit.jupiter.api.DisplayName; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.annotation.Import; 7 | import org.springframework.modulith.test.ApplicationModuleTest; 8 | import org.springframework.modulith.test.Scenario; 9 | import org.springframework.test.util.ReflectionTestUtils; 10 | import zin.rashidi.boot.modulith.TestcontainersConfiguration; 11 | 12 | import static java.time.Duration.ofMillis; 13 | import static org.assertj.core.api.Assertions.assertThat; 14 | import static zin.rashidi.boot.modulith.course.Course.Status.ENDED; 15 | 16 | /** 17 | * @author Rashidi Zin 18 | */ 19 | @Import(TestcontainersConfiguration.class) 20 | @ApplicationModuleTest 21 | class CourseManagementTests { 22 | 23 | @Autowired 24 | private CourseManagement courses; 25 | 26 | @Test 27 | @DisplayName("When a course is ENDED Then CourseEnded event will be triggered with the course Id") 28 | void courseEnded(Scenario scenario) { 29 | var course = new Course("Advanced Java Programming").status(ENDED); 30 | ReflectionTestUtils.setField(course, "id", 2L); 31 | 32 | scenario.stimulate(() -> courses.updateCourse(course)) 33 | .andWaitAtMost(ofMillis(101)) 34 | .andWaitForEventOfType(CourseEnded.class) 35 | .toArriveAndVerify(event -> assertThat(event).extracting("id").isEqualTo(2L)); 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /data-jdbc-schema-generation/src/test/java/zin/rashidi/boot/jdbcscgm/book/BookRepositoryTests.java: -------------------------------------------------------------------------------- 1 | package zin.rashidi.boot.jdbcscgm.book; 2 | 3 | import org.junit.jupiter.api.BeforeAll; 4 | import org.junit.jupiter.api.DisplayName; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.data.jdbc.DataJdbcTest; 8 | import org.springframework.context.annotation.Import; 9 | import org.springframework.core.io.FileSystemResource; 10 | import org.springframework.data.jdbc.core.mapping.schema.LiquibaseChangeSetWriter; 11 | import org.springframework.data.relational.core.mapping.RelationalMappingContext; 12 | import zin.rashidi.boot.jdbcscgm.TestcontainersConfiguration; 13 | 14 | import java.io.IOException; 15 | import java.util.Set; 16 | 17 | import static org.assertj.core.api.Assertions.assertThat; 18 | 19 | /** 20 | * @author Rashidi Zin 21 | */ 22 | @Import(TestcontainersConfiguration.class) 23 | @DataJdbcTest 24 | class BookRepositoryTests { 25 | 26 | @BeforeAll 27 | static void generateSchema(@Autowired RelationalMappingContext context) throws IOException { 28 | context.setInitialEntitySet(Set.of(Author.class, Book.class)); 29 | 30 | var writer = new LiquibaseChangeSetWriter(context); 31 | writer.writeChangeSet(new FileSystemResource("user.yaml")); 32 | } 33 | 34 | @Test 35 | @DisplayName("Given the user.yaml exists, when changelogExists, then return true") 36 | void changelogExists() { 37 | assertThat(new FileSystemResource("user.yaml").exists()).isTrue(); 38 | } 39 | 40 | } 41 | --------------------------------------------------------------------------------