├── .gitignore ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── CODE_OF_CONDUCT.adoc ├── CONTRIBUTING.adoc ├── LICENSE.txt ├── README.adoc ├── autoconfigure-adapter ├── README.adoc ├── build.gradle.kts └── src │ └── main │ └── java │ └── org │ └── springframework │ ├── boot │ ├── autoconfigure │ │ ├── cassandra │ │ │ └── CassandraInitializer.java │ │ ├── context │ │ │ └── MessageSourceInitializer.java │ │ ├── data │ │ │ ├── cassandra │ │ │ │ ├── CassandraDataInitializer.java │ │ │ │ └── CassandraReactiveDataInitializer.java │ │ │ ├── elasticsearch │ │ │ │ ├── ElasticSearchDataInitializer.java │ │ │ │ └── ReactiveElasticSearchDataInitializer.java │ │ │ ├── mongo │ │ │ │ ├── MongoDataInitializer.java │ │ │ │ └── MongoReactiveDataInitializer.java │ │ │ ├── r2dbc │ │ │ │ └── R2dbcDataInitializer.java │ │ │ └── redis │ │ │ │ ├── ClusterInitializer.java │ │ │ │ ├── JedisRedisInitializer.java │ │ │ │ ├── LettuceRedisInitializer.java │ │ │ │ ├── RedisInitializer.java │ │ │ │ ├── RedisReactiveInitializer.java │ │ │ │ └── SentinelInitializer.java │ │ ├── jackson │ │ │ └── JacksonInitializer.java │ │ ├── jdbc │ │ │ ├── DataSourceConfiguration_GenericInitializer.java │ │ │ ├── DataSourceConfiguration_HikariInitializer.java │ │ │ ├── DataSourceInitializer.java │ │ │ ├── DataSourceTransactionManagerAutoConfigurationInitializer.java │ │ │ ├── EmbeddedDataSourceConfigurationInitializer.java │ │ │ ├── JdbcTemplateConfigurationInitializer.java │ │ │ └── metadata │ │ │ │ ├── DataSourcePoolMetadataProvidersConfigurationInitializer.java │ │ │ │ ├── DataSourcePoolMetadataProvidersConfiguration_CommonsDbcp2PoolDataSourceMetadataProviderConfigurationInitializer.java │ │ │ │ ├── DataSourcePoolMetadataProvidersConfiguration_HikariPoolDataSourceMetadataProviderConfigurationInitializer.java │ │ │ │ └── DataSourcePoolMetadataProvidersConfiguration_TomcatDataSourcePoolMetadataProviderConfigurationInitializer.java │ │ ├── jooq │ │ │ └── JooqConfigurationInitializer.java │ │ ├── mongo │ │ │ ├── MongoInitializer.java │ │ │ ├── MongoReactiveInitializer.java │ │ │ └── embedded │ │ │ │ └── EmbeddedMongoInitializer.java │ │ ├── mustache │ │ │ ├── MustacheInitializer.java │ │ │ ├── MustacheReactiveWebInitializer.java │ │ │ └── MustacheServletWebInitializer.java │ │ ├── r2dbc │ │ │ └── R2dbcInitializer.java │ │ ├── thymeleaf │ │ │ ├── ThymeleafInitializer.java │ │ │ ├── ThymeleafReactiveWebInitializer.java │ │ │ └── ThymeleafServletWebInitializer.java │ │ └── web │ │ │ ├── reactive │ │ │ ├── AbstractCodecInitializer.java │ │ │ ├── FormCodecInitializer.java │ │ │ ├── JacksonJsonCodecInitializer.java │ │ │ ├── KotlinSerializationCodecInitializer.java │ │ │ ├── MultipartCodecInitializer.java │ │ │ ├── ProtobufCodecInitializer.java │ │ │ ├── ReactiveWebServerInitializer.java │ │ │ ├── ResourceCodecInitializer.java │ │ │ ├── StringCodecInitializer.java │ │ │ └── function │ │ │ │ └── client │ │ │ │ └── ReactiveWebClientBuilderInitializer.java │ │ │ └── servlet │ │ │ ├── AtomConverterInitializer.java │ │ │ ├── FormConverterInitializer.java │ │ │ ├── JacksonJsonConverterInitializer.java │ │ │ ├── KotlinSerializationConverterInitializer.java │ │ │ ├── ResourceConverterInitializer.java │ │ │ ├── RssConverterInitializer.java │ │ │ ├── ServletWebServerInitializer.java │ │ │ └── StringConverterInitializer.java │ └── context │ │ └── properties │ │ ├── FunctionalConfigurationPropertiesBinder.java │ │ └── FunctionalPropertySourcesDeducer.java │ └── security │ └── config │ └── annotation │ └── web │ ├── configuration │ ├── HttpSecurityInitializer.java │ ├── ObjectPostProcessorInitializer.java │ ├── WebMvcSecurityInitializer.java │ └── WebSecurityInitializer.java │ └── reactive │ ├── ServerHttpSecurityInitializer.java │ └── WebFluxSecurityInitializer.java ├── build.gradle.kts ├── build.sh ├── ci ├── build.sh ├── deploy.sh └── pipeline.yml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jafu ├── README.adoc ├── build.gradle.kts └── src │ ├── main │ └── java │ │ └── org │ │ └── springframework │ │ └── fu │ │ └── jafu │ │ ├── AbstractDsl.java │ │ ├── ApplicationDsl.java │ │ ├── BeanDefinitionDsl.java │ │ ├── ConfigurationDsl.java │ │ ├── Jafu.java │ │ ├── JafuApplication.java │ │ ├── LoggingDsl.java │ │ ├── cassandra │ │ └── CassandraDsl.java │ │ ├── elasticsearch │ │ ├── AbstractElasticSearchDsl.java │ │ ├── ElasticSearchDsl.java │ │ └── ReactiveElasticSearchDsl.java │ │ ├── jdbc │ │ └── JdbcDsl.java │ │ ├── mongo │ │ ├── ReactiveMongoDsl.java │ │ └── package-info.java │ │ ├── package-info.java │ │ ├── r2dbc │ │ ├── DataR2dbcDsl.java │ │ └── R2dbcDsl.java │ │ ├── redis │ │ ├── AbstractRedisDsl.java │ │ ├── ReactiveRedisDsl.java │ │ └── RedisDsl.java │ │ ├── templating │ │ ├── MustacheDsl.java │ │ └── ThymeleafDsl.java │ │ ├── web │ │ └── JacksonDsl.java │ │ ├── webflux │ │ ├── WebFluxClientDsl.java │ │ ├── WebFluxServerDsl.java │ │ └── package-info.java │ │ └── webmvc │ │ └── WebMvcServerDsl.java │ └── test │ ├── java │ └── org │ │ └── springframework │ │ └── fu │ │ └── jafu │ │ ├── ApplicationDslTests.java │ │ ├── LoggingDslTests.java │ │ ├── elasticsearch │ │ ├── ElasticSearchDslTest.java │ │ └── ReactiveElasticSearchDslTest.java │ │ ├── jdbc │ │ └── JdbcDslTests.java │ │ ├── r2dbc │ │ ├── DataR2dbcDslTest.java │ │ └── R2dbcDslTest.java │ │ ├── redis │ │ ├── ReactiveRedisDslTests.java │ │ ├── RedisDslTests.java │ │ └── TestUser.java │ │ ├── web │ │ └── JacksonDslTests.java │ │ ├── webflux │ │ ├── MustacheDslTests.java │ │ ├── ThymeleafDslTests.java │ │ └── WebServerDslTests.java │ │ └── webmvc │ │ ├── MustacheDslTests.java │ │ ├── ThymeleafDslTests.java │ │ └── WebServerDslTests.java │ └── resources │ ├── application.properties │ ├── junit-platform.properties │ ├── messages.properties │ ├── static │ └── test.txt │ └── templates │ ├── template.html │ └── template.mustache ├── kofu ├── README.adoc ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── org │ │ └── springframework │ │ └── fu │ │ └── kofu │ │ ├── AbstractDsl.kt │ │ ├── ApplicationDsl.kt │ │ ├── BeanDefinitionContext.kt │ │ ├── ConfigurationDsl.kt │ │ ├── Extensions.kt │ │ ├── Kofu.kt │ │ ├── KofuApplication.kt │ │ ├── LoggingDsl.kt │ │ ├── MessageSourceDsl.kt │ │ ├── cassandra │ │ ├── CassandraDsl.kt │ │ └── ReactiveCassandraDsl.kt │ │ ├── elasticsearch │ │ ├── AbstractElasticSearchDsl.kt │ │ ├── ElasticSearchDsl.kt │ │ └── ReactiveElasticSearchDsl.kt │ │ ├── jdbc │ │ ├── DataSourceType.kt │ │ └── JdbcDsl.kt │ │ ├── jooq │ │ └── JooqDsl.kt │ │ ├── mongo │ │ ├── AbstractMongoDsl.kt │ │ ├── MongoDsl.kt │ │ └── ReactiveMongoDsl.kt │ │ ├── r2dbc │ │ ├── DataR2dbcDsl.kt │ │ └── R2dbcDsl.kt │ │ ├── redis │ │ ├── AbstractRedisDsl.kt │ │ ├── JedisRedisSupporter.kt │ │ ├── LettuceRedisSupporter.kt │ │ ├── ReactiveRedisDsl.kt │ │ └── RedisDsl.kt │ │ ├── templating │ │ ├── MustacheDsl.kt │ │ └── ThymeleafDsl.kt │ │ ├── web │ │ ├── AbstractCorsDsl.kt │ │ └── JacksonDsl.kt │ │ ├── webflux │ │ ├── WebFluxClientDsl.kt │ │ ├── WebFluxCors.kt │ │ ├── WebFluxSecurityDsl.kt │ │ └── WebFluxServerDsl.kt │ │ └── webmvc │ │ ├── WebMvcCorsDsl.kt │ │ ├── WebMvcSecurityDsl.kt │ │ └── WebMvcServerDsl.kt │ └── test │ ├── java │ └── org │ │ └── springframework │ │ └── fu │ │ └── kofu │ │ └── javautils │ │ └── JavaKotlinUtils.java │ ├── kotlin │ └── org │ │ └── springframework │ │ └── fu │ │ └── kofu │ │ ├── ApplicationDslTests.kt │ │ ├── BeansDefinitionDslExtensionsTests.kt │ │ ├── ConfigurationDslTest.kt │ │ ├── ConfigurationPropertiesTests.kt │ │ ├── LoggingDslTests.kt │ │ ├── elasticsearch │ │ ├── ElasticSearchDslTest.kt │ │ └── ReactiveElasticSearchDslTest.kt │ │ ├── jdbc │ │ ├── JdbcDslTests.kt │ │ └── JdbcRepository.kt │ │ ├── jooq │ │ ├── JooqDslTest.kt │ │ └── JooqRepository.kt │ │ ├── mongo │ │ └── EmbeddedMongoDslTests.kt │ │ ├── r2dbc │ │ ├── DataR2dbcDslTest.kt │ │ ├── H2R2dbcDslTests.kt │ │ ├── PostgreSqlR2dbcDslTests.kt │ │ └── TestRepository.kt │ │ ├── redis │ │ ├── ReactiveRedisDslTests.kt │ │ └── RedisDslTests.kt │ │ ├── samples │ │ ├── application.kt │ │ ├── beans.kt │ │ ├── cassandra.kt │ │ ├── client.kt │ │ ├── cors.kt │ │ ├── dataR2dbc.kt │ │ ├── jackson.kt │ │ ├── listener.kt │ │ ├── logging.kt │ │ ├── mongodb.kt │ │ ├── mustache.kt │ │ ├── properties.kt │ │ ├── r2dbc.kt │ │ ├── redis.kt │ │ ├── thymeleaf.kt │ │ ├── webflux.kt │ │ ├── webfluxsecurity.kt │ │ ├── webmvc.kt │ │ └── webmvcsecurity.kt │ │ ├── testSecurity.kt │ │ ├── webflux │ │ ├── CorsDslTests.kt │ │ ├── JacksonDslTests.kt │ │ ├── MustacheDslTests.kt │ │ ├── ThymeleafDslTests.kt │ │ ├── WebFluxSecurityDslTests.kt │ │ └── WebFluxServerDslTests.kt │ │ └── webmvc │ │ ├── CorsDslTests.kt │ │ ├── JacksonDslTests.kt │ │ ├── MustacheDslTests.kt │ │ ├── ThymeleafDslTests.kt │ │ ├── WebMvcSecurityDslTests.kt │ │ └── WebMvcServerDslTests.kt │ └── resources │ ├── application.properties │ ├── junit-platform.properties │ ├── messages.properties │ ├── static │ └── test.txt │ └── templates │ ├── template.html │ └── template.mustache ├── samples ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jafu-reactive-data-r2dbc │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── sample │ │ │ │ ├── Application.java │ │ │ │ ├── Configurations.java │ │ │ │ ├── User.java │ │ │ │ ├── UserHandler.java │ │ │ │ └── UserRepository.java │ │ └── resources │ │ │ └── db │ │ │ └── tables.sql │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── sample │ │ │ ├── IntegrationTests.java │ │ │ └── UserRepositoryTest.java │ │ └── resources │ │ └── junit-platform.properties ├── jafu-reactive-minimal │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── sample │ │ │ │ ├── Application.java │ │ │ │ ├── Sample.java │ │ │ │ ├── SampleHandler.java │ │ │ │ └── SampleService.java │ │ └── resources │ │ │ └── static │ │ │ └── foo.css │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── sample │ │ │ └── IntegrationTests.java │ │ └── resources │ │ └── junit-platform.properties ├── jafu-reactive-mongodb │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── sample │ │ │ │ ├── Application.java │ │ │ │ ├── Configurations.java │ │ │ │ ├── SampleProperties.java │ │ │ │ ├── User.java │ │ │ │ ├── UserHandler.java │ │ │ │ └── UserRepository.java │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── data │ │ │ └── users.json │ │ │ └── templates │ │ │ ├── footer.mustache │ │ │ ├── header.mustache │ │ │ └── users.mustache │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── sample │ │ │ └── IntegrationTests.java │ │ └── resources │ │ └── junit-platform.properties ├── jafu-reactive-r2dbc │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── sample │ │ │ │ ├── Application.java │ │ │ │ ├── Configurations.java │ │ │ │ ├── User.java │ │ │ │ ├── UserHandler.java │ │ │ │ └── UserRepository.java │ │ └── resources │ │ │ └── db │ │ │ └── tables.sql │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── sample │ │ │ ├── IntegrationTests.java │ │ │ └── UserRepositoryTest.java │ │ └── resources │ │ └── junit-platform.properties ├── jafu-servlet-cassandra │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── sample │ │ │ ├── Application.java │ │ │ ├── Configurations.java │ │ │ ├── User.java │ │ │ ├── UserHandler.java │ │ │ └── UserRepository.java │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── sample │ │ │ └── IntegrationTests.java │ │ └── resources │ │ └── junit-platform.properties ├── jafu-servlet-minimal │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── sample │ │ │ │ ├── Application.java │ │ │ │ ├── Sample.java │ │ │ │ ├── SampleHandler.java │ │ │ │ └── SampleService.java │ │ └── resources │ │ │ └── static │ │ │ └── foo.css │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── sample │ │ │ └── IntegrationTests.java │ │ └── resources │ │ └── junit-platform.properties ├── kofu-coroutines-mongodb │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── kotlin │ │ │ └── org │ │ │ │ └── springframework │ │ │ │ └── fu │ │ │ │ └── sample │ │ │ │ └── coroutines │ │ │ │ ├── Application.kt │ │ │ │ ├── Configurations.kt │ │ │ │ ├── Handlers.kt │ │ │ │ ├── Model.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Repositories.kt │ │ │ │ └── Routes.kt │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── data │ │ │ └── users.json │ │ │ └── templates │ │ │ ├── footer.mustache │ │ │ ├── header.mustache │ │ │ └── users.mustache │ │ └── test │ │ ├── kotlin │ │ └── org │ │ │ └── springframework │ │ │ └── fu │ │ │ └── sample │ │ │ └── coroutines │ │ │ └── IntegrationTests.kt │ │ └── resources │ │ └── junit-platform.properties ├── kofu-coroutines-r2dbc │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── sample │ │ │ │ ├── Application.kt │ │ │ │ ├── Configurations.kt │ │ │ │ ├── Handlers.kt │ │ │ │ ├── Model.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Repositories.kt │ │ │ │ └── Routes.kt │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── db │ │ │ └── tables.sql │ │ │ └── templates │ │ │ ├── footer.mustache │ │ │ ├── header.mustache │ │ │ └── users.mustache │ │ └── test │ │ ├── kotlin │ │ └── com │ │ │ └── sample │ │ │ ├── IntegrationTests.kt │ │ │ └── UserRepositoryTests.kt │ │ └── resources │ │ └── junit-platform.properties ├── kofu-coroutines-validation │ ├── build.gradle.kts │ ├── build.sh │ ├── graal │ │ ├── app.json │ │ ├── boot.json │ │ ├── framework.json │ │ ├── log4j.json │ │ ├── netty.json │ │ └── yavi.json │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── com │ │ │ └── sample │ │ │ ├── Application.kt │ │ │ ├── Handlers.kt │ │ │ ├── Model.kt │ │ │ └── Routes.kt │ │ └── test │ │ ├── kotlin │ │ └── com │ │ │ └── sample │ │ │ └── IntegrationTests.kt │ │ └── resources │ │ └── junit-platform.properties ├── kofu-petclinic-jdbc │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ ├── MavenWrapperDownloader.java │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── docker-compose.yml │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ ├── readme.md │ └── src │ │ ├── main │ │ ├── kotlin │ │ │ └── org │ │ │ │ └── springframework │ │ │ │ └── samples │ │ │ │ └── petclinic │ │ │ │ ├── Extensions.kt │ │ │ │ ├── KofuPetClinicApplication.kt │ │ │ │ ├── owner │ │ │ │ ├── JdbcOwnerRepositoryImpl.kt │ │ │ │ ├── Owner.kt │ │ │ │ ├── OwnerConfig.kt │ │ │ │ ├── OwnerHandler.kt │ │ │ │ └── OwnerRepository.kt │ │ │ │ ├── pet │ │ │ │ ├── JdbcPetRepositoryImpl.kt │ │ │ │ ├── Pet.kt │ │ │ │ ├── PetConfig.kt │ │ │ │ ├── PetHandler.kt │ │ │ │ ├── PetRepository.kt │ │ │ │ ├── PetType.kt │ │ │ │ └── PetTypeFormatter.kt │ │ │ │ ├── system │ │ │ │ └── SystemConfig.kt │ │ │ │ ├── vet │ │ │ │ ├── JdbcVetRepositoryImpl.kt │ │ │ │ ├── Specialty.kt │ │ │ │ ├── Vet.kt │ │ │ │ ├── VetConfig.kt │ │ │ │ ├── VetRepository.kt │ │ │ │ └── Vets.kt │ │ │ │ └── visit │ │ │ │ ├── JdbcVisitRepositoryImpl.kt │ │ │ │ ├── Visit.kt │ │ │ │ ├── VisitConfig.kt │ │ │ │ ├── VisitHandler.kt │ │ │ │ └── VisitRepository.kt │ │ ├── less │ │ │ ├── header.less │ │ │ ├── petclinic.less │ │ │ ├── responsive.less │ │ │ └── typography.less │ │ ├── resources │ │ │ ├── META-INF │ │ │ │ └── native-image │ │ │ │ │ ├── reflect-config.json │ │ │ │ │ └── resource-config.json │ │ │ ├── banner.txt │ │ │ ├── db │ │ │ │ ├── h2 │ │ │ │ │ ├── data.sql │ │ │ │ │ └── schema.sql │ │ │ │ └── mysql │ │ │ │ │ ├── data.sql │ │ │ │ │ ├── schema.sql │ │ │ │ │ └── user.sql │ │ │ ├── messages │ │ │ │ ├── messages.properties │ │ │ │ ├── messages_de.properties │ │ │ │ └── messages_en.properties │ │ │ ├── static │ │ │ │ └── resources │ │ │ │ │ ├── fonts │ │ │ │ │ ├── montserrat-webfont.eot │ │ │ │ │ ├── montserrat-webfont.svg │ │ │ │ │ ├── montserrat-webfont.ttf │ │ │ │ │ ├── montserrat-webfont.woff │ │ │ │ │ ├── varela_round-webfont.eot │ │ │ │ │ ├── varela_round-webfont.svg │ │ │ │ │ ├── varela_round-webfont.ttf │ │ │ │ │ └── varela_round-webfont.woff │ │ │ │ │ └── images │ │ │ │ │ ├── favicon.png │ │ │ │ │ ├── pets.png │ │ │ │ │ ├── platform-bg.png │ │ │ │ │ ├── spring-logo-dataflow-mobile.png │ │ │ │ │ ├── spring-logo-dataflow.png │ │ │ │ │ └── spring-pivotal-logo.png │ │ │ └── templates │ │ │ │ ├── error.html │ │ │ │ ├── fragments │ │ │ │ ├── inputField.html │ │ │ │ ├── layout.html │ │ │ │ └── selectField.html │ │ │ │ ├── owners │ │ │ │ ├── createOrUpdateOwnerForm.html │ │ │ │ ├── findOwners.html │ │ │ │ ├── ownerDetails.html │ │ │ │ └── ownersList.html │ │ │ │ ├── pets │ │ │ │ ├── createOrUpdatePetForm.html │ │ │ │ └── createOrUpdateVisitForm.html │ │ │ │ ├── vets │ │ │ │ └── vetList.html │ │ │ │ └── welcome.html │ │ └── wro │ │ │ ├── wro.properties │ │ │ └── wro.xml │ │ └── test │ │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── samples │ │ │ └── petclinic │ │ │ └── KofuPetClinicApplicationTest.kt │ │ └── resources │ │ └── application-default.properties ├── kofu-reactive-cassandra │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── sample │ │ │ │ ├── Application.kt │ │ │ │ ├── Configurations.kt │ │ │ │ ├── Handlers.kt │ │ │ │ ├── Model.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Repositories.kt │ │ │ │ └── Routes.kt │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── data │ │ │ └── users.json │ │ │ ├── schema.cql │ │ │ └── templates │ │ │ ├── footer.mustache │ │ │ ├── header.mustache │ │ │ └── users.mustache │ │ └── test │ │ ├── kotlin │ │ └── com │ │ │ └── sample │ │ │ └── IntegrationTests.kt │ │ └── resources │ │ └── junit-platform.properties ├── kofu-reactive-data-r2dbc │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── sample │ │ │ │ ├── Application.kt │ │ │ │ ├── Configurations.kt │ │ │ │ ├── Handlers.kt │ │ │ │ ├── Model.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Repositories.kt │ │ │ │ └── Routes.kt │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── db │ │ │ └── tables.sql │ │ │ └── templates │ │ │ ├── footer.mustache │ │ │ ├── header.mustache │ │ │ └── users.mustache │ │ └── test │ │ ├── kotlin │ │ └── com │ │ │ └── sample │ │ │ ├── IntegrationTests.kt │ │ │ └── UserRepositoryTests.kt │ │ └── resources │ │ └── junit-platform.properties ├── kofu-reactive-minimal │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── com │ │ │ └── sample │ │ │ └── Application.kt │ │ └── test │ │ ├── kotlin │ │ └── com │ │ │ └── sample │ │ │ └── IntegrationTests.kt │ │ └── resources │ │ └── junit-platform.properties ├── kofu-reactive-mongodb │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── sample │ │ │ │ ├── Application.kt │ │ │ │ ├── Configurations.kt │ │ │ │ ├── Handlers.kt │ │ │ │ ├── Model.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Repositories.kt │ │ │ │ └── Routes.kt │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── data │ │ │ └── users.json │ │ │ └── templates │ │ │ ├── footer.mustache │ │ │ ├── header.mustache │ │ │ └── users.mustache │ │ └── test │ │ ├── kotlin │ │ └── com │ │ │ └── sample │ │ │ └── IntegrationTests.kt │ │ └── resources │ │ └── junit-platform.properties ├── kofu-reactive-r2dbc │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── sample │ │ │ │ ├── Application.kt │ │ │ │ ├── Configurations.kt │ │ │ │ ├── Handlers.kt │ │ │ │ ├── Model.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Repositories.kt │ │ │ │ └── Routes.kt │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── db │ │ │ └── tables.sql │ │ │ └── templates │ │ │ ├── footer.mustache │ │ │ ├── header.mustache │ │ │ └── users.mustache │ │ └── test │ │ ├── kotlin │ │ └── com │ │ │ └── sample │ │ │ ├── IntegrationTests.kt │ │ │ └── UserRepositoryTests.kt │ │ └── resources │ │ └── junit-platform.properties ├── kofu-reactive-redis │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── sample │ │ │ │ ├── Application.kt │ │ │ │ ├── Configurations.kt │ │ │ │ ├── Handlers.kt │ │ │ │ ├── Model.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Repositories.kt │ │ │ │ └── Routes.kt │ │ └── resources │ │ │ ├── data │ │ │ └── users.json │ │ │ └── templates │ │ │ ├── footer.mustache │ │ │ ├── header.mustache │ │ │ └── users.mustache │ │ └── test │ │ ├── kotlin │ │ └── com │ │ │ └── sample │ │ │ └── IntegrationTests.kt │ │ └── resources │ │ └── junit-platform.properties ├── kofu-reactive-validation │ ├── build.gradle.kts │ ├── build.sh │ ├── graal │ │ ├── app.json │ │ ├── boot.json │ │ ├── framework.json │ │ ├── log4j.json │ │ ├── netty.json │ │ └── yavi.json │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── com │ │ │ └── sample │ │ │ ├── Application.kt │ │ │ ├── Handlers.kt │ │ │ ├── Model.kt │ │ │ └── Routes.kt │ │ └── test │ │ ├── kotlin │ │ └── com │ │ │ └── sample │ │ │ └── IntegrationTests.kt │ │ └── resources │ │ └── junit-platform.properties ├── kofu-servlet-jooq │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── sample │ │ │ │ ├── Application.kt │ │ │ │ ├── Configurations.kt │ │ │ │ ├── Handlers.kt │ │ │ │ ├── Model.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Repositories.kt │ │ │ │ └── Routes.kt │ │ └── resources │ │ │ └── db │ │ │ └── schema.sql │ │ └── test │ │ ├── kotlin │ │ └── com │ │ │ └── sample │ │ │ └── IntegrationTests.kt │ │ └── resources │ │ └── junit-platform.properties ├── kofu-servlet-minimal │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── com │ │ │ └── sample │ │ │ └── Application.kt │ │ └── test │ │ ├── kotlin │ │ └── com │ │ │ └── sample │ │ │ └── IntegrationTests.kt │ │ └── resources │ │ └── junit-platform.properties ├── kofu-servlet-validation │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── com │ │ │ └── sample │ │ │ ├── Application.kt │ │ │ ├── Handlers.kt │ │ │ ├── Model.kt │ │ │ └── Routes.kt │ │ └── test │ │ ├── kotlin │ │ └── com │ │ │ └── sample │ │ │ └── IntegrationTests.kt │ │ └── resources │ │ └── junit-platform.properties ├── kofu-tutorial │ ├── .gitignore │ ├── README.adoc │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── images │ │ ├── blog.png │ │ ├── code_completion.png │ │ └── metadata.png │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── sample │ │ │ │ └── blog │ │ │ │ ├── BlogApplication.kt │ │ │ │ ├── BlogProperties.kt │ │ │ │ ├── JbdcHelper.kt │ │ │ │ ├── JdbcArticleRepositoryImpl.kt │ │ │ │ ├── JdbcUserRepositoryImpl.kt │ │ │ │ ├── LiquibaseProperties.kt │ │ │ │ ├── RenderedArticle.kt │ │ │ │ ├── RenderedUser.kt │ │ │ │ ├── blog.kt │ │ │ │ ├── blogApi.kt │ │ │ │ ├── entities.kt │ │ │ │ ├── extensions.kt │ │ │ │ └── repositories.kt │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── liquibase │ │ │ └── changelog-master.xml │ │ │ └── views │ │ │ ├── article.mustache │ │ │ ├── blog.mustache │ │ │ ├── footer.mustache │ │ │ └── header.mustache │ │ └── test │ │ └── kotlin │ │ └── com │ │ └── sample │ │ └── blog │ │ ├── ApiTests.kt │ │ ├── ArticleRepositoriesTests.kt │ │ ├── BlogTests.kt │ │ └── UserRepositoriesTests.kt └── settings.gradle.kts └── settings.gradle.kts /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | target/ 4 | .classpath 5 | .project 6 | .settings/ 7 | hs_err_pid* 8 | bin/ 9 | !gradle/wrapper/gradle-wrapper.jar 10 | .idea 11 | *.iws 12 | *.iml 13 | *.ipr 14 | out/ 15 | samples/kofu-reactive-minimal/com.sample.applicationkt 16 | .zip 17 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /autoconfigure-adapter/README.adoc: -------------------------------------------------------------------------------- 1 | = Spring Boot auto-configuration adapter 2 | 3 | This Java library adapts JavaConfig based `spring-boot-autoconfigure` to functional 4 | configuration based on function bean registration which is known to be faster and 5 | consumes less memory. 6 | 7 | It provides a collection of `ApplicationContextInitializer` that 8 | leverage Spring Boot auto-configurations to register the same beans but in a functional 9 | way. For now, it mostly targets the Reactive stack and conditions are not managed yet. 10 | 11 | Ideally in the future, such library should be generated during Spring Boot build based 12 | on `spring-boot-autoconfigure` classes. 13 | 14 | The dependency to use is `org.springframework.fu:spring-fu-autoconfigure-adapter`. 15 | -------------------------------------------------------------------------------- /autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceInitializer.java: -------------------------------------------------------------------------------- 1 | package org.springframework.boot.autoconfigure.context; 2 | 3 | import org.springframework.context.ApplicationContextInitializer; 4 | import org.springframework.context.MessageSource; 5 | import org.springframework.context.support.AbstractApplicationContext; 6 | import org.springframework.context.support.GenericApplicationContext; 7 | 8 | public class MessageSourceInitializer implements ApplicationContextInitializer { 9 | 10 | private final MessageSourceProperties properties; 11 | 12 | public MessageSourceInitializer() { 13 | this.properties = new MessageSourceProperties(); 14 | } 15 | 16 | public MessageSourceInitializer(MessageSourceProperties properties) { 17 | this.properties = properties; 18 | } 19 | 20 | @Override 21 | public void initialize(GenericApplicationContext context) { 22 | context.registerBean(AbstractApplicationContext.MESSAGE_SOURCE_BEAN_NAME, MessageSource.class, () -> new MessageSourceAutoConfiguration().messageSource(this.properties)); 23 | context.registerBean(MessageSourceProperties.class, () -> this.properties); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticSearchDataInitializer.java: -------------------------------------------------------------------------------- 1 | package org.springframework.boot.autoconfigure.data.elasticsearch; 2 | 3 | import org.elasticsearch.client.RestHighLevelClient; 4 | import org.springframework.context.ApplicationContextInitializer; 5 | import org.springframework.context.support.GenericApplicationContext; 6 | import org.springframework.data.elasticsearch.client.ClientConfiguration; 7 | import org.springframework.data.elasticsearch.client.RestClients; 8 | 9 | public class ElasticSearchDataInitializer implements ApplicationContextInitializer { 10 | 11 | private final ClientConfiguration clientConfiguration; 12 | 13 | public ElasticSearchDataInitializer(ClientConfiguration clientConfiguration) { 14 | this.clientConfiguration = clientConfiguration; 15 | } 16 | 17 | @Override 18 | public void initialize(GenericApplicationContext context) { 19 | context.registerBean(RestHighLevelClient.class, () -> RestClients.create(clientConfiguration).rest()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticSearchDataInitializer.java: -------------------------------------------------------------------------------- 1 | package org.springframework.boot.autoconfigure.data.elasticsearch; 2 | 3 | import org.springframework.context.ApplicationContextInitializer; 4 | import org.springframework.context.support.GenericApplicationContext; 5 | import org.springframework.data.elasticsearch.client.ClientConfiguration; 6 | import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; 7 | import org.springframework.data.elasticsearch.client.reactive.ReactiveRestClients; 8 | 9 | public class ReactiveElasticSearchDataInitializer implements ApplicationContextInitializer { 10 | 11 | private final ClientConfiguration clientConfiguration; 12 | 13 | public ReactiveElasticSearchDataInitializer(ClientConfiguration clientConfiguration) { 14 | this.clientConfiguration = clientConfiguration; 15 | } 16 | 17 | @Override 18 | public void initialize(GenericApplicationContext context) { 19 | context.registerBean(ReactiveElasticsearchClient.class, () -> ReactiveRestClients.create(clientConfiguration)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDataSourceConfigurationInitializer.java: -------------------------------------------------------------------------------- 1 | package org.springframework.boot.autoconfigure.jdbc; 2 | 3 | import org.springframework.context.ApplicationContextInitializer; 4 | import org.springframework.context.support.GenericApplicationContext; 5 | import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; 6 | 7 | public class EmbeddedDataSourceConfigurationInitializer implements ApplicationContextInitializer { 8 | 9 | private final DataSourceProperties dataSourceProperties; 10 | 11 | public EmbeddedDataSourceConfigurationInitializer(DataSourceProperties dataSourceProperties) { 12 | this.dataSourceProperties = dataSourceProperties; 13 | } 14 | 15 | @Override 16 | public void initialize(GenericApplicationContext context) { 17 | if (context.getBeanFactory().getBeanNamesForType(EmbeddedDataSourceConfiguration.class).length == 0) { 18 | context.registerBean("dataSource", EmbeddedDatabase.class, () -> new EmbeddedDataSourceConfiguration().dataSource(this.dataSourceProperties), def -> def.setDestroyMethodName("shutdown")); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateConfigurationInitializer.java: -------------------------------------------------------------------------------- 1 | package org.springframework.boot.autoconfigure.jdbc; 2 | 3 | import java.lang.Override; 4 | import javax.sql.DataSource; 5 | import org.springframework.context.ApplicationContextInitializer; 6 | import org.springframework.context.support.GenericApplicationContext; 7 | import org.springframework.jdbc.core.JdbcTemplate; 8 | 9 | public class JdbcTemplateConfigurationInitializer implements ApplicationContextInitializer { 10 | 11 | private final JdbcProperties jdbcProperties; 12 | 13 | public JdbcTemplateConfigurationInitializer(JdbcProperties jdbcProperties) { 14 | this.jdbcProperties = jdbcProperties; 15 | } 16 | 17 | @Override 18 | public void initialize(GenericApplicationContext context) { 19 | if (context.getBeanFactory().getBeanNamesForType(JdbcTemplateConfiguration.class).length == 0) { 20 | context.registerBean("JdbcTemplate", JdbcTemplate.class, () -> new JdbcTemplateConfiguration().jdbcTemplate(context.getBean(DataSource.class), jdbcProperties)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/web/servlet/AtomConverterInitializer.java: -------------------------------------------------------------------------------- 1 | package org.springframework.boot.autoconfigure.web.servlet; 2 | 3 | import org.springframework.context.ApplicationContextInitializer; 4 | import org.springframework.context.support.GenericApplicationContext; 5 | import org.springframework.http.converter.HttpMessageConverter; 6 | import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter; 7 | 8 | public class AtomConverterInitializer implements ApplicationContextInitializer { 9 | 10 | @Override 11 | public void initialize(GenericApplicationContext context) { 12 | context.registerBean("atomFeedHttpMessageConverter", HttpMessageConverter.class, AtomFeedHttpMessageConverter::new); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/web/servlet/FormConverterInitializer.java: -------------------------------------------------------------------------------- 1 | package org.springframework.boot.autoconfigure.web.servlet; 2 | 3 | import org.springframework.context.ApplicationContextInitializer; 4 | import org.springframework.context.support.GenericApplicationContext; 5 | import org.springframework.http.converter.HttpMessageConverter; 6 | import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; 7 | 8 | public class FormConverterInitializer implements ApplicationContextInitializer { 9 | 10 | @Override 11 | public void initialize(GenericApplicationContext context) { 12 | context.registerBean("allEncompassingFormHttpMessageConverter", HttpMessageConverter.class, AllEncompassingFormHttpMessageConverter::new); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/web/servlet/JacksonJsonConverterInitializer.java: -------------------------------------------------------------------------------- 1 | package org.springframework.boot.autoconfigure.web.servlet; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | 5 | import org.springframework.context.ApplicationContextInitializer; 6 | import org.springframework.context.support.GenericApplicationContext; 7 | import org.springframework.http.converter.HttpMessageConverter; 8 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; 9 | 10 | public class JacksonJsonConverterInitializer implements ApplicationContextInitializer { 11 | 12 | @Override 13 | public void initialize(GenericApplicationContext context) { 14 | context.registerBean("mappingJackson2HttpMessageConverter", HttpMessageConverter.class, () -> new MappingJackson2HttpMessageConverter(context.getBean(ObjectMapper.class))); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ResourceConverterInitializer.java: -------------------------------------------------------------------------------- 1 | package org.springframework.boot.autoconfigure.web.servlet; 2 | 3 | import java.util.function.Supplier; 4 | 5 | import org.springframework.context.ApplicationContextInitializer; 6 | import org.springframework.context.support.GenericApplicationContext; 7 | import org.springframework.http.converter.HttpMessageConverter; 8 | import org.springframework.http.converter.ResourceHttpMessageConverter; 9 | import org.springframework.http.converter.ResourceRegionHttpMessageConverter; 10 | 11 | public class ResourceConverterInitializer implements ApplicationContextInitializer { 12 | 13 | @Override 14 | public void initialize(GenericApplicationContext context) { 15 | context.registerBean("resourceHttpMessageConverter", HttpMessageConverter.class, (Supplier) ResourceHttpMessageConverter::new); 16 | context.registerBean("resourceRegionHttpMessageConverter", HttpMessageConverter.class, ResourceRegionHttpMessageConverter::new); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/web/servlet/RssConverterInitializer.java: -------------------------------------------------------------------------------- 1 | package org.springframework.boot.autoconfigure.web.servlet; 2 | 3 | import org.springframework.context.ApplicationContextInitializer; 4 | import org.springframework.context.support.GenericApplicationContext; 5 | import org.springframework.http.converter.HttpMessageConverter; 6 | import org.springframework.http.converter.feed.RssChannelHttpMessageConverter; 7 | 8 | public class RssConverterInitializer implements ApplicationContextInitializer { 9 | 10 | @Override 11 | public void initialize(GenericApplicationContext context) { 12 | context.registerBean("rssChannelHttpMessageConverter", HttpMessageConverter.class, RssChannelHttpMessageConverter::new); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /autoconfigure-adapter/src/main/java/org/springframework/security/config/annotation/web/configuration/ObjectPostProcessorInitializer.java: -------------------------------------------------------------------------------- 1 | package org.springframework.security.config.annotation.web.configuration; 2 | 3 | import org.springframework.context.ApplicationContextInitializer; 4 | import org.springframework.context.support.GenericApplicationContext; 5 | import org.springframework.security.config.annotation.ObjectPostProcessor; 6 | import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration; 7 | 8 | /** 9 | * {@link ApplicationContextInitializer} adapter for {@link ObjectPostProcessorConfiguration}. 10 | */ 11 | public class ObjectPostProcessorInitializer implements ApplicationContextInitializer { 12 | 13 | @Override 14 | public void initialize(GenericApplicationContext context) { 15 | ObjectPostProcessorConfiguration configuration = new ObjectPostProcessorConfiguration(); 16 | context.registerBean(ObjectPostProcessor.class, () -> configuration.objectPostProcessor(context.getBeanFactory())); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /autoconfigure-adapter/src/main/java/org/springframework/security/config/annotation/web/configuration/WebMvcSecurityInitializer.java: -------------------------------------------------------------------------------- 1 | package org.springframework.security.config.annotation.web.configuration; 2 | 3 | import org.springframework.context.ApplicationContextInitializer; 4 | import org.springframework.context.support.GenericApplicationContext; 5 | import org.springframework.web.servlet.support.RequestDataValueProcessor; 6 | 7 | import java.util.function.Supplier; 8 | 9 | /** 10 | * {@link ApplicationContextInitializer} adapter for {@link WebMvcSecurityConfiguration}. 11 | */ 12 | public class WebMvcSecurityInitializer implements ApplicationContextInitializer { 13 | 14 | @Override 15 | public void initialize(GenericApplicationContext context) { 16 | Supplier configurationSupplier = () -> { 17 | final WebMvcSecurityConfiguration configuration = new WebMvcSecurityConfiguration(); 18 | configuration.setApplicationContext(context); 19 | return configuration; 20 | }; 21 | 22 | context.registerBean(RequestDataValueProcessor.class, () -> configurationSupplier.get().requestDataValueProcessor()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | ./gradlew -x javadoc -x dokkaHtml build publishToMavenLocal 6 | cd samples 7 | ./gradlew build 8 | cd kofu-petclinic-jdbc 9 | ./mvnw package -------------------------------------------------------------------------------- /ci/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -e 4 | 5 | export GRADLE_OPTS=-Dorg.gradle.native=false 6 | cd spring-fu 7 | ./gradlew build publishToMavenLocal -PisCI=true 8 | cd samples 9 | ./gradlew build -PisCI=true 10 | -------------------------------------------------------------------------------- /ci/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -e 4 | 5 | export GRADLE_OPTS=-Dorg.gradle.native=false 6 | cd spring-fu 7 | ./gradlew -q -PrepoUsername=$ARTIFACTORY_USERNAME -PrepoPassword=$ARTIFACTORY_PASSWORD dokkaHtml publish 8 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | bootVersion=2.6.6 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /jafu/src/main/java/org/springframework/fu/jafu/ApplicationDsl.java: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.jafu; 2 | 3 | import java.util.function.Consumer; 4 | 5 | import org.springframework.boot.autoconfigure.context.MessageSourceInitializer; 6 | import org.springframework.context.support.GenericApplicationContext; 7 | 8 | /** 9 | * Jafu top level DSL for application which allows to configure a Spring Boot 10 | * application using Jafu and functional bean registration. 11 | * 12 | * @author Sebastien Deleuze 13 | * @see org.springframework.fu.jafu.Jafu#application 14 | */ 15 | public class ApplicationDsl extends ConfigurationDsl { 16 | 17 | private final Consumer dsl; 18 | 19 | ApplicationDsl(Consumer dsl) { 20 | super(configurationDsl -> {}); 21 | this.dsl = dsl; 22 | } 23 | 24 | @Override 25 | public void initialize(GenericApplicationContext context) { 26 | super.initialize(context); 27 | this.dsl.accept(this); 28 | new MessageSourceInitializer().initialize(context); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /jafu/src/main/java/org/springframework/fu/jafu/mongo/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Jafu MongoDB DSL 3 | */ 4 | package org.springframework.fu.jafu.mongo; -------------------------------------------------------------------------------- /jafu/src/main/java/org/springframework/fu/jafu/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Jafu DSL for Spring Boot 3 | */ 4 | package org.springframework.fu.jafu; -------------------------------------------------------------------------------- /jafu/src/main/java/org/springframework/fu/jafu/r2dbc/DataR2dbcDsl.java: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.jafu.r2dbc; 2 | 3 | import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataInitializer; 4 | import org.springframework.context.ApplicationContextInitializer; 5 | import org.springframework.context.support.GenericApplicationContext; 6 | import org.springframework.fu.jafu.AbstractDsl; 7 | 8 | import java.util.function.Consumer; 9 | 10 | public class DataR2dbcDsl extends AbstractDsl { 11 | 12 | private final Consumer dsl; 13 | 14 | public DataR2dbcDsl(Consumer dsl) { 15 | this.dsl = dsl; 16 | } 17 | 18 | public static ApplicationContextInitializer dataR2dbc(Consumer dsl) { 19 | return new DataR2dbcDsl(dsl); 20 | } 21 | 22 | public DataR2dbcDsl r2dbc(Consumer r2dbcDsl) { 23 | new R2dbcDsl(r2dbcDsl).initialize(context); 24 | return this; 25 | } 26 | 27 | @Override 28 | public void initialize(GenericApplicationContext context) { 29 | super.initialize(context); 30 | dsl.accept(this); 31 | new R2dbcDataInitializer().initialize(context); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jafu/src/main/java/org/springframework/fu/jafu/webflux/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Jafu webflux webClient and webFlux DSL 3 | */ 4 | package org.springframework.fu.jafu.webflux; -------------------------------------------------------------------------------- /jafu/src/test/java/org/springframework/fu/jafu/jdbc/JdbcDslTests.java: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.jafu.jdbc; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.wildfly.common.Assert; 5 | 6 | import org.springframework.jdbc.core.JdbcTemplate; 7 | 8 | import static org.springframework.fu.jafu.Jafu.application; 9 | import static org.springframework.fu.jafu.jdbc.JdbcDsl.*; 10 | 11 | public class JdbcDslTests { 12 | 13 | @Test 14 | public void enableJdbc() { 15 | var app = application(a -> a.enable(jdbc())); 16 | var context = app.run(); 17 | Assert.assertNotNull(context.getBean(JdbcTemplate.class)); 18 | context.close(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /jafu/src/test/java/org/springframework/fu/jafu/redis/TestUser.java: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.jafu.redis; 2 | 3 | import java.io.Serializable; 4 | 5 | public class TestUser implements Serializable { 6 | 7 | private final String id; 8 | private final String name; 9 | 10 | public TestUser(String id, String name) { 11 | this.id = id; 12 | this.name = name; 13 | } 14 | 15 | public String getId() { 16 | return id; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /jafu/src/test/java/org/springframework/fu/jafu/webflux/MustacheDslTests.java: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.jafu.webflux; 2 | 3 | import static org.springframework.fu.jafu.Jafu.reactiveWebApplication; 4 | import static org.springframework.fu.jafu.webflux.WebFluxServerDsl.webFlux; 5 | import static org.springframework.web.reactive.function.server.ServerResponse.ok; 6 | 7 | import java.util.Collections; 8 | 9 | import org.junit.jupiter.api.Test; 10 | 11 | import org.springframework.test.web.reactive.server.WebTestClient; 12 | 13 | public class MustacheDslTests { 14 | 15 | @Test 16 | void createAndRequestAMustacheView() { 17 | var app = reactiveWebApplication(a -> a.enable(webFlux(s -> s.port(0).mustache().router(r -> r.GET("/view", request -> ok().render("template", Collections.singletonMap("name", "world"))))))); 18 | 19 | var context = app.run(); 20 | var port = context.getEnvironment().getProperty("local.server.port"); 21 | var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:" + port).build(); 22 | client.get().uri("/view").exchange() 23 | .expectStatus().is2xxSuccessful() 24 | .expectBody(String.class) 25 | .isEqualTo("Hello world!"); 26 | context.close(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /jafu/src/test/java/org/springframework/fu/jafu/webflux/ThymeleafDslTests.java: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.jafu.webflux; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.test.web.reactive.server.WebTestClient; 5 | 6 | import java.util.Collections; 7 | 8 | import static org.springframework.fu.jafu.Jafu.reactiveWebApplication; 9 | import static org.springframework.fu.jafu.webflux.WebFluxServerDsl.webFlux; 10 | import static org.springframework.web.reactive.function.server.ServerResponse.ok; 11 | 12 | public class ThymeleafDslTests { 13 | 14 | @Test 15 | void createAndRequestAThymeleafView() { 16 | var app = reactiveWebApplication(a -> a.enable(webFlux(s -> s.port(0).thymeleaf().router(r -> r.GET("/view", request -> ok().render("template", Collections.singletonMap("name", "world"))))))); 17 | 18 | var context = app.run(); 19 | var port = context.getEnvironment().getProperty("local.server.port"); 20 | var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:" + port).build(); 21 | client.get().uri("/view").exchange() 22 | .expectStatus().is2xxSuccessful() 23 | .expectBody(String.class) 24 | .isEqualTo("

Hello world!

"); 25 | context.close(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jafu/src/test/java/org/springframework/fu/jafu/webmvc/MustacheDslTests.java: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.jafu.webmvc; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.test.web.reactive.server.WebTestClient; 5 | 6 | import java.util.Collections; 7 | 8 | import static org.springframework.fu.jafu.Jafu.webApplication; 9 | import static org.springframework.fu.jafu.webmvc.WebMvcServerDsl.webMvc; 10 | import static org.springframework.web.servlet.function.ServerResponse.ok; 11 | 12 | public class MustacheDslTests { 13 | 14 | @Test 15 | void createAndRequestAMustacheView() { 16 | var app = webApplication(a -> a.enable( 17 | webMvc( 18 | s -> s.port(0).mustache().router( 19 | r -> r.GET("/view", request -> ok().render("template", Collections.singletonMap("name", "world"))))))); 20 | 21 | var context = app.run(); 22 | var port = context.getEnvironment().getProperty("local.server.port"); 23 | var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:" + port).build(); 24 | client.get().uri("/view").exchange() 25 | .expectStatus().is2xxSuccessful() 26 | .expectBody(String.class) 27 | .isEqualTo("Hello world!"); 28 | context.close(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /jafu/src/test/java/org/springframework/fu/jafu/webmvc/ThymeleafDslTests.java: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.jafu.webmvc; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.test.web.reactive.server.WebTestClient; 5 | 6 | import java.util.Collections; 7 | 8 | import static org.springframework.fu.jafu.Jafu.webApplication; 9 | import static org.springframework.fu.jafu.webmvc.WebMvcServerDsl.webMvc; 10 | import static org.springframework.web.servlet.function.ServerResponse.ok; 11 | 12 | public class ThymeleafDslTests { 13 | 14 | @Test 15 | void createAndRequestAThymeleafView() { 16 | var app = webApplication(a -> a.enable( 17 | webMvc( 18 | s -> s.port(0).thymeleaf().router( 19 | r -> r.GET("/view", request -> ok().render("template", Collections.singletonMap("name", "world"))))))); 20 | 21 | var context = app.run(); 22 | var port = context.getEnvironment().getProperty("local.server.port"); 23 | var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:" + port).build(); 24 | client.get().uri("/view").exchange() 25 | .expectStatus().is2xxSuccessful() 26 | .expectBody(String.class) 27 | .isEqualTo("

Hello world!

"); 28 | context.close(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /jafu/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | city.name=San Francisco 2 | city.country=USA 3 | -------------------------------------------------------------------------------- /jafu/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /jafu/src/test/resources/messages.properties: -------------------------------------------------------------------------------- 1 | sample.message=Spring Fu! -------------------------------------------------------------------------------- /jafu/src/test/resources/static/test.txt: -------------------------------------------------------------------------------- 1 | Test -------------------------------------------------------------------------------- /jafu/src/test/resources/templates/template.html: -------------------------------------------------------------------------------- 1 |

-------------------------------------------------------------------------------- /jafu/src/test/resources/templates/template.mustache: -------------------------------------------------------------------------------- 1 | Hello {{name}}! -------------------------------------------------------------------------------- /kofu/src/main/kotlin/org/springframework/fu/kofu/Extensions.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu 2 | 3 | import org.springframework.context.ApplicationContext 4 | import org.springframework.core.env.get 5 | 6 | /** 7 | * Shortcut for `environment["local.server.port"]`. 8 | */ 9 | val ApplicationContext.localServerPort: String 10 | get() = environment["local.server.port"]!! -------------------------------------------------------------------------------- /kofu/src/main/kotlin/org/springframework/fu/kofu/MessageSourceDsl.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu 2 | 3 | import org.springframework.boot.autoconfigure.context.MessageSourceInitializer 4 | import org.springframework.boot.autoconfigure.context.MessageSourceProperties 5 | import org.springframework.context.support.GenericApplicationContext 6 | 7 | class MessageSourceDsl(private val init: MessageSourceDsl.() -> Unit) : AbstractDsl() { 8 | 9 | var basename = "messages" 10 | 11 | override fun initialize(context: GenericApplicationContext) { 12 | super.initialize(context) 13 | init() 14 | 15 | val messageSourceProperties = MessageSourceProperties().apply { 16 | basename = this@MessageSourceDsl.basename 17 | } 18 | MessageSourceInitializer(messageSourceProperties).initialize(context) 19 | } 20 | } 21 | 22 | /** 23 | * Configure MessageSource support. 24 | * @see MessageSourceDsl 25 | */ 26 | fun ConfigurationDsl.messageSource(dsl: MessageSourceDsl.() -> Unit = {}) { 27 | MessageSourceDsl(dsl).initialize(context) 28 | } -------------------------------------------------------------------------------- /kofu/src/main/kotlin/org/springframework/fu/kofu/elasticsearch/AbstractElasticSearchDsl.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.elasticsearch 2 | 3 | import org.springframework.data.elasticsearch.client.ClientConfiguration 4 | import org.springframework.fu.kofu.AbstractDsl 5 | 6 | abstract class AbstractElasticSearchDsl: AbstractDsl() { 7 | 8 | var hostAndPort: String? = null 9 | var usingSsl: Boolean = false 10 | 11 | protected fun createClientConfiguration() = 12 | ClientConfiguration.builder() 13 | .let { 14 | if (hostAndPort != null) it.connectedTo(hostAndPort) 15 | else it.connectedToLocalhost() 16 | } 17 | .let { 18 | if (usingSsl) it.usingSsl() 19 | else it 20 | }.build() 21 | } -------------------------------------------------------------------------------- /kofu/src/main/kotlin/org/springframework/fu/kofu/elasticsearch/ElasticSearchDsl.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.elasticsearch 2 | 3 | import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticSearchDataInitializer 4 | import org.springframework.context.support.GenericApplicationContext 5 | import org.springframework.data.elasticsearch.client.ClientConfiguration 6 | import org.springframework.fu.kofu.AbstractDsl 7 | import org.springframework.fu.kofu.ConfigurationDsl 8 | 9 | class ElasticSearchDsl(private val dsl: ElasticSearchDsl.() -> Unit): AbstractElasticSearchDsl() { 10 | 11 | override fun initialize(context: GenericApplicationContext) { 12 | super.initialize(context) 13 | apply(dsl) 14 | ElasticSearchDataInitializer(createClientConfiguration()).initialize(context) 15 | } 16 | } 17 | 18 | fun ConfigurationDsl.elasticSearch(dsl: ElasticSearchDsl.() -> Unit) { 19 | ElasticSearchDsl(dsl).initialize(context) 20 | } -------------------------------------------------------------------------------- /kofu/src/main/kotlin/org/springframework/fu/kofu/elasticsearch/ReactiveElasticSearchDsl.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.elasticsearch 2 | 3 | import org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticSearchDataInitializer 4 | import org.springframework.context.support.GenericApplicationContext 5 | import org.springframework.fu.kofu.ConfigurationDsl 6 | 7 | class ReactiveElasticSearchDsl(private val dsl: ReactiveElasticSearchDsl.() -> Unit): AbstractElasticSearchDsl() { 8 | override fun initialize(context: GenericApplicationContext) { 9 | super.initialize(context) 10 | apply(dsl) 11 | ReactiveElasticSearchDataInitializer(createClientConfiguration()).initialize(context) 12 | } 13 | } 14 | 15 | fun ConfigurationDsl.reactiveElasticSearch(dsl: ReactiveElasticSearchDsl.() -> Unit) { 16 | ReactiveElasticSearchDsl(dsl).initialize(context) 17 | } -------------------------------------------------------------------------------- /kofu/src/main/kotlin/org/springframework/fu/kofu/jdbc/DataSourceType.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.jdbc 2 | 3 | enum class DataSourceType { 4 | Hikari, Embedded, Generic 5 | } -------------------------------------------------------------------------------- /kofu/src/main/kotlin/org/springframework/fu/kofu/r2dbc/DataR2dbcDsl.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.r2dbc 2 | 3 | import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataInitializer 4 | import org.springframework.context.support.GenericApplicationContext 5 | import org.springframework.fu.kofu.AbstractDsl 6 | import org.springframework.fu.kofu.ConfigurationDsl 7 | 8 | class DataR2dbcDsl(private val init: DataR2dbcDsl.() -> Unit) : AbstractDsl() { 9 | 10 | override fun initialize(context: GenericApplicationContext) { 11 | super.initialize(context) 12 | init() 13 | R2dbcDataInitializer().initialize(context) 14 | } 15 | } 16 | 17 | /** 18 | * Configure R2DBC support. 19 | * @see R2dbcDsl 20 | */ 21 | fun ConfigurationDsl.dataR2dbc(r2dbcDsl: DataR2dbcDsl.() -> Unit = {}) { 22 | DataR2dbcDsl(r2dbcDsl).initialize(context) 23 | } -------------------------------------------------------------------------------- /kofu/src/main/kotlin/org/springframework/fu/kofu/redis/JedisRedisSupporter.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.redis 2 | 3 | import org.springframework.boot.autoconfigure.data.redis.RedisProperties 4 | import org.springframework.context.support.GenericApplicationContext 5 | 6 | interface JedisRedisSupporter { 7 | /** 8 | * Configure the jedis client properties via a [dedicated DSL][PoolDsl]. 9 | */ 10 | fun jedis(dsl: PoolDsl.() -> Unit = {}) 11 | } 12 | 13 | /** 14 | * Configure the jedis client properties 15 | * 16 | * @author Waldemar Panas 17 | */ 18 | class JedisDsl(redisProperties: RedisProperties, private val init: PoolDsl.() -> Unit) : PoolDsl(redisProperties.jedis.pool, init) { 19 | override fun initialize(context: GenericApplicationContext) { 20 | super.initialize(context) 21 | init() 22 | } 23 | } -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/beans.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.samples 2 | 3 | import org.springframework.fu.kofu.application 4 | 5 | private fun beansDsl() { 6 | application { 7 | beans { 8 | bean() 9 | bean() 10 | bean() 11 | bean() 12 | } 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/client.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.samples 2 | 3 | import org.springframework.fu.kofu.application 4 | import org.springframework.fu.kofu.webflux.webClient 5 | 6 | fun clientDsl() { 7 | application { 8 | webClient { 9 | codecs { 10 | string() 11 | jackson() 12 | resource() 13 | protobuf() 14 | form() 15 | multipart() 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/cors.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.samples 2 | 3 | import org.springframework.fu.kofu.application 4 | import org.springframework.fu.kofu.webflux.cors 5 | import org.springframework.fu.kofu.webflux.webFlux 6 | 7 | fun corsDsl() { 8 | application { 9 | webFlux { 10 | cors { 11 | "/api/**" { 12 | allowedOrigins = listOf("first.example.com", "second.example.com") 13 | allowedMethods = listOf("GET", "PUT", "POST", "DELETE") 14 | } 15 | "/static/**" { 16 | allowedOrigins = listOf("full.config.example.com") 17 | allowedMethods = listOf("GET") 18 | allowedHeaders = listOf("*") 19 | exposedHeaders = listOf("Content-Location") 20 | allowCredentials = true 21 | maxAge = 3600 22 | } 23 | path("/public/**") // Enable CORS with permit default values 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/dataR2dbc.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.samples 2 | 3 | import org.springframework.fu.kofu.application 4 | import org.springframework.fu.kofu.r2dbc.dataR2dbc 5 | import org.springframework.fu.kofu.r2dbc.r2dbc 6 | 7 | fun dataR2dbcPostgresql() { 8 | application { 9 | dataR2dbc { 10 | r2dbc { 11 | url = "r2dbc:postgresql://dbserver:1234" 12 | } 13 | } 14 | } 15 | } 16 | 17 | fun dataR2dbc() { 18 | application { 19 | dataR2dbc { 20 | r2dbc { 21 | url = "r2dbc:postgresql://localhost/test" 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/jackson.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.samples 2 | 3 | import org.springframework.fu.kofu.application 4 | import org.springframework.fu.kofu.webflux.webClient 5 | import org.springframework.fu.kofu.webflux.webFlux 6 | 7 | fun jacksonDsl() { 8 | application { 9 | webFlux { 10 | codecs { 11 | jackson() 12 | } 13 | } 14 | webClient { 15 | codecs { 16 | jackson() 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/listener.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.samples 2 | 3 | import org.springframework.boot.context.event.ApplicationReadyEvent 4 | import org.springframework.fu.kofu.application 5 | 6 | fun listener() { 7 | application { 8 | listener { 9 | ref().init() 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/logging.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.samples 2 | 3 | import org.springframework.boot.logging.LogLevel 4 | import org.springframework.fu.kofu.application 5 | 6 | private fun loggingDsl() { 7 | application { 8 | logging { 9 | level = LogLevel.INFO 10 | level("org.springframework", LogLevel.DEBUG) 11 | level(LogLevel.WARN) 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/mongodb.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.samples 2 | 3 | import de.flapdoodle.embed.mongo.distribution.Version 4 | import org.springframework.fu.kofu.application 5 | import org.springframework.fu.kofu.mongo.reactiveMongodb 6 | 7 | fun mongo() { 8 | application { 9 | reactiveMongodb { 10 | uri = "mongodb://myserver.com/foo" 11 | } 12 | } 13 | } 14 | 15 | fun mongoEmbedded() { 16 | application { 17 | reactiveMongodb { 18 | uri = "mongodb://myserver.com/foo" 19 | embedded(version = Version.Main.PRODUCTION) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/mustache.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.samples 2 | 3 | import org.springframework.fu.kofu.reactiveWebApplication 4 | import org.springframework.fu.kofu.templating.mustache 5 | import org.springframework.fu.kofu.webflux.webFlux 6 | 7 | fun mustacheDsl() { 8 | reactiveWebApplication { 9 | webFlux { 10 | mustache() 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/properties.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("UNUSED_VARIABLE") 2 | 3 | package org.springframework.fu.kofu.samples 4 | 5 | import org.springframework.fu.kofu.application 6 | 7 | fun configurationProperties() { 8 | application { 9 | 10 | /** Bind `sample.message` property typically defined in an `application.properties` 11 | * or `application.yml` file to [SampleProperties.message]. Typically used by retrieving 12 | * a [SampleProperties] bean. 13 | */ 14 | val properties = configurationProperties(prefix = "sample") 15 | 16 | } 17 | } 18 | 19 | class SampleProperties(val message: String) -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/r2dbc.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.samples 2 | 3 | import org.springframework.fu.kofu.application 4 | import org.springframework.fu.kofu.r2dbc.r2dbc 5 | 6 | fun r2dbcPostgresql() { 7 | application { 8 | r2dbc { 9 | url = "r2dbc:postgresql://dbserver:1234" 10 | } 11 | } 12 | } 13 | 14 | fun r2dbc(){ 15 | application { 16 | r2dbc { 17 | url = "r2dbc:postgresql://localhost/test" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/redis.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.samples 2 | 3 | import org.springframework.fu.kofu.application 4 | import org.springframework.fu.kofu.redis.redis 5 | import java.time.Duration 6 | 7 | fun jedis() { 8 | application { 9 | redis { 10 | password = "password" 11 | jedis { 12 | maxActive = 7 13 | maxIdle = 7 14 | minIdle = 2 15 | maxWait = Duration.ofMillis(-1) 16 | } 17 | cluster { 18 | node("localhost", 1234) 19 | node("localhost", 1235) 20 | node("localhost", 1236) 21 | maxRedirects = 2 22 | } 23 | } 24 | } 25 | } 26 | 27 | fun lettuce() { 28 | application { 29 | redis { 30 | host = "localhost" 31 | port = 6789 32 | password = "password" 33 | timeout = Duration.ofMillis(100) 34 | ssl = true 35 | lettuce { 36 | shutdownTimeout = Duration.ofMillis(100) 37 | pool { 38 | maxActive = 7 39 | maxIdle = 7 40 | minIdle = 2 41 | maxWait = Duration.ofMillis(-1) 42 | } 43 | } 44 | sentinel { 45 | master = "mymaster" 46 | node("localhost", 1234) 47 | node("localhost", 1235) 48 | node("localhost", 1236) 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/thymeleaf.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.samples 2 | 3 | import org.springframework.fu.kofu.webApplication 4 | import org.springframework.fu.kofu.templating.thymeleaf 5 | import org.springframework.fu.kofu.webflux.webFlux 6 | 7 | fun thymeleafDsl() { 8 | webApplication { 9 | webFlux { 10 | thymeleaf() 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /kofu/src/test/kotlin/org/springframework/fu/kofu/samples/webmvcsecurity.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.kofu.samples 2 | 3 | import org.springframework.fu.kofu.webApplication 4 | import org.springframework.fu.kofu.webmvc.security 5 | import org.springframework.fu.kofu.webmvc.webMvc 6 | import org.springframework.security.core.userdetails.User 7 | import org.springframework.security.provisioning.InMemoryUserDetailsManager 8 | 9 | fun webMvcSecurity() { 10 | webApplication { 11 | webMvc { 12 | security { 13 | userDetailsService = userDetailsService() 14 | http { 15 | anonymous { } 16 | authorizeRequests { 17 | authorize("/view", hasRole("USER")) 18 | authorize("/public-view", permitAll) 19 | } 20 | headers {} 21 | logout {} 22 | } 23 | } 24 | } 25 | } 26 | } 27 | 28 | private fun userDetailsService() = 29 | InMemoryUserDetailsManager( 30 | @Suppress("DEPRECATION") 31 | User.withDefaultPasswordEncoder() 32 | .username("username") 33 | .password("password") 34 | .roles("USER") 35 | .build() 36 | ) 37 | -------------------------------------------------------------------------------- /kofu/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | city.name=San Francisco 2 | city.country=USA 3 | 4 | withdefaultvalue.name=Paris 5 | -------------------------------------------------------------------------------- /kofu/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /kofu/src/test/resources/messages.properties: -------------------------------------------------------------------------------- 1 | sample.message=Spring Fu! -------------------------------------------------------------------------------- /kofu/src/test/resources/static/test.txt: -------------------------------------------------------------------------------- 1 | Test -------------------------------------------------------------------------------- /kofu/src/test/resources/templates/template.html: -------------------------------------------------------------------------------- 1 |

-------------------------------------------------------------------------------- /kofu/src/test/resources/templates/template.mustache: -------------------------------------------------------------------------------- 1 | Hello {{name}}! -------------------------------------------------------------------------------- /samples/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/jafu-reactive-data-r2dbc/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 3 | id("org.springframework.boot") version "2.6.6" 4 | id("java") 5 | } 6 | 7 | java { 8 | sourceCompatibility = JavaVersion.VERSION_11 9 | targetCompatibility = JavaVersion.VERSION_11 10 | } 11 | 12 | dependencies { 13 | implementation("org.springframework.fu:spring-fu-jafu:0.5.2-SNAPSHOT") 14 | 15 | implementation("org.springframework.boot:spring-boot-starter-webflux") 16 | implementation("org.springframework.boot:spring-boot-starter-mustache") 17 | implementation("org.springframework.boot:spring-boot-starter-data-r2dbc") 18 | implementation("io.r2dbc:r2dbc-h2") 19 | 20 | testImplementation("org.springframework.boot:spring-boot-starter-test") 21 | } 22 | 23 | repositories { 24 | mavenLocal() 25 | mavenCentral() 26 | maven("https://repo.spring.io/milestone") 27 | maven("https://repo.spring.io/snapshot") 28 | } 29 | 30 | tasks.withType { 31 | useJUnitPlatform() 32 | } 33 | -------------------------------------------------------------------------------- /samples/jafu-reactive-data-r2dbc/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/jafu-reactive-data-r2dbc/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/jafu-reactive-data-r2dbc/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/jafu-reactive-data-r2dbc/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/jafu-reactive-data-r2dbc/src/main/java/com/sample/Application.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | import org.springframework.fu.jafu.JafuApplication; 4 | 5 | import static org.springframework.fu.jafu.Jafu.reactiveWebApplication; 6 | 7 | public abstract class Application { 8 | 9 | public static JafuApplication app = reactiveWebApplication(app -> app 10 | .enable(Configurations.dataConfig) 11 | .enable(Configurations.webConfig)); 12 | 13 | public static void main (String[] args) { 14 | app.run(args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /samples/jafu-reactive-data-r2dbc/src/main/java/com/sample/UserHandler.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | import reactor.core.publisher.Mono; 4 | 5 | import org.springframework.http.MediaType; 6 | import org.springframework.web.reactive.function.server.ServerRequest; 7 | import org.springframework.web.reactive.function.server.ServerResponse; 8 | 9 | public class UserHandler { 10 | 11 | private final UserRepository repository; 12 | 13 | public UserHandler(UserRepository repository) { 14 | this.repository = repository; 15 | } 16 | 17 | public Mono listApi(ServerRequest request) { 18 | return ServerResponse.ok() 19 | .contentType(MediaType.APPLICATION_JSON) 20 | .body(repository.findAll(), User.class); 21 | } 22 | 23 | public Mono userApi(ServerRequest request) { 24 | return ServerResponse.ok() 25 | .contentType(MediaType.APPLICATION_JSON) 26 | .body(repository.findOne(request.pathVariable("login")), User.class); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /samples/jafu-reactive-data-r2dbc/src/main/resources/db/tables.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS users (login varchar PRIMARY KEY, firstname varchar, lastname varchar); 2 | MERGE INTO users VALUES('smaldini', 'Stéphane', 'Maldini'),('sdeleuze', 'Sébastien', 'Deleuze'),('bclozel', 'Brian', 'Clozel'); 3 | -------------------------------------------------------------------------------- /samples/jafu-reactive-data-r2dbc/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/jafu-reactive-minimal/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 3 | id("org.springframework.boot") version "2.6.6" 4 | id("java") 5 | } 6 | 7 | java { 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | targetCompatibility = JavaVersion.VERSION_1_8 10 | } 11 | 12 | dependencies { 13 | implementation("org.springframework.fu:spring-fu-jafu:0.5.2-SNAPSHOT") 14 | 15 | implementation("org.springframework.boot:spring-boot-starter-webflux") 16 | 17 | testImplementation("org.springframework.boot:spring-boot-starter-test") 18 | } 19 | 20 | repositories { 21 | mavenLocal() 22 | mavenCentral() 23 | maven("https://repo.spring.io/milestone") 24 | maven("https://repo.spring.io/snapshot") 25 | } 26 | 27 | tasks.withType { 28 | useJUnitPlatform() 29 | } 30 | -------------------------------------------------------------------------------- /samples/jafu-reactive-minimal/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/jafu-reactive-minimal/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/jafu-reactive-minimal/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/jafu-reactive-minimal/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/jafu-reactive-minimal/src/main/java/com/sample/Application.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | import org.springframework.fu.jafu.JafuApplication; 4 | 5 | import static org.springframework.fu.jafu.Jafu.reactiveWebApplication; 6 | import static org.springframework.fu.jafu.webflux.WebFluxServerDsl.webFlux; 7 | 8 | public class Application { 9 | 10 | public static JafuApplication app = reactiveWebApplication(a -> a 11 | .beans(b -> b 12 | .bean(SampleHandler.class) 13 | .bean(SampleService.class)) 14 | .enable(webFlux(s -> s 15 | .port(s.profiles().contains("test") ? 8181 : 8080) 16 | .router(r -> { 17 | SampleHandler handler = s.ref(SampleHandler.class); 18 | r 19 | .GET("/", handler::hello) 20 | .GET("/api", handler::json); 21 | }).codecs(c -> c 22 | .string() 23 | .jackson())))); 24 | 25 | public static void main (String[] args) { 26 | app.run(args); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /samples/jafu-reactive-minimal/src/main/java/com/sample/Sample.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | public class Sample { 4 | 5 | private String message; 6 | 7 | 8 | public Sample() { 9 | } 10 | 11 | public Sample(String message) { 12 | this.message = message; 13 | } 14 | 15 | 16 | public String getMessage() { 17 | return message; 18 | } 19 | 20 | public void setMessage(String message) { 21 | this.message = message; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples/jafu-reactive-minimal/src/main/java/com/sample/SampleHandler.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | import reactor.core.publisher.Mono; 4 | 5 | import org.springframework.web.reactive.function.server.ServerRequest; 6 | import org.springframework.web.reactive.function.server.ServerResponse; 7 | 8 | import static org.springframework.web.reactive.function.server.ServerResponse.ok; 9 | 10 | public class SampleHandler { 11 | 12 | private SampleService sampleService; 13 | 14 | public SampleHandler(SampleService sampleService) { 15 | this.sampleService = sampleService; 16 | } 17 | 18 | public Mono hello(ServerRequest request) { 19 | return ok().bodyValue(sampleService.generateMessage()); 20 | } 21 | 22 | public Mono json(ServerRequest request) { 23 | return ok().bodyValue(new Sample(sampleService.generateMessage())); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /samples/jafu-reactive-minimal/src/main/java/com/sample/SampleService.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | public class SampleService { 4 | 5 | public String generateMessage() { 6 | return "Hello world!"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /samples/jafu-reactive-minimal/src/main/resources/static/foo.css: -------------------------------------------------------------------------------- 1 | p.one { 2 | border-style: solid; 3 | border-width: 5px; 4 | } -------------------------------------------------------------------------------- /samples/jafu-reactive-minimal/src/test/java/com/sample/IntegrationTests.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | import org.junit.jupiter.api.AfterAll; 4 | import org.junit.jupiter.api.BeforeAll; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import org.springframework.context.ConfigurableApplicationContext; 8 | import org.springframework.test.web.reactive.server.WebTestClient; 9 | 10 | public class IntegrationTests { 11 | 12 | private WebTestClient client = WebTestClient.bindToServer().baseUrl("http://localhost:8181").build(); 13 | 14 | private ConfigurableApplicationContext context; 15 | 16 | @BeforeAll 17 | public void beforeAll() { 18 | context = Application.app.run("test"); 19 | } 20 | 21 | @Test 22 | public void requestRootEndpoint() { 23 | client.get().uri("/").exchange() 24 | .expectStatus().is2xxSuccessful() 25 | .expectBody(String.class).isEqualTo("Hello world!"); 26 | } 27 | 28 | @Test 29 | public void requestApiEndpoint() { 30 | client.get().uri("/api").exchange() 31 | .expectStatus().is2xxSuccessful() 32 | .expectBody(String.class).isEqualTo("{\"message\":\"Hello world!\"}"); 33 | } 34 | 35 | @AfterAll 36 | void afterAll() { 37 | context.close(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /samples/jafu-reactive-minimal/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/jafu-reactive-mongodb/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 3 | id("org.springframework.boot") version "2.6.6" 4 | id("java") 5 | } 6 | 7 | java { 8 | sourceCompatibility = JavaVersion.VERSION_11 9 | targetCompatibility = JavaVersion.VERSION_11 10 | } 11 | 12 | dependencies { 13 | implementation("org.springframework.fu:spring-fu-jafu:0.5.2-SNAPSHOT") 14 | implementation("org.springframework.boot:spring-boot-starter-webflux") 15 | implementation("org.springframework.boot:spring-boot-starter-mustache") 16 | implementation("org.springframework.boot:spring-boot-starter-data-mongodb-reactive") 17 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 18 | implementation("de.flapdoodle.embed:de.flapdoodle.embed.mongo") 19 | 20 | testImplementation("org.springframework.boot:spring-boot-starter-test") 21 | } 22 | 23 | repositories { 24 | mavenLocal() 25 | mavenCentral() 26 | maven("https://repo.spring.io/milestone") 27 | maven("https://repo.spring.io/snapshot") 28 | } 29 | 30 | tasks.withType { 31 | useJUnitPlatform() 32 | } 33 | -------------------------------------------------------------------------------- /samples/jafu-reactive-mongodb/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/jafu-reactive-mongodb/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/jafu-reactive-mongodb/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/jafu-reactive-mongodb/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/jafu-reactive-mongodb/src/main/java/com/sample/Application.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | import org.springframework.fu.jafu.JafuApplication; 4 | 5 | import static org.springframework.fu.jafu.Jafu.reactiveWebApplication; 6 | 7 | public abstract class Application { 8 | public static JafuApplication app = reactiveWebApplication(app -> app 9 | .enable(Configurations.dataConfig) 10 | .enable(Configurations.webConfig) 11 | .configurationProperties(SampleProperties.class, "sample")); 12 | 13 | public static void main(String[] args) { 14 | app.run(); 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /samples/jafu-reactive-mongodb/src/main/java/com/sample/SampleProperties.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | public class SampleProperties { 4 | 5 | private String message; 6 | 7 | SampleProperties(String message) { 8 | this.message = message; 9 | } 10 | 11 | public String getMessage() { 12 | return message; 13 | } 14 | 15 | public void setMessage(String message) { 16 | this.message = message; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /samples/jafu-reactive-mongodb/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | sample.message=hello -------------------------------------------------------------------------------- /samples/jafu-reactive-mongodb/src/main/resources/data/users.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "login": "smaldini", 4 | "firstname": "Stéphane", 5 | "lastname": "Maldini" 6 | }, 7 | { 8 | "login": "sdeleuze", 9 | "firstname": "Sébastien", 10 | "lastname": "Deleuze" 11 | }, 12 | { 13 | "login": "bclozel", 14 | "firstname": "Brian", 15 | "lastname": "Clozel" 16 | } 17 | ] -------------------------------------------------------------------------------- /samples/jafu-reactive-mongodb/src/main/resources/templates/footer.mustache: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /samples/jafu-reactive-mongodb/src/main/resources/templates/header.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | Spring Fu simple webapp 4 | 5 | -------------------------------------------------------------------------------- /samples/jafu-reactive-mongodb/src/main/resources/templates/users.mustache: -------------------------------------------------------------------------------- 1 | {{> header}} 2 | 3 |

    4 | {{#users}} 5 |
  • User {{login}}: {{firstname}} {{lastname}}
  • 6 | {{/users}} 7 |
8 | 9 | {{> footer}} -------------------------------------------------------------------------------- /samples/jafu-reactive-mongodb/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/jafu-reactive-r2dbc/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 3 | id("org.springframework.boot") version "2.6.6" 4 | id("java") 5 | } 6 | 7 | java { 8 | sourceCompatibility = JavaVersion.VERSION_11 9 | targetCompatibility = JavaVersion.VERSION_11 10 | } 11 | 12 | dependencies { 13 | implementation("org.springframework.fu:spring-fu-jafu:0.5.2-SNAPSHOT") 14 | 15 | implementation("org.springframework.boot:spring-boot-starter-webflux") 16 | implementation("org.springframework.boot:spring-boot-starter-mustache") 17 | implementation("org.springframework:spring-r2dbc") 18 | implementation("io.r2dbc:r2dbc-h2") 19 | 20 | testImplementation("org.springframework.boot:spring-boot-starter-test") 21 | } 22 | 23 | repositories { 24 | mavenLocal() 25 | mavenCentral() 26 | maven("https://repo.spring.io/milestone") 27 | maven("https://repo.spring.io/snapshot") 28 | } 29 | 30 | tasks.withType { 31 | useJUnitPlatform() 32 | } 33 | -------------------------------------------------------------------------------- /samples/jafu-reactive-r2dbc/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/jafu-reactive-r2dbc/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/jafu-reactive-r2dbc/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/jafu-reactive-r2dbc/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/jafu-reactive-r2dbc/src/main/java/com/sample/Application.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | import org.springframework.fu.jafu.JafuApplication; 4 | 5 | import static org.springframework.fu.jafu.Jafu.reactiveWebApplication; 6 | 7 | public abstract class Application { 8 | 9 | public static JafuApplication app = reactiveWebApplication(app -> app 10 | .enable(Configurations.dataConfig) 11 | .enable(Configurations.webConfig)); 12 | 13 | public static void main (String[] args) { 14 | app.run(args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /samples/jafu-reactive-r2dbc/src/main/java/com/sample/UserHandler.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | import reactor.core.publisher.Mono; 4 | 5 | import org.springframework.http.MediaType; 6 | import org.springframework.web.reactive.function.server.ServerRequest; 7 | import org.springframework.web.reactive.function.server.ServerResponse; 8 | 9 | public class UserHandler { 10 | 11 | private final UserRepository repository; 12 | 13 | public UserHandler(UserRepository repository) { 14 | this.repository = repository; 15 | } 16 | 17 | public Mono listApi(ServerRequest request) { 18 | return ServerResponse.ok() 19 | .contentType(MediaType.APPLICATION_JSON) 20 | .body(repository.findAll(), User.class); 21 | } 22 | 23 | public Mono userApi(ServerRequest request) { 24 | return ServerResponse.ok() 25 | .contentType(MediaType.APPLICATION_JSON) 26 | .body(repository.findOne(request.pathVariable("login")), User.class); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /samples/jafu-reactive-r2dbc/src/main/resources/db/tables.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS users (login varchar PRIMARY KEY, firstname varchar, lastname varchar); 2 | MERGE INTO users VALUES('smaldini', 'Stéphane', 'Maldini'),('sdeleuze', 'Sébastien', 'Deleuze'),('bclozel', 'Brian', 'Clozel'); 3 | -------------------------------------------------------------------------------- /samples/jafu-reactive-r2dbc/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/jafu-servlet-cassandra/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 3 | id("org.springframework.boot") version "2.6.6" 4 | id("java") 5 | } 6 | 7 | java { 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | targetCompatibility = JavaVersion.VERSION_1_8 10 | } 11 | 12 | dependencies { 13 | implementation("org.springframework.fu:spring-fu-jafu:0.5.2-SNAPSHOT") 14 | implementation("org.testcontainers:cassandra:1.15.1") 15 | implementation("org.springframework.boot:spring-boot-starter-web") 16 | implementation("org.springframework.data:spring-data-cassandra") 17 | 18 | testImplementation("org.springframework.boot:spring-boot-starter-test") 19 | testImplementation("org.springframework.boot:spring-boot-starter-webflux") 20 | } 21 | 22 | repositories { 23 | mavenLocal() 24 | mavenCentral() 25 | maven("https://repo.spring.io/milestone") 26 | maven("https://repo.spring.io/snapshot") 27 | } 28 | 29 | tasks.withType { 30 | useJUnitPlatform() 31 | if (project.hasProperty("isCI")) { 32 | exclude("com/sample/IntegrationTests.class") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /samples/jafu-servlet-cassandra/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/jafu-servlet-cassandra/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/jafu-servlet-cassandra/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/jafu-servlet-cassandra/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/jafu-servlet-cassandra/src/main/java/com/sample/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | import org.springframework.data.cassandra.core.CassandraOperations; 4 | 5 | import java.util.List; 6 | import java.util.Optional; 7 | import java.util.UUID; 8 | 9 | public class UserRepository { 10 | 11 | private final CassandraOperations operations; 12 | 13 | public UserRepository(CassandraOperations operations) { 14 | this.operations = operations; 15 | } 16 | 17 | public List findAll() { 18 | return operations.select("select * from users", User.class); 19 | } 20 | 21 | public User save(User user) { 22 | user.setId(UUID.randomUUID()); 23 | return operations.insert(user); 24 | } 25 | 26 | public Optional fineOne(UUID id) { 27 | return Optional.ofNullable(operations.selectOneById(id, User.class)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /samples/jafu-servlet-cassandra/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/jafu-servlet-minimal/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 3 | id("org.springframework.boot") version "2.6.6" 4 | id("java") 5 | } 6 | 7 | java { 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | targetCompatibility = JavaVersion.VERSION_1_8 10 | } 11 | 12 | dependencies { 13 | implementation("org.springframework.fu:spring-fu-jafu:0.5.2-SNAPSHOT") 14 | 15 | implementation("org.springframework.boot:spring-boot-starter-web") 16 | 17 | testImplementation("org.springframework.boot:spring-boot-starter-test") 18 | testImplementation("org.springframework.boot:spring-boot-starter-webflux") 19 | } 20 | 21 | repositories { 22 | mavenLocal() 23 | mavenCentral() 24 | maven("https://repo.spring.io/milestone") 25 | maven("https://repo.spring.io/snapshot") 26 | } 27 | 28 | tasks.withType { 29 | useJUnitPlatform() 30 | } 31 | -------------------------------------------------------------------------------- /samples/jafu-servlet-minimal/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/jafu-servlet-minimal/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/jafu-servlet-minimal/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/jafu-servlet-minimal/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/jafu-servlet-minimal/src/main/java/com/sample/Application.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | import org.springframework.fu.jafu.JafuApplication; 4 | 5 | import static org.springframework.fu.jafu.Jafu.webApplication; 6 | import static org.springframework.fu.jafu.webmvc.WebMvcServerDsl.webMvc; 7 | 8 | public class Application { 9 | 10 | public static JafuApplication app = webApplication(a -> a.beans(b -> b 11 | .bean(SampleHandler.class) 12 | .bean(SampleService.class)) 13 | .enable(webMvc(s -> s 14 | .port(s.profiles().contains("test") ? 8181 : 8080) 15 | .router(router -> { 16 | SampleHandler handler = s.ref(SampleHandler.class); 17 | router 18 | .GET("/", handler::hello) 19 | .GET("/api", handler::json); 20 | }).converters(c -> c 21 | .string() 22 | .jackson())))); 23 | 24 | public static void main (String[] args) { 25 | app.run(args); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /samples/jafu-servlet-minimal/src/main/java/com/sample/Sample.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | public class Sample { 4 | 5 | private String message; 6 | 7 | 8 | public Sample() { 9 | } 10 | 11 | public Sample(String message) { 12 | this.message = message; 13 | } 14 | 15 | 16 | public String getMessage() { 17 | return message; 18 | } 19 | 20 | public void setMessage(String message) { 21 | this.message = message; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples/jafu-servlet-minimal/src/main/java/com/sample/SampleHandler.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | import org.springframework.web.servlet.function.ServerRequest; 4 | import org.springframework.web.servlet.function.ServerResponse; 5 | 6 | import static org.springframework.web.servlet.function.ServerResponse.ok; 7 | 8 | public class SampleHandler { 9 | 10 | private SampleService sampleService; 11 | 12 | public SampleHandler(SampleService sampleService) { 13 | this.sampleService = sampleService; 14 | } 15 | 16 | public ServerResponse hello(ServerRequest request) { 17 | return ok().body(sampleService.generateMessage()); 18 | } 19 | 20 | public ServerResponse json(ServerRequest request) { 21 | return ok().body(new Sample(sampleService.generateMessage())); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples/jafu-servlet-minimal/src/main/java/com/sample/SampleService.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | public class SampleService { 4 | 5 | public String generateMessage() { 6 | return "Hello world!"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /samples/jafu-servlet-minimal/src/main/resources/static/foo.css: -------------------------------------------------------------------------------- 1 | p.one { 2 | border-style: solid; 3 | border-width: 5px; 4 | } -------------------------------------------------------------------------------- /samples/jafu-servlet-minimal/src/test/java/com/sample/IntegrationTests.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | import org.junit.jupiter.api.AfterAll; 4 | import org.junit.jupiter.api.BeforeAll; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import org.springframework.context.ConfigurableApplicationContext; 8 | import org.springframework.test.web.reactive.server.WebTestClient; 9 | 10 | public class IntegrationTests { 11 | 12 | private WebTestClient client = WebTestClient.bindToServer().baseUrl("http://localhost:8181").build(); 13 | 14 | private ConfigurableApplicationContext context; 15 | 16 | @BeforeAll 17 | public void beforeAll() { 18 | context = Application.app.run("test"); 19 | } 20 | 21 | @Test 22 | public void requestRootEndpoint() { 23 | client.get().uri("/").exchange() 24 | .expectStatus().is2xxSuccessful() 25 | .expectBody(String.class).isEqualTo("Hello world!"); 26 | } 27 | 28 | @Test 29 | public void requestApiEndpoint() { 30 | client.get().uri("/api").exchange() 31 | .expectStatus().is2xxSuccessful() 32 | .expectBody(String.class).isEqualTo("{\"message\":\"Hello world!\"}"); 33 | } 34 | 35 | @AfterAll 36 | void afterAll() { 37 | context.close(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /samples/jafu-servlet-minimal/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-coroutines-mongodb/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/src/main/kotlin/org/springframework/fu/sample/coroutines/Application.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.sample.coroutines 2 | 3 | import org.springframework.fu.kofu.reactiveWebApplication 4 | 5 | val app = reactiveWebApplication { 6 | configurationProperties(prefix = "sample") 7 | enable(dataConfig) 8 | enable(webConfig) 9 | } 10 | 11 | fun main() { 12 | app.run() 13 | } 14 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/src/main/kotlin/org/springframework/fu/sample/coroutines/Configurations.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.sample.coroutines 2 | 3 | import de.flapdoodle.embed.mongo.distribution.Version 4 | import kotlinx.coroutines.runBlocking 5 | import org.springframework.boot.context.event.ApplicationReadyEvent 6 | import org.springframework.fu.kofu.configuration 7 | import org.springframework.fu.kofu.mongo.reactiveMongodb 8 | import org.springframework.fu.kofu.templating.mustache 9 | import org.springframework.fu.kofu.webflux.webFlux 10 | 11 | val dataConfig = configuration { 12 | beans { 13 | bean() 14 | } 15 | listener { 16 | runBlocking { 17 | ref().init() 18 | } 19 | } 20 | reactiveMongodb { 21 | embedded(Version.Main.PRODUCTION) 22 | } 23 | } 24 | 25 | val webConfig = configuration { 26 | beans { 27 | bean() 28 | bean(::routes) 29 | } 30 | webFlux { 31 | port = if (profiles.contains("test")) 8181 else 8080 32 | mustache() 33 | codecs { 34 | string() 35 | jackson() 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/src/main/kotlin/org/springframework/fu/sample/coroutines/Handlers.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.sample.coroutines 2 | 3 | import org.springframework.http.MediaType 4 | import org.springframework.web.reactive.function.server.ServerRequest 5 | import org.springframework.web.reactive.function.server.ServerResponse.ok 6 | import org.springframework.web.reactive.function.server.bodyAndAwait 7 | import org.springframework.web.reactive.function.server.bodyValueAndAwait 8 | import org.springframework.web.reactive.function.server.renderAndAwait 9 | 10 | @Suppress("UNUSED_PARAMETER") 11 | class UserHandler( 12 | private val repository: UserRepository, 13 | private val configuration: SampleProperties 14 | ) { 15 | 16 | suspend fun listApi(request: ServerRequest) = 17 | ok().contentType(MediaType.APPLICATION_JSON).bodyAndAwait(repository.findAll()) 18 | 19 | 20 | suspend fun listView(request: ServerRequest) = 21 | ok().renderAndAwait("users", mapOf("users" to repository.findAll())) 22 | 23 | suspend fun conf(request: ServerRequest) = 24 | ok().bodyValueAndAwait(configuration.message) 25 | } -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/src/main/kotlin/org/springframework/fu/sample/coroutines/Model.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.sample.coroutines 2 | 3 | import org.springframework.data.annotation.Id 4 | import org.springframework.data.mongodb.core.mapping.Document 5 | 6 | @Document 7 | data class User( 8 | @Id val login: String, 9 | val firstname: String, 10 | val lastname: String 11 | ) -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/src/main/kotlin/org/springframework/fu/sample/coroutines/Properties.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.sample.coroutines 2 | 3 | class SampleProperties(val message: String) -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/src/main/kotlin/org/springframework/fu/sample/coroutines/Routes.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.fu.sample.coroutines 2 | 3 | import org.springframework.web.reactive.function.server.coRouter 4 | 5 | fun routes(userHandler: UserHandler) = coRouter { 6 | GET("/", userHandler::listView) 7 | GET("/api/user", userHandler::listApi) 8 | GET("/conf", userHandler::conf) 9 | } 10 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | sample.message=hello -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/src/main/resources/data/users.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "login": "smaldini", 4 | "firstname": "Stéphane", 5 | "lastname": "Maldini" 6 | }, 7 | { 8 | "login": "sdeleuze", 9 | "firstname": "Sébastien", 10 | "lastname": "Deleuze" 11 | }, 12 | { 13 | "login": "bclozel", 14 | "firstname": "Brian", 15 | "lastname": "Clozel" 16 | } 17 | ] -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/src/main/resources/templates/footer.mustache: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/src/main/resources/templates/header.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | Spring Fu simple webapp 4 | 5 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/src/main/resources/templates/users.mustache: -------------------------------------------------------------------------------- 1 | {{> header}} 2 | 3 |
    4 | {{#users}} 5 |
  • User {{login}}: {{firstname}} {{lastname}}
  • 6 | {{/users}} 7 |
8 | 9 | {{> footer}} -------------------------------------------------------------------------------- /samples/kofu-coroutines-mongodb/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-coroutines-r2dbc/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/src/main/kotlin/com/sample/Application.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.sample 18 | 19 | import org.springframework.fu.kofu.reactiveWebApplication 20 | 21 | val app = reactiveWebApplication { 22 | configurationProperties(prefix = "sample") 23 | enable(dataConfig) 24 | enable(webConfig) 25 | } 26 | 27 | fun main() { 28 | app.run() 29 | } 30 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/src/main/kotlin/com/sample/Configurations.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.core.io.ClassPathResource 4 | import org.springframework.fu.kofu.configuration 5 | import org.springframework.fu.kofu.r2dbc.r2dbc 6 | import org.springframework.fu.kofu.templating.mustache 7 | import org.springframework.fu.kofu.webflux.webFlux 8 | import org.springframework.r2dbc.connection.init.ConnectionFactoryInitializer 9 | import org.springframework.r2dbc.connection.init.ResourceDatabasePopulator 10 | 11 | val dataConfig = configuration { 12 | beans { 13 | bean() 14 | bean { 15 | ConnectionFactoryInitializer().apply { 16 | setConnectionFactory(ref()) 17 | setDatabasePopulator(ResourceDatabasePopulator(ClassPathResource("db/tables.sql"))) 18 | } 19 | } 20 | } 21 | r2dbc { 22 | url = "r2dbc:h2:mem:///testdb;DB_CLOSE_DELAY=-1" 23 | } 24 | } 25 | 26 | val webConfig = configuration { 27 | beans { 28 | bean() 29 | bean(::routes) 30 | } 31 | webFlux { 32 | port = if (profiles.contains("test")) 8181 else 8080 33 | mustache() 34 | codecs { 35 | string() 36 | jackson() 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/src/main/kotlin/com/sample/Handlers.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.http.MediaType 4 | import org.springframework.web.reactive.function.server.* 5 | import org.springframework.web.reactive.function.server.ServerResponse.ok 6 | 7 | @Suppress("UNUSED_PARAMETER") 8 | class UserHandler( 9 | private val repository: UserRepository, 10 | private val configuration: SampleProperties) { 11 | 12 | suspend fun listApi(request: ServerRequest) = 13 | ok().contentType(MediaType.APPLICATION_JSON).bodyAndAwait(repository.findAll()) 14 | 15 | suspend fun userApi(request: ServerRequest) = 16 | ok().contentType(MediaType.APPLICATION_JSON).run { 17 | repository.findOne(request.pathVariable("login")) 18 | ?.let { bodyValueAndAwait(it) } 19 | ?:buildAndAwait() 20 | } 21 | 22 | 23 | suspend fun listView(request: ServerRequest) = 24 | ok().renderAndAwait("users", mapOf("users" to repository.findAll())) 25 | 26 | suspend fun conf(request: ServerRequest) = 27 | ok().bodyValueAndAwait(configuration.message) 28 | 29 | } -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/src/main/kotlin/com/sample/Model.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.data.annotation.Id 4 | import org.springframework.data.relational.core.mapping.Table 5 | 6 | @Table("users") 7 | data class User( 8 | @Id 9 | val login: String, 10 | val firstname: String, 11 | val lastname: String 12 | ) -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/src/main/kotlin/com/sample/Properties.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | class SampleProperties(val message: String) 4 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/src/main/kotlin/com/sample/Routes.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.web.reactive.function.server.coRouter 4 | 5 | fun routes(userHandler: UserHandler) = coRouter { 6 | GET("/", userHandler::listView) 7 | GET("/api/user", userHandler::listApi) 8 | GET("/api/user/{login}", userHandler::userApi) 9 | GET("/conf", userHandler::conf) 10 | } 11 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | sample.message=hello -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/src/main/resources/db/tables.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS users (login varchar PRIMARY KEY, firstname varchar, lastname varchar); 2 | MERGE INTO users VALUES('smaldini', 'Stéphane', 'Maldini'),('sdeleuze', 'Sébastien', 'Deleuze'),('bclozel', 'Brian', 'Clozel'); 3 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/src/main/resources/templates/footer.mustache: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/src/main/resources/templates/header.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | Spring Fu simple webapp 4 | 5 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/src/main/resources/templates/users.mustache: -------------------------------------------------------------------------------- 1 | {{> header}} 2 | 3 |
    4 | {{#users}} 5 |
  • User {{login}}: {{firstname}} {{lastname}}
  • 6 | {{/users}} 7 |
8 | 9 | {{> footer}} -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/src/test/kotlin/com/sample/UserRepositoryTests.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import kotlinx.coroutines.runBlocking 4 | import org.junit.jupiter.api.AfterAll 5 | import org.junit.jupiter.api.Assertions.assertEquals 6 | import org.junit.jupiter.api.BeforeAll 7 | import org.junit.jupiter.api.Test 8 | import org.springframework.beans.factory.getBean 9 | import org.springframework.context.ConfigurableApplicationContext 10 | import org.springframework.fu.kofu.application 11 | 12 | class UserRepositoryTests { 13 | 14 | private val dataApp = application { 15 | enable(dataConfig) 16 | } 17 | 18 | private lateinit var context: ConfigurableApplicationContext 19 | 20 | @BeforeAll 21 | fun beforeAll() { 22 | context = dataApp.run(profiles = "test") 23 | } 24 | 25 | @Test 26 | fun count() { 27 | val repository = context.getBean() 28 | runBlocking { 29 | assertEquals(3, repository.count()) 30 | } 31 | } 32 | 33 | @AfterAll 34 | fun afterAll() { 35 | context.close() 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-r2dbc/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.jetbrains.kotlin.jvm") version "1.6.10" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | id("org.springframework.boot") version "2.6.6" 7 | } 8 | 9 | dependencies { 10 | implementation("org.springframework.fu:spring-fu-kofu:0.5.2-SNAPSHOT") 11 | implementation("org.springframework.boot:spring-boot-starter-webflux") 12 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 13 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core") 14 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") 15 | implementation("am.ik.yavi:yavi:0.9.1") 16 | 17 | testImplementation("org.springframework.boot:spring-boot-starter-test") 18 | } 19 | 20 | repositories { 21 | mavenLocal() 22 | mavenCentral() 23 | maven("https://repo.spring.io/milestone") 24 | maven("https://repo.spring.io/snapshot") 25 | } 26 | 27 | tasks.withType { 28 | kotlinOptions { 29 | jvmTarget = "1.8" 30 | freeCompilerArgs = listOf("-Xjsr305=strict", "-Xjvm-default=enable") 31 | } 32 | } 33 | 34 | tasks.withType { 35 | useJUnitPlatform() 36 | } 37 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ./gradlew clean build -Pgraal=true 4 | unzip build/libs/kofu-coroutines-validation.jar -d build/libs/kofu-coroutines-validation 5 | 6 | native-image --allow-incomplete-classpath -H:IncludeResources='META-INF/.*.json|META-INF/spring.factories|org/springframework/boot/logging/.*|kotlin/.*.kotlin_builtins' --delay-class-initialization-to-runtime=io.netty.handler.codec.http.HttpObjectEncoder,org.springframework.core.io.VfsUtils,org.springframework.format.support.DefaultFormattingConversionService --delay-class-initialization-to-runtime=io.netty.handler.codec.http.HttpObjectEncoder,org.springframework.core.io.VfsUtils,org.springframework.format.support.DefaultFormattingConversionService -H:ReflectionConfigurationFiles=graal/app.json,graal/boot.json,graal/framework.json,graal/netty.json,graal/log4j.json,graal/yavi.json -Dio.netty.noUnsafe=true -H:+ReportUnsupportedElementsAtRuntime -Dfile.encoding=UTF-8 -cp ".:$(echo build/libs/kofu-coroutines-validation/BOOT-INF/lib/*.jar | tr ' ' ':')":build/libs/kofu-coroutines-validation/BOOT-INF/classes com.sample.ApplicationKt 7 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/graal/app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "com.sample.User", 4 | "allDeclaredConstructors" : true, 5 | "allDeclaredMethods": true 6 | } 7 | ] -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/graal/framework.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "org.springframework.context.support.GenericApplicationContext", 4 | "methods": [ 5 | { "name": "", "parameterTypes": [] } 6 | ] 7 | }, 8 | { 9 | "name": "org.springframework.context.annotation.ConfigurationClassPostProcessor", 10 | "methods": [ 11 | { "name": "", "parameterTypes": [] } 12 | ] 13 | }, 14 | { 15 | "name": "org.springframework.http.codec.support.DefaultServerCodecConfigurer", 16 | "methods": [ 17 | { "name": "", "parameterTypes": [] } 18 | ] 19 | } 20 | ] -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/graal/log4j.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "org.apache.logging.log4j.message.ReusableMessageFactory", 4 | "methods": [ 5 | { "name": "", "parameterTypes": [] } 6 | ] 7 | }, 8 | { 9 | "name": "org.apache.logging.log4j.message.DefaultFlowMessageFactory", 10 | "methods": [ 11 | { "name": "", "parameterTypes": [] } 12 | ] 13 | }, 14 | { 15 | "name": "org.apache.logging.log4j.message.ParameterizedMessageFactory", 16 | "methods": [ 17 | { "name": "", "parameterTypes": [] } 18 | ] 19 | } 20 | ] -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/graal/netty.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "io.netty.channel.socket.nio.NioServerSocketChannel", 4 | "methods": [ 5 | { "name": "", "parameterTypes": [] } 6 | ] 7 | }, 8 | { 9 | "name": "io.netty.channel.socket.nio.NioSocketChannel", 10 | "methods": [ 11 | { "name": "", "parameterTypes": [] } 12 | ] 13 | } 14 | ] -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/graal/yavi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "am.ik.yavi.core.ViolationDetail", 4 | "allDeclaredConstructors": true, 5 | "allDeclaredMethods": true 6 | } 7 | ] -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-coroutines-validation/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/src/main/kotlin/com/sample/Application.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.boot.WebApplicationType 4 | import org.springframework.fu.kofu.application 5 | import org.springframework.fu.kofu.reactiveWebApplication 6 | import org.springframework.fu.kofu.webflux.webFlux 7 | 8 | val app = reactiveWebApplication { 9 | beans { 10 | bean() 11 | bean(::routes) 12 | } 13 | webFlux { 14 | port = if (profiles.contains("test")) 8181 else 8080 15 | codecs { 16 | string() 17 | jackson() 18 | } 19 | } 20 | } 21 | 22 | fun main() { 23 | app.run() 24 | } 25 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/src/main/kotlin/com/sample/Handlers.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import am.ik.yavi.fn.awaitFold 4 | import org.springframework.web.reactive.function.server.ServerRequest 5 | import org.springframework.web.reactive.function.server.ServerResponse 6 | import org.springframework.web.reactive.function.server.ServerResponse.badRequest 7 | import org.springframework.web.reactive.function.server.ServerResponse.ok 8 | import org.springframework.web.reactive.function.server.awaitBody 9 | import org.springframework.web.reactive.function.server.bodyValueAndAwait 10 | 11 | @Suppress("UNUSED_PARAMETER") 12 | class UserHandler { 13 | 14 | suspend fun createApi(request: ServerRequest): ServerResponse = 15 | request.awaitBody() 16 | .validate() 17 | .mapError { it.detail() } 18 | .awaitFold( 19 | { badRequest().bodyValueAndAwait(mapOf("details" to it)) }, 20 | ok()::bodyValueAndAwait 21 | ) 22 | } -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/src/main/kotlin/com/sample/Model.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import am.ik.yavi.builder.validator 4 | import am.ik.yavi.core.Validated 5 | 6 | data class User( 7 | val login: String, 8 | val firstname: String, 9 | val lastname: String 10 | ) { 11 | companion object { 12 | val validator = validator { 13 | User::login { 14 | notNull() 15 | greaterThanOrEqual(4) 16 | lessThanOrEqual(8) 17 | } 18 | User::firstname { 19 | notBlank() 20 | lessThanOrEqual(32) 21 | } 22 | User::lastname { 23 | notBlank() 24 | lessThanOrEqual(32) 25 | } 26 | }.applicative() 27 | } 28 | 29 | fun validate(): Validated { 30 | return validator.validate(this) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/src/main/kotlin/com/sample/Routes.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.web.reactive.function.server.coRouter 4 | 5 | fun routes(userHandler: UserHandler) = coRouter { 6 | POST("/api/user", userHandler::createApi) 7 | } 8 | -------------------------------------------------------------------------------- /samples/kofu-coroutines-validation/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/.gitignore: -------------------------------------------------------------------------------- 1 | target/* 2 | .settings/* 3 | .classpath 4 | .project 5 | .factorypath 6 | .attach_pid* 7 | .idea 8 | *.iml 9 | /target 10 | .sts4-cache/ 11 | .vscode/* 12 | !.vscode/settings.json 13 | !.vscode/tasks.json 14 | !.vscode/launch.json 15 | !.vscode/extensions.json 16 | _site/ 17 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.1' 2 | services: 3 | mysql-server: 4 | image: mysql 5 | environment: 6 | - MYSQL_ROOT_PASSWORD=root 7 | - MYSQL_DATABASE=petclinic 8 | - MYSQL_USER=petclinic 9 | - MYSQL_PASSWORD=petclinic 10 | ports: 11 | - "3306:3306" 12 | volumes: 13 | - ./src/main/resources/db/mysql/schema.sql:/docker-entrypoint-initdb.d/1-schema.sql 14 | - ./src/main/resources/db/mysql/data.sql:/docker-entrypoint-initdb.d/2-data.sql 15 | kofu-petclinic-jdbc: 16 | image: kofu-petclinic-jdbc:0.0.1-SNAPSHOT 17 | ports: 18 | - "8080:8080" 19 | depends_on: 20 | - mysql-server -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/readme.md: -------------------------------------------------------------------------------- 1 | Kofu version of Spring Boot famous Petclinic sample with JDBC persistence. 2 | 3 | To build and run the native application packaged in a lightweight container with `functional` mode: 4 | ``` 5 | mvn spring-boot:build-image 6 | docker-compose up 7 | ``` 8 | 9 | To build and run the native application as a native executable with a local `native-image` install: 10 | ``` 11 | mvn -Pnative package 12 | target/org.springframework.samples.petclinic.kofupetclinicapplicationkt 13 | ``` 14 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/owner/Owner.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.owner 2 | 3 | import org.springframework.samples.petclinic.pet.Pet 4 | 5 | data class Owner( 6 | val id: Int? = null, 7 | val firstName: String, 8 | val lastName: String, 9 | val address: String, 10 | val city: String, 11 | val telephone: String, 12 | val pets: Set = hashSetOf() 13 | ) { 14 | 15 | fun getPetsSorted(): Set = 16 | pets.sortedBy { it.name }.toHashSet() 17 | 18 | fun addPet(pet: Pet) = 19 | copy(pets = pets + pet) 20 | 21 | fun getPet(name: String): Pet? = 22 | pets.filter { it.name == name.decapitalize() }.firstOrNull() 23 | 24 | fun isNew() = id == null 25 | 26 | companion object 27 | } 28 | 29 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/owner/OwnerConfig.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.owner 2 | 3 | import org.springframework.fu.kofu.configuration 4 | import org.springframework.web.servlet.function.router 5 | 6 | val ownerConfig = configuration { 7 | // Lambda based syntax for native application compat because of https://github.com/oracle/graal/issues/2500 8 | beans { 9 | bean { JdbcOwnerRepositoryImpl(ref()) } 10 | bean { OwnerHandler(ref(), ref()) } 11 | bean(::ownerRoutes) 12 | } 13 | } 14 | 15 | fun ownerRoutes(ownerHandler: OwnerHandler) = router { 16 | 17 | "/owners".nest { 18 | 19 | GET("/new", ownerHandler::getOwnerCreationView) 20 | 21 | POST("/new", ownerHandler::addOwner) 22 | 23 | GET("/find", ownerHandler::findOwnerView) 24 | 25 | GET("/", ownerHandler::findOwnerByLastName) 26 | 27 | GET("/{ownerId}/edit", ownerHandler::getOwnerUpdateView) 28 | 29 | POST("/{ownerId}/edit", ownerHandler::updateOwner) 30 | 31 | GET("/{ownerId}", ownerHandler::getOwnerById) 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/owner/OwnerRepository.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.owner 2 | 3 | import org.springframework.dao.DataAccessException 4 | 5 | interface OwnerRepository { 6 | 7 | @Throws(DataAccessException::class) 8 | fun findByLastName(lastName: String): Collection 9 | 10 | @Throws(DataAccessException::class) 11 | fun findById(ownerId: Int): Owner 12 | 13 | @Throws(DataAccessException::class) 14 | fun save(owner: Owner): Owner 15 | } 16 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/pet/Pet.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.pet 2 | 3 | import org.springframework.samples.petclinic.owner.Owner 4 | import org.springframework.samples.petclinic.visit.Visit 5 | import java.time.LocalDate 6 | 7 | data class Pet( 8 | val id: Int? = null, 9 | val name: String, 10 | val birthDate: LocalDate, 11 | val type: PetType, 12 | val owner: Owner, 13 | val visits: Set = linkedSetOf() 14 | ) { 15 | fun isNew() = id == null 16 | } 17 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/pet/PetConfig.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.pet 2 | 3 | import org.springframework.fu.kofu.configuration 4 | import org.springframework.web.servlet.function.router 5 | 6 | val petConfig = configuration { 7 | // Lambda based syntax for native application compat because of https://github.com/oracle/graal/issues/2500 8 | beans { 9 | bean { JdbcPetRepositoryImpl(ref(), ref(), ref()) } 10 | bean { PetHandler(ref(), ref()) } 11 | bean(::petRoutes) 12 | bean { PetTypeFormatter(ref()) } 13 | } 14 | } 15 | 16 | fun petRoutes(petHandler: PetHandler) = router { 17 | 18 | "/owners/{ownerId}/pets".nest { 19 | 20 | GET("/new", petHandler::getPetCreationView) 21 | 22 | POST("/new", petHandler::addPet) 23 | 24 | GET("/{petId}/edit", petHandler::getUpdatePetView) 25 | 26 | POST("/{petId}/edit", petHandler::updatePet) 27 | } 28 | } -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/pet/PetRepository.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.pet 2 | 3 | import org.springframework.dao.DataAccessException 4 | 5 | interface PetRepository{ 6 | 7 | @Throws(DataAccessException::class) 8 | fun findPetTypes(): List 9 | 10 | @Throws(DataAccessException::class) 11 | fun findById(petId: Int): Pet 12 | 13 | @Throws(DataAccessException::class) 14 | fun findByOwnerId(ownerId: Int): Set 15 | 16 | @Throws(DataAccessException::class) 17 | fun save(pet: Pet) 18 | } -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/pet/PetType.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.pet 2 | 3 | data class PetType( 4 | val id: Int, 5 | val name: String 6 | ) -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/pet/PetTypeFormatter.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.pet 2 | 3 | import org.springframework.beans.factory.annotation.Autowired 4 | import org.springframework.format.Formatter 5 | import java.text.ParseException 6 | import java.util.* 7 | 8 | class PetTypeFormatter(@Autowired val pets: PetRepository) : Formatter { 9 | override fun print(petType: PetType, locale: Locale): String = petType.name 10 | 11 | override fun parse(text: String, locale: Locale): PetType = 12 | pets.findPetTypes().firstOrNull { text == it.name } ?: throw ParseException("type not found: $text", 0) 13 | 14 | } -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/system/SystemConfig.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.system 2 | 3 | import org.springframework.fu.kofu.configuration 4 | import org.springframework.web.servlet.function.router 5 | 6 | val systemConfig = configuration { 7 | beans { 8 | bean(::systemRoutes) 9 | } 10 | } 11 | 12 | fun systemRoutes() = router { 13 | GET("/") { 14 | ok().render("welcome") 15 | } 16 | GET("/oups") { 17 | throw RuntimeException("Expected: route used to showcase what happens when an exception is thrown") 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/vet/Specialty.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.vet 2 | 3 | data class Specialty( 4 | val id: Int?, 5 | val name: String 6 | ) -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/vet/Vet.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.vet 2 | 3 | data class Vet( 4 | val id: Int, 5 | val firstName: String, 6 | val lastName: String, 7 | val specialties: Set = hashSetOf() 8 | ) { 9 | fun getNrOfSpecialties() = specialties.size 10 | } -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/vet/VetConfig.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.vet 2 | 3 | import org.springframework.fu.kofu.configuration 4 | import org.springframework.web.servlet.function.router 5 | 6 | val vetConfig = configuration { 7 | // Lambda based syntax for native application compat because of https://github.com/oracle/graal/issues/2500 8 | beans { 9 | bean { JdbcVetRepositoryImpl(ref()) } 10 | bean(::vetRoutes) 11 | } 12 | } 13 | 14 | fun vetRoutes(vetRepository: VetRepository) = router { 15 | GET("/vets.html") { 16 | ok().render("vets/vetList", mapOf("vets" to vetRepository.findAll().toList())) 17 | } 18 | GET("/vets") { 19 | ok().body(object { val vets = vetRepository.findAll().toList()}) 20 | } 21 | } -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/vet/VetRepository.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.vet 2 | 3 | import org.springframework.dao.DataAccessException 4 | import kotlin.jvm.Throws 5 | 6 | 7 | interface VetRepository { 8 | 9 | @Throws(DataAccessException::class) 10 | fun findAll(): Collection 11 | } -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/vet/Vets.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.vet 2 | 3 | class Vets( 4 | val vetList: List = listOf() 5 | ) -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/visit/Visit.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.visit 2 | 3 | import java.time.LocalDate 4 | 5 | data class Visit( 6 | val id: Int? = null, 7 | val date: LocalDate, 8 | val description: String 9 | ) { 10 | fun isNew() = id == null 11 | } -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/visit/VisitConfig.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.visit 2 | 3 | import org.springframework.fu.kofu.configuration 4 | import org.springframework.web.servlet.function.router 5 | 6 | val visitConfig = configuration { 7 | // Lambda based syntax for native application compat because of https://github.com/oracle/graal/issues/2500 8 | beans { 9 | bean { JdbcVisitRepositoryImpl(ref()) } 10 | bean { VisitHandler(ref(), ref()) } 11 | bean(::visitRoutes) 12 | } 13 | } 14 | 15 | fun visitRoutes(visitHandler: VisitHandler) = router { 16 | 17 | "/owners/{ownerId}/pets".nest { 18 | 19 | GET("/{petId}/visits/new", visitHandler::getVisitsView) 20 | 21 | POST("/{petId}/visits/new", visitHandler::addVisit) 22 | } 23 | } -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/kotlin/org/springframework/samples/petclinic/visit/VisitRepository.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic.visit 2 | 3 | import org.springframework.dao.DataAccessException 4 | import kotlin.jvm.Throws 5 | 6 | interface VisitRepository { 7 | 8 | @Throws(DataAccessException::class) 9 | fun save(visit: Visit, petId: Int) 10 | 11 | fun findByPetId(petId: Int): Set 12 | 13 | } -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/less/responsive.less: -------------------------------------------------------------------------------- 1 | @media (max-width: 768px) { 2 | .navbar-toggle { 3 | position:absolute; 4 | z-index: 9999; 5 | left:0px; 6 | top:0px; 7 | } 8 | 9 | .navbar a.navbar-brand { 10 | display: block; 11 | margin: 0 auto 0 auto; 12 | width: 148px; 13 | height: 50px; 14 | float: none; 15 | background: url("../images/spring-logo-dataflow-mobile.png") 0 center no-repeat; 16 | } 17 | 18 | .homepage-billboard .homepage-subtitle { 19 | font-size: 21px; 20 | line-height: 21px; 21 | } 22 | 23 | .navbar a.navbar-brand span { 24 | display: none; 25 | } 26 | 27 | .navbar { 28 | border-top-width: 0; 29 | } 30 | 31 | .xd-container { 32 | margin-top: 20px; 33 | margin-bottom: 30px; 34 | } 35 | 36 | .index-page--subtitle { 37 | margin-top: 10px; 38 | margin-bottom: 30px; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/META-INF/native-image/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "bundles": [ 3 | {"name":"messages/messages"} 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | |\ _,,,--,,_ 4 | /,`.-'`' ._ \-;;,_ 5 | _______ __|,4- ) )_ .;.(__`'-'__ ___ __ _ ___ _______ 6 | | | '---''(_/._)-'(_\_) | | | | | | | | | 7 | | _ | ___|_ _| | | | | |_| | | | __ _ _ 8 | | |_| | |___ | | | | | | | | | | \ \ \ \ 9 | | ___| ___| | | | _| |___| | _ | | _| \ \ \ \ 10 | | | | |___ | | | |_| | | | | | | |_ ) ) ) ) 11 | |___| |_______| |___| |_______|_______|___|_| |__|___|_______| / / / / 12 | ==================================================================/_/_/_/ 13 | 14 | :: Built with Spring Boot :: ${spring-boot.version} 15 | 16 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/db/mysql/user.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS petclinic; 2 | CREATE USER 'petclinic' IDENTIFIED BY 'petclinic'; 3 | ALTER DATABASE petclinic DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; 4 | GRANT ALL PRIVILEGES ON petclinic.* TO 'petclinic'@'%'; 5 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/messages/messages.properties: -------------------------------------------------------------------------------- 1 | welcome=Welcome 2 | required=is required 3 | notFound=has not been found 4 | duplicate=is already in use 5 | nonNumeric=must be all numeric 6 | duplicateFormSubmission=Duplicate form submission is not allowed 7 | typeMismatch.date=invalid date 8 | typeMismatch.birthDate=invalid date 9 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/messages/messages_de.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/src/main/resources/messages/messages_de.properties -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/messages/messages_en.properties: -------------------------------------------------------------------------------- 1 | # This file is intentionally empty. Message look-ups will fall back to the default "messages.properties" file. -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/static/resources/fonts/montserrat-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/src/main/resources/static/resources/fonts/montserrat-webfont.eot -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/static/resources/fonts/montserrat-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/src/main/resources/static/resources/fonts/montserrat-webfont.ttf -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/static/resources/fonts/montserrat-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/src/main/resources/static/resources/fonts/montserrat-webfont.woff -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/static/resources/fonts/varela_round-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/src/main/resources/static/resources/fonts/varela_round-webfont.eot -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/static/resources/fonts/varela_round-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/src/main/resources/static/resources/fonts/varela_round-webfont.ttf -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/static/resources/fonts/varela_round-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/src/main/resources/static/resources/fonts/varela_round-webfont.woff -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/static/resources/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/src/main/resources/static/resources/images/favicon.png -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/static/resources/images/pets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/src/main/resources/static/resources/images/pets.png -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/static/resources/images/platform-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/src/main/resources/static/resources/images/platform-bg.png -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/static/resources/images/spring-logo-dataflow-mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/src/main/resources/static/resources/images/spring-logo-dataflow-mobile.png -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/static/resources/images/spring-logo-dataflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/src/main/resources/static/resources/images/spring-logo-dataflow.png -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/static/resources/images/spring-pivotal-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-petclinic-jdbc/src/main/resources/static/resources/images/spring-pivotal-logo.png -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/templates/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Something happened...

8 |

Exception message

9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/templates/fragments/selectField.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
8 | 9 | 10 |
11 | 15 | 18 | 19 | 22 | Error 23 | 24 |
25 |
26 |
27 |
28 | 29 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/templates/owners/ownersList.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Owners

8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 28 | 29 | 30 |
NameAddressCityTelephonePets
22 | 23 | 25 | 26 | 27 |
31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/templates/vets/vetList.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 |

Veterinarians

9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 |
NameSpecialties
none
26 | 27 | 28 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/resources/templates/welcome.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Welcome

8 |
9 |
10 | 11 |
12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/wro/wro.properties: -------------------------------------------------------------------------------- 1 | #List of preProcessors 2 | preProcessors=lessCssImport 3 | #List of postProcessors 4 | postProcessors=less4j -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/main/wro/wro.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | classpath:META-INF/resources/webjars/bootstrap/3.3.6/less/bootstrap.less 4 | /petclinic.less 5 | 6 | 7 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/test/java/org/springframework/samples/petclinic/KofuPetClinicApplicationTest.kt: -------------------------------------------------------------------------------- 1 | package org.springframework.samples.petclinic 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class KofuPetClinicApplicationTest { 8 | 9 | @Test 10 | fun contextLoads(){} 11 | } 12 | -------------------------------------------------------------------------------- /samples/kofu-petclinic-jdbc/src/test/resources/application-default.properties: -------------------------------------------------------------------------------- 1 | database=h2 2 | spring.datasource.url= 3 | spring.datasource.initialization-mode=always -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-reactive-cassandra/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/src/main/kotlin/com/sample/Configurations.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.boot.context.event.ApplicationReadyEvent 4 | import org.springframework.fu.kofu.cassandra.reactiveCassandra 5 | import org.springframework.fu.kofu.configuration 6 | import org.springframework.fu.kofu.templating.mustache 7 | import org.springframework.fu.kofu.webflux.webFlux 8 | 9 | fun dataConfig(cassandraHost: String, 10 | cassandraPort: Int) = configuration { 11 | beans { 12 | bean() 13 | } 14 | listener { 15 | ref().init() 16 | } 17 | reactiveCassandra { 18 | keyspaceName = "Kofu" 19 | contactPoints = listOf("$cassandraHost:$cassandraPort") 20 | localDatacenter = "datacenter1" 21 | } 22 | } 23 | 24 | fun webConfig(serverPort: Int) = configuration { 25 | beans { 26 | bean() 27 | bean(::routes) 28 | } 29 | webFlux { 30 | port = serverPort 31 | mustache() 32 | codecs { 33 | string() 34 | jackson() 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/src/main/kotlin/com/sample/Handlers.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.http.MediaType 4 | import org.springframework.web.reactive.function.server.ServerRequest 5 | import org.springframework.web.reactive.function.server.ServerResponse 6 | import org.springframework.web.reactive.function.server.body 7 | 8 | @Suppress("UNUSED_PARAMETER") 9 | class UserHandler( 10 | private val repository: UserRepository, 11 | private val configuration: ApplicationProperties 12 | ) { 13 | 14 | fun listApi(request: ServerRequest) = ServerResponse 15 | .ok() 16 | .contentType(MediaType.APPLICATION_JSON) 17 | .body(repository.findAll()) 18 | 19 | fun listView(request: ServerRequest) = ServerResponse 20 | .ok() 21 | .render("users", mapOf("users" to repository.findAll())) 22 | 23 | 24 | fun conf(request: ServerRequest) = ServerResponse 25 | .ok() 26 | .bodyValue(configuration.message) 27 | 28 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/src/main/kotlin/com/sample/Model.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.data.annotation.Id 4 | import org.springframework.data.cassandra.core.mapping.Table 5 | 6 | @Table("users") 7 | data class User( 8 | @Id val login: String, 9 | val firstname: String, 10 | val lastname: String 11 | ) 12 | -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/src/main/kotlin/com/sample/Properties.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import com.datastax.driver.core.ProtocolOptions 4 | 5 | class ApplicationProperties( 6 | val cassandraHost: String = "localhost", 7 | val cassandraPort: Int = ProtocolOptions.DEFAULT_PORT, 8 | val serverPort: Int = 8080, 9 | val message: String = "Default message") -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/src/main/kotlin/com/sample/Routes.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.web.reactive.function.server.router 4 | 5 | fun routes(userHandler: UserHandler) = router { 6 | GET("/", userHandler::listView) 7 | GET("/api/user", userHandler::listApi) 8 | GET("/conf", userHandler::conf) 9 | } 10 | -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | sample.message=hello -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/src/main/resources/data/users.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "login": "smaldini", 4 | "firstname": "Stéphane", 5 | "lastname": "Maldini" 6 | }, 7 | { 8 | "login": "sdeleuze", 9 | "firstname": "Sébastien", 10 | "lastname": "Deleuze" 11 | }, 12 | { 13 | "login": "bclozel", 14 | "firstname": "Brian", 15 | "lastname": "Clozel" 16 | } 17 | ] -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/src/main/resources/schema.cql: -------------------------------------------------------------------------------- 1 | CREATE KEYSPACE Kofu WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1}; 2 | CREATE TABLE Kofu.Users (login VARCHAR PRIMARY KEY, firstname VARCHAR, lastname VARCHAR); 3 | USE Kofu; 4 | -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/src/main/resources/templates/footer.mustache: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/src/main/resources/templates/header.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | Spring Fu simple webapp 4 | 5 | -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/src/main/resources/templates/users.mustache: -------------------------------------------------------------------------------- 1 | {{> header}} 2 | 3 |
    4 | {{#users}} 5 |
  • User {{login}}: {{firstname}} {{lastname}}
  • 6 | {{/users}} 7 |
8 | 9 | {{> footer}} -------------------------------------------------------------------------------- /samples/kofu-reactive-cassandra/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-reactive-data-r2dbc/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/src/main/kotlin/com/sample/Application.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.sample 18 | 19 | import org.springframework.fu.kofu.reactiveWebApplication 20 | 21 | val app = reactiveWebApplication { 22 | configurationProperties(prefix = "sample") 23 | enable(dataConfig) 24 | enable(webConfig) 25 | } 26 | 27 | fun main() { 28 | app.run() 29 | } 30 | -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/src/main/kotlin/com/sample/Handlers.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.http.MediaType 4 | import org.springframework.web.reactive.function.server.ServerRequest 5 | import org.springframework.web.reactive.function.server.ServerResponse 6 | import org.springframework.web.reactive.function.server.body 7 | import org.springframework.web.reactive.function.server.bodyAndAwait 8 | 9 | @Suppress("UNUSED_PARAMETER") 10 | class UserHandler( 11 | private val repository: UserRepository, 12 | private val properties: SampleProperties 13 | ) { 14 | 15 | fun listApi(request: ServerRequest) = ServerResponse 16 | .ok() 17 | .contentType(MediaType.APPLICATION_JSON) 18 | .body(repository.findAll()) 19 | 20 | fun userApi(request: ServerRequest) = ServerResponse 21 | .ok() 22 | .contentType(MediaType.APPLICATION_JSON) 23 | .body(repository.findOne(request.pathVariable("login"))) 24 | 25 | fun listView(request: ServerRequest) = ServerResponse 26 | .ok() 27 | .render("users", mapOf("users" to repository.findAll())) 28 | 29 | 30 | fun conf(request: ServerRequest) = ServerResponse 31 | .ok() 32 | .bodyValue(properties.message) 33 | 34 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/src/main/kotlin/com/sample/Model.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.data.annotation.Id 4 | import org.springframework.data.relational.core.mapping.Table 5 | 6 | @Table("users") 7 | data class User( 8 | @Id 9 | val login: String, 10 | val firstname: String, 11 | val lastname: String 12 | ) -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/src/main/kotlin/com/sample/Properties.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | class SampleProperties(val message: String) -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/src/main/kotlin/com/sample/Repositories.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.data.r2dbc.core.R2dbcEntityOperations 4 | import org.springframework.data.relational.core.query.Criteria 5 | import org.springframework.data.relational.core.query.Query 6 | 7 | class UserRepository(private val operations: R2dbcEntityOperations) { 8 | 9 | fun count() = 10 | operations.count(Query.empty(), User::class.java) 11 | 12 | 13 | fun findAll() = 14 | operations.select(Query.empty(), User::class.java) 15 | 16 | 17 | fun findOne(id: String?) = 18 | operations.select(User::class.java).matching(Query.query(Criteria.where("login").`is`(id!!))).one() 19 | 20 | 21 | fun deleteAll() = 22 | operations.delete(User::class.java).all().then() 23 | 24 | 25 | fun insert(user: User) = 26 | operations.insert(User::class.java).using(user) 27 | 28 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/src/main/kotlin/com/sample/Routes.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.web.reactive.function.server.router 4 | 5 | fun routes(userHandler: UserHandler) = router { 6 | GET("/", userHandler::listView) 7 | GET("/api/user", userHandler::listApi) 8 | GET("/api/user/{login}", userHandler::userApi) 9 | GET("/conf", userHandler::conf) 10 | } 11 | -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | sample.message=hello -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/src/main/resources/db/tables.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS users (login varchar PRIMARY KEY, firstname varchar, lastname varchar); 2 | MERGE INTO users VALUES('smaldini', 'Stéphane', 'Maldini'),('sdeleuze', 'Sébastien', 'Deleuze'),('bclozel', 'Brian', 'Clozel'); 3 | -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/src/main/resources/templates/footer.mustache: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/src/main/resources/templates/header.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | Spring Fu simple webapp 4 | 5 | -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/src/main/resources/templates/users.mustache: -------------------------------------------------------------------------------- 1 | {{> header}} 2 | 3 |
    4 | {{#users}} 5 |
  • User {{login}}: {{firstname}} {{lastname}}
  • 6 | {{/users}} 7 |
8 | 9 | {{> footer}} -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/src/test/kotlin/com/sample/UserRepositoryTests.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.junit.jupiter.api.AfterAll 4 | import org.junit.jupiter.api.Assertions.assertEquals 5 | import org.junit.jupiter.api.BeforeAll 6 | import org.junit.jupiter.api.Test 7 | import org.springframework.beans.factory.getBean 8 | import org.springframework.context.ConfigurableApplicationContext 9 | import org.springframework.fu.kofu.application 10 | 11 | class UserRepositoryTests { 12 | 13 | private val dataApp = application { 14 | enable(dataConfig) 15 | } 16 | 17 | private lateinit var context: ConfigurableApplicationContext 18 | 19 | @BeforeAll 20 | fun beforeAll() { 21 | context = app.run(profiles = "test") 22 | } 23 | 24 | @Test 25 | fun count() { 26 | val repository = context.getBean() 27 | assertEquals(3, repository.count().block()) 28 | } 29 | 30 | @AfterAll 31 | fun afterAll() { 32 | context.close() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /samples/kofu-reactive-data-r2dbc/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/kofu-reactive-minimal/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.jetbrains.kotlin.jvm") version "1.6.10" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | id("org.springframework.boot") version "2.6.6" 7 | } 8 | 9 | dependencies { 10 | implementation("org.springframework.fu:spring-fu-kofu:0.5.2-SNAPSHOT") 11 | implementation("org.springframework.boot:spring-boot-starter-webflux") 12 | 13 | testImplementation("org.springframework.boot:spring-boot-starter-test") 14 | } 15 | 16 | repositories { 17 | mavenLocal() 18 | mavenCentral() 19 | maven("https://repo.spring.io/milestone") 20 | maven("https://repo.spring.io/snapshot") 21 | } 22 | 23 | tasks.withType { 24 | kotlinOptions { 25 | jvmTarget = "1.8" 26 | freeCompilerArgs = listOf("-Xjsr305=strict", "-Xjvm-default=enable") 27 | } 28 | } 29 | 30 | tasks.withType { 31 | useJUnitPlatform() 32 | } 33 | 34 | -------------------------------------------------------------------------------- /samples/kofu-reactive-minimal/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-reactive-minimal/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-reactive-minimal/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-reactive-minimal/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-minimal/src/main/kotlin/com/sample/Application.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.fu.kofu.reactiveWebApplication 4 | import org.springframework.fu.kofu.webflux.webFlux 5 | import org.springframework.web.reactive.function.server.ServerRequest 6 | import org.springframework.web.reactive.function.server.ServerResponse.ok 7 | 8 | val app = reactiveWebApplication { 9 | beans { 10 | bean() 11 | bean() 12 | } 13 | webFlux { 14 | port = if (profiles.contains("test")) 8181 else 8080 15 | router { 16 | val handler = ref() 17 | GET("/", handler::hello) 18 | GET("/api", handler::json) 19 | } 20 | codecs { 21 | string() 22 | jackson() 23 | } 24 | } 25 | } 26 | 27 | data class Sample(val message: String) 28 | 29 | class SampleService { 30 | fun generateMessage() = "Hello world!" 31 | } 32 | 33 | @Suppress("UNUSED_PARAMETER") 34 | class SampleHandler(private val sampleService: SampleService) { 35 | fun hello(request: ServerRequest)= ok().bodyValue(sampleService.generateMessage()) 36 | fun json(request: ServerRequest) = ok().bodyValue(Sample(sampleService.generateMessage())) 37 | } 38 | 39 | fun main() { 40 | app.run() 41 | } 42 | -------------------------------------------------------------------------------- /samples/kofu-reactive-minimal/src/test/kotlin/com/sample/IntegrationTests.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.junit.jupiter.api.AfterAll 4 | import org.junit.jupiter.api.BeforeAll 5 | import org.junit.jupiter.api.Test 6 | import org.springframework.context.ConfigurableApplicationContext 7 | import org.springframework.test.web.reactive.server.WebTestClient 8 | import org.springframework.test.web.reactive.server.expectBody 9 | 10 | class IntegrationTests { 11 | 12 | private val client = WebTestClient.bindToServer().baseUrl("http://localhost:8181").build() 13 | 14 | private lateinit var context: ConfigurableApplicationContext 15 | 16 | @BeforeAll 17 | fun beforeAll() { 18 | context = app.run(profiles = "test") 19 | } 20 | 21 | @Test 22 | fun `Request root endpoint`() { 23 | client.get().uri("/").exchange() 24 | .expectStatus().is2xxSuccessful 25 | .expectBody().isEqualTo("Hello world!") 26 | } 27 | 28 | @Test 29 | fun `Request API endpoint`() { 30 | client.get().uri("/api").exchange() 31 | .expectStatus().is2xxSuccessful 32 | .expectBody().isEqualTo("{\"message\":\"Hello world!\"}") 33 | } 34 | 35 | @AfterAll 36 | fun afterAll() { 37 | context.close() 38 | } 39 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-minimal/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-reactive-mongodb/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/src/main/kotlin/com/sample/Application.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.sample 18 | 19 | import org.springframework.fu.kofu.reactiveWebApplication 20 | 21 | val app = reactiveWebApplication { 22 | configurationProperties(prefix = "sample") 23 | enable(dataConfig) 24 | enable(webConfig) 25 | } 26 | 27 | fun main() { 28 | app.run() 29 | } 30 | -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/src/main/kotlin/com/sample/Configurations.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import de.flapdoodle.embed.mongo.distribution.Version 4 | import org.springframework.boot.context.event.ApplicationReadyEvent 5 | import org.springframework.fu.kofu.configuration 6 | import org.springframework.fu.kofu.mongo.reactiveMongodb 7 | import org.springframework.fu.kofu.templating.mustache 8 | import org.springframework.fu.kofu.webflux.webFlux 9 | 10 | val dataConfig = configuration { 11 | beans { 12 | bean() 13 | } 14 | listener { 15 | ref().init() 16 | } 17 | reactiveMongodb { 18 | embedded(Version.Main.PRODUCTION) 19 | } 20 | } 21 | 22 | val webConfig = configuration { 23 | beans { 24 | bean() 25 | bean(::routes) 26 | } 27 | webFlux { 28 | port = if (profiles.contains("test")) 8181 else 8080 29 | mustache() 30 | codecs { 31 | string() 32 | jackson() 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/src/main/kotlin/com/sample/Handlers.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.http.MediaType 4 | import org.springframework.web.reactive.function.server.ServerRequest 5 | import org.springframework.web.reactive.function.server.ServerResponse 6 | import org.springframework.web.reactive.function.server.body 7 | 8 | @Suppress("UNUSED_PARAMETER") 9 | class UserHandler( 10 | private val repository: UserRepository, 11 | private val configuration: SampleProperties 12 | ) { 13 | 14 | fun listApi(request: ServerRequest) = ServerResponse 15 | .ok() 16 | .contentType(MediaType.APPLICATION_JSON) 17 | .body(repository.findAll()) 18 | 19 | fun listView(request: ServerRequest) = ServerResponse 20 | .ok() 21 | .render("users", mapOf("users" to repository.findAll())) 22 | 23 | 24 | fun conf(request: ServerRequest) = ServerResponse 25 | .ok() 26 | .bodyValue(configuration.message) 27 | 28 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/src/main/kotlin/com/sample/Model.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.data.annotation.Id 4 | import org.springframework.data.mongodb.core.mapping.Document 5 | 6 | @Document 7 | data class User( 8 | @Id val login: String, 9 | val firstname: String, 10 | val lastname: String 11 | ) -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/src/main/kotlin/com/sample/Properties.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | class SampleProperties(val message: String) -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/src/main/kotlin/com/sample/Repositories.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper 4 | import com.fasterxml.jackson.module.kotlin.readValue 5 | import org.springframework.core.io.ClassPathResource 6 | import org.springframework.data.mongodb.core.ReactiveMongoOperations 7 | import org.springframework.data.mongodb.core.count 8 | import org.springframework.data.mongodb.core.findAll 9 | import org.springframework.data.mongodb.core.findById 10 | import org.springframework.data.mongodb.core.remove 11 | 12 | class UserRepository( 13 | private val mongo: ReactiveMongoOperations, 14 | private val objectMapper: ObjectMapper 15 | ) { 16 | 17 | fun count() = mongo.count() 18 | 19 | fun findAll() = mongo.findAll() 20 | 21 | fun findOne(id: String) = mongo.findById(id) 22 | 23 | fun deleteAll() = mongo.remove() 24 | 25 | fun save(user: User) = mongo.save(user) 26 | 27 | fun init() { 28 | val eventsResource = ClassPathResource("data/users.json") 29 | val users: List = objectMapper.readValue(eventsResource.inputStream) 30 | users.forEach { 31 | save(it).subscribe() 32 | } 33 | 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/src/main/kotlin/com/sample/Routes.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.web.reactive.function.server.router 4 | 5 | fun routes(userHandler: UserHandler) = router { 6 | GET("/", userHandler::listView) 7 | GET("/api/user", userHandler::listApi) 8 | GET("/conf", userHandler::conf) 9 | } 10 | -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | sample.message=hello -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/src/main/resources/data/users.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "login": "smaldini", 4 | "firstname": "Stéphane", 5 | "lastname": "Maldini" 6 | }, 7 | { 8 | "login": "sdeleuze", 9 | "firstname": "Sébastien", 10 | "lastname": "Deleuze" 11 | }, 12 | { 13 | "login": "bclozel", 14 | "firstname": "Brian", 15 | "lastname": "Clozel" 16 | } 17 | ] -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/src/main/resources/templates/footer.mustache: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/src/main/resources/templates/header.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | Spring Fu simple webapp 4 | 5 | -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/src/main/resources/templates/users.mustache: -------------------------------------------------------------------------------- 1 | {{> header}} 2 | 3 |
    4 | {{#users}} 5 |
  • User {{login}}: {{firstname}} {{lastname}}
  • 6 | {{/users}} 7 |
8 | 9 | {{> footer}} -------------------------------------------------------------------------------- /samples/kofu-reactive-mongodb/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-reactive-r2dbc/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/src/main/kotlin/com/sample/Application.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.sample 18 | 19 | import org.springframework.fu.kofu.reactiveWebApplication 20 | 21 | val app = reactiveWebApplication { 22 | configurationProperties(prefix = "sample") 23 | enable(dataConfig) 24 | enable(webConfig) 25 | } 26 | 27 | fun main() { 28 | app.run() 29 | } 30 | -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/src/main/kotlin/com/sample/Configurations.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.core.io.ClassPathResource 4 | import org.springframework.fu.kofu.configuration 5 | import org.springframework.fu.kofu.r2dbc.r2dbc 6 | import org.springframework.fu.kofu.templating.mustache 7 | import org.springframework.fu.kofu.webflux.webFlux 8 | import org.springframework.r2dbc.connection.init.ConnectionFactoryInitializer 9 | import org.springframework.r2dbc.connection.init.ResourceDatabasePopulator 10 | 11 | val dataConfig = configuration { 12 | beans { 13 | bean() 14 | bean { 15 | ConnectionFactoryInitializer().apply { 16 | setConnectionFactory(ref()) 17 | setDatabasePopulator(ResourceDatabasePopulator(ClassPathResource("db/tables.sql"))) 18 | } 19 | } 20 | } 21 | r2dbc { 22 | url = "r2dbc:h2:mem:///testdb;DB_CLOSE_DELAY=-1" 23 | } 24 | } 25 | 26 | val webConfig = configuration { 27 | beans { 28 | bean() 29 | bean(::routes) 30 | } 31 | webFlux { 32 | port = if (profiles.contains("test")) 8181 else 8080 33 | mustache() 34 | codecs { 35 | string() 36 | jackson() 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/src/main/kotlin/com/sample/Handlers.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.http.MediaType 4 | import org.springframework.web.reactive.function.server.ServerRequest 5 | import org.springframework.web.reactive.function.server.ServerResponse 6 | import org.springframework.web.reactive.function.server.body 7 | import org.springframework.web.reactive.function.server.bodyAndAwait 8 | 9 | @Suppress("UNUSED_PARAMETER") 10 | class UserHandler( 11 | private val repository: UserRepository, 12 | private val properties: SampleProperties 13 | ) { 14 | 15 | fun listApi(request: ServerRequest) = ServerResponse 16 | .ok() 17 | .contentType(MediaType.APPLICATION_JSON) 18 | .body(repository.findAll()) 19 | 20 | fun userApi(request: ServerRequest) = ServerResponse 21 | .ok() 22 | .contentType(MediaType.APPLICATION_JSON) 23 | .body(repository.findOne(request.pathVariable("login"))) 24 | 25 | fun listView(request: ServerRequest) = ServerResponse 26 | .ok() 27 | .render("users", mapOf("users" to repository.findAll())) 28 | 29 | 30 | fun conf(request: ServerRequest) = ServerResponse 31 | .ok() 32 | .bodyValue(properties.message) 33 | 34 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/src/main/kotlin/com/sample/Model.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | data class User( 4 | val login: String, 5 | val firstname: String, 6 | val lastname: String 7 | ) -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/src/main/kotlin/com/sample/Properties.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | class SampleProperties(val message: String) -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/src/main/kotlin/com/sample/Routes.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.web.reactive.function.server.router 4 | 5 | fun routes(userHandler: UserHandler) = router { 6 | GET("/", userHandler::listView) 7 | GET("/api/user", userHandler::listApi) 8 | GET("/api/user/{login}", userHandler::userApi) 9 | GET("/conf", userHandler::conf) 10 | } 11 | -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | sample.message=hello -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/src/main/resources/db/tables.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS users (login varchar PRIMARY KEY, firstname varchar, lastname varchar); 2 | MERGE INTO users VALUES('smaldini', 'Stéphane', 'Maldini'),('sdeleuze', 'Sébastien', 'Deleuze'),('bclozel', 'Brian', 'Clozel'); 3 | -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/src/main/resources/templates/footer.mustache: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/src/main/resources/templates/header.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | Spring Fu simple webapp 4 | 5 | -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/src/main/resources/templates/users.mustache: -------------------------------------------------------------------------------- 1 | {{> header}} 2 | 3 |
    4 | {{#users}} 5 |
  • User {{login}}: {{firstname}} {{lastname}}
  • 6 | {{/users}} 7 |
8 | 9 | {{> footer}} -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/src/test/kotlin/com/sample/UserRepositoryTests.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.junit.jupiter.api.AfterAll 4 | import org.junit.jupiter.api.Assertions.assertEquals 5 | import org.junit.jupiter.api.BeforeAll 6 | import org.junit.jupiter.api.Test 7 | import org.springframework.beans.factory.getBean 8 | import org.springframework.context.ConfigurableApplicationContext 9 | import org.springframework.fu.kofu.application 10 | 11 | class UserRepositoryTests { 12 | 13 | private val dataApp = application { 14 | enable(dataConfig) 15 | } 16 | 17 | private lateinit var context: ConfigurableApplicationContext 18 | 19 | @BeforeAll 20 | fun beforeAll() { 21 | context = app.run(profiles = "test") 22 | } 23 | 24 | @Test 25 | fun count() { 26 | val repository = context.getBean() 27 | assertEquals(3, repository.count().block()) 28 | } 29 | 30 | @AfterAll 31 | fun afterAll() { 32 | context.close() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /samples/kofu-reactive-r2dbc/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-reactive-redis/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/src/main/kotlin/com/sample/Application.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.fu.kofu.reactiveWebApplication 4 | import org.testcontainers.containers.GenericContainer 5 | 6 | fun app(properties: ApplicationProperties) = reactiveWebApplication { 7 | with(configurationProperties(properties)) { 8 | enable(dataConfig(redisHost, redisPort)) 9 | enable(webConfig(serverPort)) 10 | } 11 | } 12 | 13 | fun main() { 14 | val redisContainer = object : GenericContainer("redis:5") {} 15 | redisContainer.withExposedPorts(6379) 16 | redisContainer.start() 17 | val properties = ApplicationProperties( 18 | redisHost = redisContainer.containerIpAddress, 19 | redisPort = redisContainer.firstMappedPort) 20 | app(properties).run() 21 | } 22 | -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/src/main/kotlin/com/sample/Configurations.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.boot.context.event.ApplicationReadyEvent 4 | import org.springframework.fu.kofu.configuration 5 | import org.springframework.fu.kofu.redis.reactiveRedis 6 | import org.springframework.fu.kofu.templating.mustache 7 | import org.springframework.fu.kofu.webflux.webFlux 8 | 9 | fun dataConfig(redisHost: String, redisPort: Int) = configuration { 10 | beans { 11 | bean() 12 | } 13 | listener { 14 | ref().init() 15 | } 16 | reactiveRedis { 17 | host = redisHost 18 | port = redisPort 19 | } 20 | } 21 | 22 | fun webConfig(serverPort: Int) = configuration { 23 | beans { 24 | bean() 25 | bean(::routes) 26 | } 27 | webFlux { 28 | port = serverPort 29 | mustache() 30 | codecs { 31 | string() 32 | jackson() 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/src/main/kotlin/com/sample/Handlers.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.http.MediaType 4 | import org.springframework.web.reactive.function.server.ServerRequest 5 | import org.springframework.web.reactive.function.server.ServerResponse 6 | import org.springframework.web.reactive.function.server.body 7 | 8 | @Suppress("UNUSED_PARAMETER") 9 | class UserHandler( 10 | private val repository: UserRepository, 11 | private val configuration: ApplicationProperties 12 | ) { 13 | 14 | fun listApi(request: ServerRequest) = ServerResponse 15 | .ok() 16 | .contentType(MediaType.APPLICATION_JSON) 17 | .body(repository.findAll()) 18 | 19 | fun listView(request: ServerRequest) = ServerResponse 20 | .ok() 21 | .render("users", mapOf("users" to repository.findAll())) 22 | 23 | 24 | fun conf(request: ServerRequest) = ServerResponse 25 | .ok() 26 | .bodyValue(configuration.message) 27 | 28 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/src/main/kotlin/com/sample/Model.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import java.io.Serializable 4 | 5 | const val KEY = "users" 6 | 7 | data class User( 8 | val login: String, 9 | val firstname: String, 10 | val lastname: String 11 | ) : Serializable -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/src/main/kotlin/com/sample/Properties.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | class ApplicationProperties( 4 | val redisHost: String = "localhost", 5 | val redisPort: Int = 6379, 6 | val serverPort: Int = 8080, 7 | val message: String = "Default message") -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/src/main/kotlin/com/sample/Repositories.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper 4 | import com.fasterxml.jackson.module.kotlin.readValue 5 | import org.springframework.core.io.ClassPathResource 6 | import org.springframework.data.redis.core.ReactiveRedisTemplate 7 | 8 | 9 | class UserRepository( 10 | reactiveRedisTemplate: ReactiveRedisTemplate, 11 | private val objectMapper: ObjectMapper 12 | ) { 13 | private val operations = reactiveRedisTemplate.opsForHash() 14 | 15 | fun count() = operations.size(KEY) 16 | 17 | fun findAll() = operations.values(KEY) 18 | 19 | fun findOne(login: String) = operations.get(KEY, login) 20 | 21 | fun save(user: User) = operations.put(KEY, user.login, user) 22 | 23 | fun deleteAll() = operations.delete(KEY) 24 | 25 | fun init() { 26 | val eventResource = ClassPathResource("data/users.json") 27 | val users: List = objectMapper.readValue(eventResource.inputStream) 28 | users.forEach { 29 | save(it).subscribe() 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/src/main/kotlin/com/sample/Routes.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.web.reactive.function.server.router 4 | 5 | fun routes(userHandler: UserHandler) = router { 6 | GET("/", userHandler::listView) 7 | GET("/api/user", userHandler::listApi) 8 | GET("/conf", userHandler::conf) 9 | } 10 | -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/src/main/resources/data/users.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "login": "smaldini", 4 | "firstname": "Stéphane", 5 | "lastname": "Maldini" 6 | }, 7 | { 8 | "login": "sdeleuze", 9 | "firstname": "Sébastien", 10 | "lastname": "Deleuze" 11 | }, 12 | { 13 | "login": "bclozel", 14 | "firstname": "Brian", 15 | "lastname": "Clozel" 16 | } 17 | ] -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/src/main/resources/templates/footer.mustache: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/src/main/resources/templates/header.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | Spring Fu simple webapp 4 | 5 | -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/src/main/resources/templates/users.mustache: -------------------------------------------------------------------------------- 1 | {{> header}} 2 | 3 |
    4 | {{#users}} 5 |
  • User {{login}}: {{firstname}} {{lastname}}
  • 6 | {{/users}} 7 |
8 | 9 | {{> footer}} -------------------------------------------------------------------------------- /samples/kofu-reactive-redis/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default=per_class -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.jetbrains.kotlin.jvm") version "1.6.10" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | id("org.springframework.boot") version "2.6.6" 7 | } 8 | 9 | dependencies { 10 | implementation("org.springframework.fu:spring-fu-kofu:0.5.2-SNAPSHOT") 11 | implementation("org.springframework.boot:spring-boot-starter-webflux") 12 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 13 | implementation("am.ik.yavi:yavi:0.9.1") 14 | 15 | testImplementation("org.springframework.boot:spring-boot-starter-test") 16 | } 17 | 18 | repositories { 19 | mavenLocal() 20 | mavenCentral() 21 | maven("https://repo.spring.io/milestone") 22 | maven("https://repo.spring.io/snapshot") 23 | } 24 | 25 | tasks.withType { 26 | kotlinOptions { 27 | jvmTarget = "1.8" 28 | freeCompilerArgs = listOf("-Xjsr305=strict", "-Xjvm-default=enable") 29 | } 30 | } 31 | 32 | tasks.withType { 33 | useJUnitPlatform() 34 | } 35 | -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ./gradlew clean build -Pgraal=true 4 | unzip build/libs/kofu-reactive-validation.jar -d build/libs/kofu-reactive-validation 5 | 6 | native-image --allow-incomplete-classpath -H:IncludeResources='META-INF/.*.json|META-INF/spring.factories|org/springframework/boot/logging/.*|kotlin/.*.kotlin_builtins' --delay-class-initialization-to-runtime=io.netty.handler.codec.http.HttpObjectEncoder,org.springframework.core.io.VfsUtils,org.springframework.format.support.DefaultFormattingConversionService --delay-class-initialization-to-runtime=io.netty.handler.codec.http.HttpObjectEncoder,org.springframework.core.io.VfsUtils,org.springframework.format.support.DefaultFormattingConversionService -H:ReflectionConfigurationFiles=graal/app.json,graal/boot.json,graal/framework.json,graal/netty.json,graal/log4j.json,graal/yavi.json -Dio.netty.noUnsafe=true -H:+ReportUnsupportedElementsAtRuntime -Dfile.encoding=UTF-8 -cp ".:$(echo build/libs/kofu-reactive-validation/BOOT-INF/lib/*.jar | tr ' ' ':')":build/libs/kofu-reactive-validation/BOOT-INF/classes com.sample.ApplicationKt 7 | -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/graal/app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "com.sample.User", 4 | "allDeclaredConstructors" : true, 5 | "allDeclaredMethods": true 6 | } 7 | ] -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/graal/framework.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "org.springframework.context.support.GenericApplicationContext", 4 | "methods": [ 5 | { "name": "", "parameterTypes": [] } 6 | ] 7 | }, 8 | { 9 | "name": "org.springframework.context.annotation.ConfigurationClassPostProcessor", 10 | "methods": [ 11 | { "name": "", "parameterTypes": [] } 12 | ] 13 | }, 14 | { 15 | "name": "org.springframework.http.codec.support.DefaultServerCodecConfigurer", 16 | "methods": [ 17 | { "name": "", "parameterTypes": [] } 18 | ] 19 | } 20 | ] -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/graal/log4j.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "org.apache.logging.log4j.message.ReusableMessageFactory", 4 | "methods": [ 5 | { "name": "", "parameterTypes": [] } 6 | ] 7 | }, 8 | { 9 | "name": "org.apache.logging.log4j.message.DefaultFlowMessageFactory", 10 | "methods": [ 11 | { "name": "", "parameterTypes": [] } 12 | ] 13 | }, 14 | { 15 | "name": "org.apache.logging.log4j.message.ParameterizedMessageFactory", 16 | "methods": [ 17 | { "name": "", "parameterTypes": [] } 18 | ] 19 | } 20 | ] -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/graal/netty.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "io.netty.channel.socket.nio.NioServerSocketChannel", 4 | "methods": [ 5 | { "name": "", "parameterTypes": [] } 6 | ] 7 | }, 8 | { 9 | "name": "io.netty.channel.socket.nio.NioSocketChannel", 10 | "methods": [ 11 | { "name": "", "parameterTypes": [] } 12 | ] 13 | } 14 | ] -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/graal/yavi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "am.ik.yavi.core.ViolationDetail", 4 | "allDeclaredConstructors": true, 5 | "allDeclaredMethods": true 6 | } 7 | ] -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-reactive-validation/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/src/main/kotlin/com/sample/Application.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.fu.kofu.reactiveWebApplication 4 | import org.springframework.fu.kofu.webflux.webFlux 5 | 6 | val app = reactiveWebApplication { 7 | beans { 8 | bean() 9 | bean(::routes) 10 | } 11 | webFlux { 12 | port = if (profiles.contains("test")) 8181 else 8080 13 | codecs { 14 | string() 15 | jackson() 16 | } 17 | } 18 | } 19 | 20 | fun main() { 21 | app.run() 22 | } 23 | -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/src/main/kotlin/com/sample/Handlers.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.web.reactive.function.server.ServerRequest 4 | import org.springframework.web.reactive.function.server.ServerResponse.badRequest 5 | import org.springframework.web.reactive.function.server.ServerResponse.ok 6 | import org.springframework.web.reactive.function.server.bodyToMono 7 | 8 | @Suppress("UNUSED_PARAMETER") 9 | class UserHandler { 10 | 11 | fun createApi(request: ServerRequest) = 12 | request.bodyToMono() 13 | .flatMap { user -> 14 | user.validate() 15 | .mapError { it.detail() } 16 | .fold( 17 | { badRequest().bodyValue(mapOf("details" to it)) }, 18 | ok()::bodyValue 19 | ) 20 | } 21 | } -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/src/main/kotlin/com/sample/Model.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import am.ik.yavi.builder.validator 4 | import am.ik.yavi.core.Validated 5 | 6 | data class User( 7 | val login: String?, 8 | val firstname: String, 9 | val lastname: String 10 | ) { 11 | companion object { 12 | val validator = validator { 13 | User::login { 14 | notNull() 15 | greaterThanOrEqual(4) 16 | lessThanOrEqual(8) 17 | } 18 | User::firstname { 19 | notBlank() 20 | lessThanOrEqual(32) 21 | } 22 | User::lastname { 23 | notBlank() 24 | lessThanOrEqual(32) 25 | } 26 | }.applicative() 27 | } 28 | 29 | fun validate(): Validated { 30 | return validator.validate(this) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/src/main/kotlin/com/sample/Routes.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.web.reactive.function.server.router 4 | 5 | fun routes(userHandler: UserHandler) = router { 6 | POST("/api/user", userHandler::createApi) 7 | } 8 | -------------------------------------------------------------------------------- /samples/kofu-reactive-validation/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/kofu-servlet-jooq/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-servlet-jooq/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /samples/kofu-servlet-jooq/src/main/kotlin/com/sample/Application.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.fu.kofu.webApplication 4 | 5 | val app = webApplication { 6 | configurationProperties(prefix = "sample") 7 | enable(dataConfig) 8 | enable(webConfig) 9 | } 10 | 11 | fun main() { 12 | app.run() 13 | } 14 | -------------------------------------------------------------------------------- /samples/kofu-servlet-jooq/src/main/kotlin/com/sample/Configurations.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.fu.kofu.configuration 4 | import org.springframework.fu.kofu.jdbc.DataSourceType 5 | import org.springframework.fu.kofu.jooq.jooq 6 | import org.springframework.fu.kofu.webmvc.webMvc 7 | 8 | val dataConfig = configuration { 9 | beans { 10 | bean() 11 | } 12 | jooq(DataSourceType.Generic) { 13 | url = "jdbc:h2:mem:vet-clinic-generation" 14 | schema = listOf("classpath:db/schema.sql") 15 | generateUniqueName = false 16 | name = "minimal-jooq" 17 | } 18 | } 19 | 20 | val webConfig = configuration { 21 | beans { 22 | bean() 23 | bean(::routes) 24 | } 25 | webMvc { 26 | port = if (profiles.contains("test")) 8181 else 8080 27 | converters { 28 | string() 29 | jackson() 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /samples/kofu-servlet-jooq/src/main/kotlin/com/sample/Handlers.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.http.MediaType 4 | import org.springframework.web.servlet.function.ServerRequest 5 | import org.springframework.web.servlet.function.ServerResponse 6 | 7 | /** 8 | * @author Kevin Davin 9 | */ 10 | @Suppress("UNUSED_PARAMETER") 11 | class UserHandler( 12 | private val repository: UserRepository, 13 | private val properties: SampleProperties 14 | ) { 15 | 16 | fun listApi(request: ServerRequest) = ServerResponse 17 | .ok() 18 | .contentType(MediaType.APPLICATION_JSON) 19 | .body(repository.findAll()) 20 | 21 | fun userApi(request: ServerRequest): ServerResponse { 22 | val user = repository.findOne(request.pathVariable("login")) 23 | 24 | return if (user != null) { 25 | ServerResponse 26 | .ok() 27 | .contentType(MediaType.APPLICATION_JSON) 28 | .body(user) 29 | } else { 30 | ServerResponse.notFound().build() 31 | } 32 | } 33 | 34 | fun conf(request: ServerRequest) = ServerResponse 35 | .ok() 36 | .body(properties.message) 37 | 38 | } 39 | -------------------------------------------------------------------------------- /samples/kofu-servlet-jooq/src/main/kotlin/com/sample/Model.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | data class User( 4 | val login: String, 5 | val firstname: String, 6 | val lastname: String 7 | ) 8 | -------------------------------------------------------------------------------- /samples/kofu-servlet-jooq/src/main/kotlin/com/sample/Properties.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | class SampleProperties(val message: String) -------------------------------------------------------------------------------- /samples/kofu-servlet-jooq/src/main/kotlin/com/sample/Routes.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.web.servlet.function.router 4 | 5 | 6 | fun routes(userHandler: UserHandler) = router { 7 | GET("/api/user", userHandler::listApi) 8 | GET("/api/user/{login}", userHandler::userApi) 9 | GET("/conf", userHandler::conf) 10 | } 11 | -------------------------------------------------------------------------------- /samples/kofu-servlet-jooq/src/main/resources/db/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS users (login varchar PRIMARY KEY, firstname varchar, lastname varchar); 2 | MERGE INTO users VALUES 3 | ('smaldini', 'Stéphane', 'Maldini'), 4 | ('sdeleuze', 'Sébastien', 'Deleuze'), 5 | ('bclozel', 'Brian', 'Clozel'); 6 | -------------------------------------------------------------------------------- /samples/kofu-servlet-jooq/src/test/kotlin/com/sample/IntegrationTests.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.junit.jupiter.api.AfterAll 4 | import org.junit.jupiter.api.BeforeAll 5 | import org.junit.jupiter.api.Test 6 | import org.springframework.context.ConfigurableApplicationContext 7 | import org.springframework.test.web.reactive.server.WebTestClient 8 | import org.springframework.test.web.reactive.server.expectBody 9 | 10 | /** 11 | * @author Kevin Davin 12 | */ 13 | class IntegrationTests { 14 | 15 | private val client = WebTestClient.bindToServer().baseUrl("http://localhost:8181").build() 16 | 17 | private lateinit var context: ConfigurableApplicationContext 18 | 19 | @BeforeAll 20 | fun beforeAll() { 21 | context = app.run(profiles = "test") 22 | } 23 | 24 | @Test 25 | fun `request for users`() { 26 | client.get().uri("/api/user").exchange() 27 | .expectStatus().is2xxSuccessful 28 | .expectBody() 29 | .isEqualTo("""[{"login":"smaldini","firstname":"Stéphane","lastname":"Maldini"},{"login":"sdeleuze","firstname":"Sébastien","lastname":"Deleuze"},{"login":"bclozel","firstname":"Brian","lastname":"Clozel"}]""") 30 | } 31 | 32 | @AfterAll 33 | fun afterAll() { 34 | context.close() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /samples/kofu-servlet-jooq/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/kofu-servlet-minimal/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.jetbrains.kotlin.jvm") version "1.6.10" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | id("org.springframework.boot") version "2.6.6" 7 | } 8 | 9 | dependencies { 10 | implementation("org.springframework.fu:spring-fu-kofu:0.5.2-SNAPSHOT") 11 | implementation("org.springframework.boot:spring-boot-starter-web") 12 | 13 | testImplementation("org.springframework.boot:spring-boot-starter-test") 14 | testImplementation("org.springframework.boot:spring-boot-starter-webflux") 15 | } 16 | 17 | repositories { 18 | mavenLocal() 19 | mavenCentral() 20 | maven("https://repo.spring.io/milestone") 21 | maven("https://repo.spring.io/snapshot") 22 | } 23 | 24 | tasks.withType { 25 | kotlinOptions { 26 | jvmTarget = "1.8" 27 | freeCompilerArgs = listOf("-Xjsr305=strict", "-Xjvm-default=enable") 28 | } 29 | } 30 | 31 | tasks.withType { 32 | useJUnitPlatform() 33 | } 34 | -------------------------------------------------------------------------------- /samples/kofu-servlet-minimal/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-servlet-minimal/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-servlet-minimal/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-servlet-minimal/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /samples/kofu-servlet-minimal/src/main/kotlin/com/sample/Application.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.fu.kofu.webApplication 4 | import org.springframework.fu.kofu.webmvc.webMvc 5 | import org.springframework.web.servlet.function.ServerRequest 6 | import org.springframework.web.servlet.function.ServerResponse.ok 7 | 8 | 9 | val app = webApplication { 10 | beans { 11 | bean() 12 | bean() 13 | } 14 | webMvc { 15 | port = if (profiles.contains("test")) 8181 else 8080 16 | router { 17 | val handler = ref() 18 | GET("/", handler::hello) 19 | GET("/api", handler::json) 20 | } 21 | converters { 22 | string() 23 | jackson() 24 | } 25 | } 26 | } 27 | 28 | 29 | fun main() { 30 | app.run() 31 | } 32 | 33 | data class Sample(val message: String) 34 | 35 | class SampleService { 36 | fun generateMessage() = "Hello world!" 37 | } 38 | 39 | @Suppress("UNUSED_PARAMETER") 40 | class SampleHandler(private val sampleService: SampleService) { 41 | fun hello(request: ServerRequest)= ok().body(sampleService.generateMessage()) 42 | fun json(request: ServerRequest) = ok().body(Sample(sampleService.generateMessage())) 43 | } 44 | 45 | -------------------------------------------------------------------------------- /samples/kofu-servlet-minimal/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/kofu-servlet-validation/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.jetbrains.kotlin.jvm") version "1.6.10" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | id("org.springframework.boot") version "2.6.6" 7 | } 8 | 9 | dependencies { 10 | implementation("org.springframework.fu:spring-fu-kofu:0.5.2-SNAPSHOT") 11 | implementation("org.springframework.boot:spring-boot-starter-web") 12 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 13 | implementation("am.ik.yavi:yavi:0.9.1") 14 | 15 | testImplementation("org.springframework.boot:spring-boot-starter-test") 16 | testImplementation("org.springframework.boot:spring-boot-starter-webflux") 17 | } 18 | 19 | repositories { 20 | mavenLocal() 21 | mavenCentral() 22 | maven("https://repo.spring.io/milestone") 23 | maven("https://repo.spring.io/snapshot") 24 | } 25 | 26 | tasks.withType { 27 | kotlinOptions { 28 | jvmTarget = "1.8" 29 | freeCompilerArgs = listOf("-Xjsr305=strict", "-Xjvm-default=enable") 30 | } 31 | } 32 | 33 | tasks.withType { 34 | useJUnitPlatform() 35 | } 36 | -------------------------------------------------------------------------------- /samples/kofu-servlet-validation/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-servlet-validation/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-servlet-validation/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-servlet-validation/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://repo.spring.io/milestone") 5 | maven("https://repo.spring.io/snapshot") 6 | } 7 | resolutionStrategy { 8 | eachPlugin { 9 | if (requested.id.id == "org.springframework.boot") { 10 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /samples/kofu-servlet-validation/src/main/kotlin/com/sample/Application.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.fu.kofu.webApplication 4 | import org.springframework.fu.kofu.webmvc.webMvc 5 | 6 | val app = webApplication { 7 | beans { 8 | bean() 9 | bean(::routes) 10 | } 11 | webMvc { 12 | port = if (profiles.contains("test")) 8181 else 8080 13 | converters { 14 | jackson() 15 | } 16 | } 17 | } 18 | 19 | fun main() { 20 | app.run() 21 | } -------------------------------------------------------------------------------- /samples/kofu-servlet-validation/src/main/kotlin/com/sample/Handlers.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.web.servlet.function.ServerRequest 4 | import org.springframework.web.servlet.function.ServerResponse.badRequest 5 | import org.springframework.web.servlet.function.ServerResponse.ok 6 | 7 | @Suppress("UNUSED_PARAMETER") 8 | class UserHandler { 9 | 10 | fun createApi(request: ServerRequest) = 11 | request.body(User::class.java) 12 | .validate() 13 | .mapError { it.detail() } 14 | .fold( 15 | { badRequest().body(mapOf("details" to it)) }, 16 | ok()::body 17 | ) 18 | } -------------------------------------------------------------------------------- /samples/kofu-servlet-validation/src/main/kotlin/com/sample/Model.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import am.ik.yavi.builder.validator 4 | import am.ik.yavi.core.Validated 5 | 6 | data class User( 7 | val login: String?, 8 | val firstname: String, 9 | val lastname: String 10 | ) { 11 | companion object { 12 | val validator = validator { 13 | User::login { 14 | notNull() 15 | greaterThanOrEqual(4) 16 | lessThanOrEqual(8) 17 | } 18 | User::firstname { 19 | notBlank() 20 | lessThanOrEqual(32) 21 | } 22 | User::lastname { 23 | notBlank() 24 | lessThanOrEqual(32) 25 | } 26 | }.applicative() 27 | } 28 | 29 | fun validate(): Validated { 30 | return validator.validate(this) 31 | } 32 | } -------------------------------------------------------------------------------- /samples/kofu-servlet-validation/src/main/kotlin/com/sample/Routes.kt: -------------------------------------------------------------------------------- 1 | package com.sample 2 | 3 | import org.springframework.web.servlet.function.router 4 | 5 | fun routes(userHandler: UserHandler) = router { 6 | POST("/api/user", userHandler::createApi) 7 | } -------------------------------------------------------------------------------- /samples/kofu-servlet-validation/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /samples/kofu-tutorial/.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 | -------------------------------------------------------------------------------- /samples/kofu-tutorial/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-tutorial/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/kofu-tutorial/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/kofu-tutorial/images/blog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-tutorial/images/blog.png -------------------------------------------------------------------------------- /samples/kofu-tutorial/images/code_completion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-tutorial/images/code_completion.png -------------------------------------------------------------------------------- /samples/kofu-tutorial/images/metadata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects-experimental/spring-fu/78a07bbf0898fa3f8cdaf3f5223d82b6edf0bbbe/samples/kofu-tutorial/images/metadata.png -------------------------------------------------------------------------------- /samples/kofu-tutorial/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "kofu-tutorial" 2 | 3 | pluginManagement { 4 | repositories { 5 | gradlePluginPortal() 6 | maven("https://repo.spring.io/milestone") 7 | maven("https://repo.spring.io/snapshot") 8 | } 9 | resolutionStrategy { 10 | eachPlugin { 11 | if (requested.id.id == "org.springframework.boot") { 12 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 13 | } 14 | } 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /samples/kofu-tutorial/src/main/kotlin/com/sample/blog/BlogProperties.kt: -------------------------------------------------------------------------------- 1 | package com.sample.blog 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties 4 | import org.springframework.boot.context.properties.ConstructorBinding 5 | 6 | @ConstructorBinding 7 | @ConfigurationProperties("blog") 8 | data class BlogProperties(val title: String, val banner: Banner) { 9 | data class Banner(val title: String? = null, val content: String) 10 | } -------------------------------------------------------------------------------- /samples/kofu-tutorial/src/main/kotlin/com/sample/blog/LiquibaseProperties.kt: -------------------------------------------------------------------------------- 1 | package com.sample.blog 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties 4 | import org.springframework.boot.context.properties.ConstructorBinding 5 | 6 | @ConstructorBinding 7 | @ConfigurationProperties("liquibase") 8 | data class LiquibaseProperties( 9 | var changelogPath: String 10 | ) -------------------------------------------------------------------------------- /samples/kofu-tutorial/src/main/kotlin/com/sample/blog/RenderedArticle.kt: -------------------------------------------------------------------------------- 1 | package com.sample.blog 2 | 3 | data class RenderedArticle( 4 | val id: Long, 5 | val slug: String, 6 | val title: String, 7 | val headline: String, 8 | val content: String, 9 | val author: RenderedUser, 10 | val addedAt: String) 11 | 12 | fun ArticleEntity.render() = RenderedArticle( 13 | id.value, 14 | info.slug, 15 | info.title, 16 | info.headline, 17 | info.content, 18 | info.author.render(), 19 | info.addedAt.format() 20 | ) -------------------------------------------------------------------------------- /samples/kofu-tutorial/src/main/kotlin/com/sample/blog/RenderedUser.kt: -------------------------------------------------------------------------------- 1 | package com.sample.blog 2 | 3 | data class RenderedUser( 4 | val id: Long, 5 | val login: String, 6 | val firstname: String, 7 | val lastname: String, 8 | val description: String?) 9 | 10 | fun UserEntity.render() = RenderedUser( 11 | id.value, 12 | info.login.value, 13 | info.name.firstname, 14 | info.name.lastname, 15 | info.description) -------------------------------------------------------------------------------- /samples/kofu-tutorial/src/main/kotlin/com/sample/blog/extensions.kt: -------------------------------------------------------------------------------- 1 | package com.sample.blog 2 | 3 | import java.time.LocalDateTime 4 | import java.time.format.DateTimeFormatterBuilder 5 | import java.time.temporal.ChronoField 6 | import java.util.* 7 | 8 | fun LocalDateTime.format(): String = this.format(englishDateFormatter) 9 | 10 | private val daysLookup = (1..31).associate { it.toLong() to getOrdinal(it) } 11 | 12 | private val englishDateFormatter = DateTimeFormatterBuilder() 13 | .appendPattern("yyyy-MM-dd") 14 | .appendLiteral(" ") 15 | .appendText(ChronoField.DAY_OF_MONTH, daysLookup) 16 | .appendLiteral(" ") 17 | .appendPattern("yyyy") 18 | .toFormatter(Locale.ENGLISH) 19 | 20 | private fun getOrdinal(n: Int) = when { 21 | n in 11..13 -> "${n}th" 22 | n % 10 == 1 -> "${n}st" 23 | n % 10 == 2 -> "${n}nd" 24 | n % 10 == 3 -> "${n}rd" 25 | else -> "${n}th" 26 | } 27 | 28 | fun String.toSlug() = lowercase() 29 | .replace("\n", " ") 30 | .replace("[^a-z\\d\\s]".toRegex(), " ") 31 | .split(" ") 32 | .joinToString("-") 33 | .replace("-+".toRegex(), "-") -------------------------------------------------------------------------------- /samples/kofu-tutorial/src/main/kotlin/com/sample/blog/repositories.kt: -------------------------------------------------------------------------------- 1 | package com.sample.blog 2 | 3 | interface UserRepository { 4 | fun save(user: Entity): UserEntity 5 | fun findAll(): Collection 6 | fun findById(id: Id): UserEntity? 7 | fun findByLogin(login: Login): UserEntity? 8 | } 9 | 10 | interface ArticleRepository { 11 | fun save(article: Entity
): ArticleEntity 12 | fun findAll(): Collection 13 | fun findAllByOrderByAddedAtDesc(): Collection 14 | fun findById(id: Id): ArticleEntity? 15 | fun findBySlug(slug: String): ArticleEntity? 16 | } 17 | -------------------------------------------------------------------------------- /samples/kofu-tutorial/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE 3 | datasource.driver=org.h2.Driver 4 | datasource.username=sa 5 | datasource.password= 6 | 7 | blog.title=Blog 8 | blog.banner.title=Warning 9 | blog.banner.content=The blog will be down tomorrow. 10 | 11 | liquibase.changelog-path=classpath:/liquibase/changelog-master.xml 12 | -------------------------------------------------------------------------------- /samples/kofu-tutorial/src/main/resources/views/article.mustache: -------------------------------------------------------------------------------- 1 | {{> header}} 2 | 3 |
4 |
5 |

{{article.title}}

6 | 7 |
8 | 9 |
10 | {{article.headline}} 11 | 12 | {{article.content}} 13 |
14 |
15 | 16 | {{> footer}} -------------------------------------------------------------------------------- /samples/kofu-tutorial/src/main/resources/views/blog.mustache: -------------------------------------------------------------------------------- 1 | {{> header}} 2 | 3 |

{{title}}

4 | 5 |
6 | 7 | {{#banner.title}} 8 |
9 | 12 | 15 |
16 | {{/banner.title}} 17 | 18 | {{#articles}} 19 |
20 |
21 |

{{title}}

22 | 23 |
24 |
25 | {{headline}} 26 |
27 |
28 | {{/articles}} 29 |
30 | 31 | {{> footer}} -------------------------------------------------------------------------------- /samples/kofu-tutorial/src/main/resources/views/footer.mustache: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /samples/kofu-tutorial/src/main/resources/views/header.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{title}} 4 | 5 | -------------------------------------------------------------------------------- /samples/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "spring-fu-samples" 2 | 3 | include( 4 | "jafu-reactive-minimal", 5 | "jafu-reactive-mongodb", 6 | "jafu-reactive-data-r2dbc", 7 | "jafu-reactive-r2dbc", 8 | "jafu-servlet-minimal", 9 | "jafu-servlet-cassandra", 10 | "kofu-coroutines-mongodb", 11 | "kofu-coroutines-minimal", 12 | "kofu-coroutines-r2dbc", 13 | "kofu-coroutines-validation", 14 | "kofu-reactive-minimal", 15 | "kofu-reactive-mongodb", 16 | "kofu-reactive-data-r2dbc", 17 | "kofu-reactive-r2dbc", 18 | "kofu-reactive-redis", 19 | "kofu-reactive-cassandra", 20 | "kofu-reactive-validation", 21 | "kofu-servlet-minimal", 22 | "kofu-servlet-validation", 23 | "kofu-tutorial" 24 | ) 25 | 26 | pluginManagement { 27 | repositories { 28 | gradlePluginPortal() 29 | maven("https://repo.spring.io/milestone") 30 | maven("https://repo.spring.io/snapshot") 31 | } 32 | resolutionStrategy { 33 | eachPlugin { 34 | if (requested.id.id == "org.springframework.boot") { 35 | useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "spring-fu-build" 2 | 3 | include( 4 | "autoconfigure-adapter", 5 | "kofu", 6 | "jafu" 7 | ) 8 | 9 | pluginManagement { 10 | repositories { 11 | gradlePluginPortal() 12 | maven("https://repo.spring.io/milestone") 13 | maven("https://repo.spring.io/snapshot") 14 | } 15 | resolutionStrategy { 16 | val bootVersion: String by settings 17 | eachPlugin { 18 | if (requested.id.id == "org.springframework.boot") { 19 | useModule("org.springframework.boot:spring-boot-gradle-plugin:$bootVersion") 20 | } 21 | } 22 | } 23 | } 24 | --------------------------------------------------------------------------------