diff --git a/.gitignore b/.gitignore index 0457317af..02407f5b9 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ build/ *.ipr out/ samples/kofu-reactive-graal/com.sample.applicationkt +samples/jafu-reactive-graal/com.sample.applicationkt diff --git a/samples/jafu-reactive-r2dbc/build.gradle.kts b/samples/jafu-reactive-r2dbc/build.gradle.kts index a5cf3408d..b2c8ec93a 100644 --- a/samples/jafu-reactive-r2dbc/build.gradle.kts +++ b/samples/jafu-reactive-r2dbc/build.gradle.kts @@ -7,11 +7,15 @@ plugins { dependencies { implementation("org.springframework.fu:spring-fu-jafu:0.0.3.BUILD-SNAPSHOT") + implementation("org.apache.logging.log4j:log4j-to-slf4j") + implementation("org.slf4j", "jul-to-slf4j") + implementation("org.slf4j", "slf4j-jdk14") + implementation("org.springframework.boot:spring-boot-starter-webflux") implementation("org.springframework.boot:spring-boot-starter-mustache") implementation("org.springframework.data:spring-data-r2dbc:1.0.0.BUILD-SNAPSHOT") - implementation("io.r2dbc:r2dbc-spi:1.0.0.M5") - implementation("io.r2dbc:r2dbc-postgresql:1.0.0.M5") + implementation("io.r2dbc:r2dbc-spi:1.0.0.BUILD-SNAPSHOT") + implementation("io.r2dbc:r2dbc-postgresql:1.0.0.BUILD-SNAPSHOT") testImplementation("org.junit.jupiter:junit-jupiter-api") testImplementation("org.springframework:spring-test") @@ -25,3 +29,11 @@ repositories { maven("https://repo.spring.io/milestone") maven("https://repo.spring.io/snapshot") } + +configurations.all { + exclude(module = "netty-transport-native-epoll") + exclude(module = "netty-transport-native-unix-common") + exclude(module = "netty-codec-http2") + exclude(module = "hibernate-validator") + exclude(module = "spring-boot-starter-logging") +} diff --git a/samples/jafu-reactive-r2dbc/build.sh b/samples/jafu-reactive-r2dbc/build.sh new file mode 100755 index 000000000..4cb07b48d --- /dev/null +++ b/samples/jafu-reactive-r2dbc/build.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +./gradlew clean build --refresh-dependencies +unzip build/libs/jafu-reactive-r2dbc.jar -d build/libs/jafu-reactive-r2dbc + +native-image -H:IncludeResources='META-INF/.*.json|META-INF/spring.factories|org/springframework/boot/logging/.*' --allow-incomplete-classpath --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/log4j.json,graal/netty.json -Dio.netty.noUnsafe=true -H:+ReportUnsupportedElementsAtRuntime -Dfile.encoding=UTF-8 -cp ".:$(echo build/libs/jafu-reactive-r2dbc/BOOT-INF/lib/*.jar | tr ' ' ':')":build/libs/jafu-reactive-r2dbc/BOOT-INF/classes com.sample.Application diff --git a/samples/jafu-reactive-r2dbc/graal/app.json b/samples/jafu-reactive-r2dbc/graal/app.json new file mode 100644 index 000000000..ab8521396 --- /dev/null +++ b/samples/jafu-reactive-r2dbc/graal/app.json @@ -0,0 +1,23 @@ +[ + { + "name": "com.sample.UserRepository", + "methods": [ + { "name": "", "parameterTypes": ["org.springframework.data.r2dbc.function.DatabaseClient"] } + ] + }, + { + "name": "com.sample.UserHandler", + "methods": [ + { "name": "", "parameterTypes": ["com.sample.UserRepository"] } + ] + }, + { + "name": "com.sample.User", + "allDeclaredConstructors" : true, + "allPublicConstructors" : true, + "allPublicFields": true, + "allPublicMethods": true, + "allDeclaredMethods": true, + "allDeclaredFields": true + } +] \ No newline at end of file diff --git a/samples/jafu-reactive-r2dbc/graal/boot.json b/samples/jafu-reactive-r2dbc/graal/boot.json new file mode 100644 index 000000000..6d117c226 --- /dev/null +++ b/samples/jafu-reactive-r2dbc/graal/boot.json @@ -0,0 +1,219 @@ +[ + { + "name": "org.springframework.boot.env.PropertiesPropertySourceLoader", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.env.YamlPropertySourceLoader", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.context.event.EventPublishingRunListener", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.FailureAnalyzers", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.context.ContextIdApplicationContextInitializer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.context.config.DelegatingApplicationContextInitializer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.ClearCachesApplicationListener", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.builder.ParentContextCloserApplicationListener", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.context.FileEncodingApplicationListener", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.context.config.AnsiOutputApplicationListener", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.context.config.ConfigFileApplicationListener", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.context.config.DelegatingApplicationListener", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.context.logging.ClasspathLoggingApplicationListener", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.context.logging.LoggingApplicationListener", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.analyzer.BeanDefinitionOverrideFailureAnalyzer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer$SharedMetadataReaderFactoryBean", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.autoconfigure.BackgroundPreinitializer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.autoconfigure.condition.OnClassCondition", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider", + "allDeclaredConstructors": true + }, + { + "name": "org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext", + "methods": [ + { "name": "", "parameterTypes": [] } + ] + }, + { + "name": "org.springframework.boot.logging.java.JavaLoggingSystem", + "allDeclaredConstructors" : true, + "allPublicConstructors" : true, + "allPublicFields": true, + "allPublicMethods": true, + "allDeclaredMethods": true, + "allDeclaredFields": true + }, + { + "name": "java.util.logging.ConsoleHandler", + "allDeclaredConstructors" : true, + "allPublicConstructors" : true, + "allPublicFields": true, + "allPublicMethods": true, + "allDeclaredMethods": true, + "allDeclaredFields": true + } +] diff --git a/samples/jafu-reactive-r2dbc/graal/framework.json b/samples/jafu-reactive-r2dbc/graal/framework.json new file mode 100644 index 000000000..4d1bcbbde --- /dev/null +++ b/samples/jafu-reactive-r2dbc/graal/framework.json @@ -0,0 +1,20 @@ +[ + { + "name": "org.springframework.context.support.GenericApplicationContext", + "methods": [ + { "name": "", "parameterTypes": [] } + ] + }, + { + "name": "org.springframework.context.annotation.ConfigurationClassPostProcessor", + "methods": [ + { "name": "", "parameterTypes": [] } + ] + }, + { + "name": "org.springframework.http.codec.support.DefaultServerCodecConfigurer", + "methods": [ + { "name": "", "parameterTypes": [] } + ] + } +] \ No newline at end of file diff --git a/samples/jafu-reactive-r2dbc/graal/log4j.json b/samples/jafu-reactive-r2dbc/graal/log4j.json new file mode 100644 index 000000000..bfd076984 --- /dev/null +++ b/samples/jafu-reactive-r2dbc/graal/log4j.json @@ -0,0 +1,20 @@ +[ + { + "name": "org.apache.logging.log4j.message.ReusableMessageFactory", + "methods": [ + { "name": "", "parameterTypes": [] } + ] + }, + { + "name": "org.apache.logging.log4j.message.DefaultFlowMessageFactory", + "methods": [ + { "name": "", "parameterTypes": [] } + ] + }, + { + "name": "org.apache.logging.log4j.message.ParameterizedMessageFactory", + "methods": [ + { "name": "", "parameterTypes": [] } + ] + } +] \ No newline at end of file diff --git a/samples/jafu-reactive-r2dbc/graal/netty.json b/samples/jafu-reactive-r2dbc/graal/netty.json new file mode 100644 index 000000000..b53be8f75 --- /dev/null +++ b/samples/jafu-reactive-r2dbc/graal/netty.json @@ -0,0 +1,14 @@ +[ + { + "name": "io.netty.channel.socket.nio.NioServerSocketChannel", + "methods": [ + { "name": "", "parameterTypes": [] } + ] + }, + { + "name": "io.netty.channel.socket.nio.NioSocketChannel", + "methods": [ + { "name": "", "parameterTypes": [] } + ] + } +] \ No newline at end of file diff --git a/samples/jafu-reactive-r2dbc/src/main/java/com/sample/Application.java b/samples/jafu-reactive-r2dbc/src/main/java/com/sample/Application.java index 8a3edc151..942aeba76 100644 --- a/samples/jafu-reactive-r2dbc/src/main/java/com/sample/Application.java +++ b/samples/jafu-reactive-r2dbc/src/main/java/com/sample/Application.java @@ -10,11 +10,11 @@ public abstract class Application { public static ApplicationDsl app = application(app -> app.importConfiguration(Configurations.dataConfig) .importConfiguration(Configurations.webConfig) - .properties(SampleProperties.class, "sample") .listener(ApplicationReadyEvent.class, e -> app.ref(UserRepository.class).init()) ); public static void main (String[] args) { + System.setProperty("org.springframework.boot.logging.LoggingSystem", "org.springframework.boot.logging.java.JavaLoggingSystem"); app.run(args); } } diff --git a/samples/jafu-reactive-r2dbc/src/main/java/com/sample/Configurations.java b/samples/jafu-reactive-r2dbc/src/main/java/com/sample/Configurations.java index e203f401c..872aa5b08 100644 --- a/samples/jafu-reactive-r2dbc/src/main/java/com/sample/Configurations.java +++ b/samples/jafu-reactive-r2dbc/src/main/java/com/sample/Configurations.java @@ -20,11 +20,8 @@ public abstract class Configurations { } server.router(router -> { UserHandler userHandler = conf.ref(UserHandler.class); - router - .GET("/", userHandler::listView) - .GET("/api/user", userHandler::listApi) - .GET("/conf", userHandler::conf); - }).codecs(codecs -> codecs.string().jackson()).mustache(); + router.GET("/", userHandler::listApi); + }).codecs(codecs -> codecs.string().jackson()); }); }; } diff --git a/samples/jafu-reactive-r2dbc/src/main/java/com/sample/SampleProperties.java b/samples/jafu-reactive-r2dbc/src/main/java/com/sample/SampleProperties.java deleted file mode 100644 index ef3ae5908..000000000 --- a/samples/jafu-reactive-r2dbc/src/main/java/com/sample/SampleProperties.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.sample; - -public class SampleProperties { - - private String message; - - public SampleProperties() { - } - - public SampleProperties(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } -} \ No newline at end of file diff --git a/samples/jafu-reactive-r2dbc/src/main/java/com/sample/User.java b/samples/jafu-reactive-r2dbc/src/main/java/com/sample/User.java index faef94666..a1deb4902 100644 --- a/samples/jafu-reactive-r2dbc/src/main/java/com/sample/User.java +++ b/samples/jafu-reactive-r2dbc/src/main/java/com/sample/User.java @@ -40,4 +40,13 @@ public void setFirstname(String firstname) { public void setLastname(String lastname) { this.lastname = lastname; } + + @Override + public String toString() { + return "User{" + + "login='" + login + '\'' + + ", firstname='" + firstname + '\'' + + ", lastname='" + lastname + '\'' + + '}'; + } } diff --git a/samples/jafu-reactive-r2dbc/src/main/java/com/sample/UserHandler.java b/samples/jafu-reactive-r2dbc/src/main/java/com/sample/UserHandler.java index 8c2a5390b..250ff70fe 100644 --- a/samples/jafu-reactive-r2dbc/src/main/java/com/sample/UserHandler.java +++ b/samples/jafu-reactive-r2dbc/src/main/java/com/sample/UserHandler.java @@ -1,7 +1,5 @@ package com.sample; -import java.util.Collections; - import reactor.core.publisher.Mono; import org.springframework.http.MediaType; @@ -12,11 +10,8 @@ public class UserHandler { private final UserRepository repository; - private final SampleProperties properties; - - public UserHandler(UserRepository repository, SampleProperties properties) { + public UserHandler(UserRepository repository) { this.repository = repository; - this.properties = properties; } public Mono listApi(ServerRequest request) { @@ -25,14 +20,4 @@ public Mono listApi(ServerRequest request) { .body(repository.findAll(), User.class); } - public Mono listView(ServerRequest request) { - return ServerResponse.ok().render("users", Collections.singletonMap("users", repository.findAll())); - } - - - - public Mono conf(ServerRequest request) { - return ServerResponse.ok().syncBody(properties.getMessage()); - } - } diff --git a/samples/jafu-reactive-r2dbc/src/main/java/com/sample/UserRepository.java b/samples/jafu-reactive-r2dbc/src/main/java/com/sample/UserRepository.java index b396f7a98..1707437fd 100644 --- a/samples/jafu-reactive-r2dbc/src/main/java/com/sample/UserRepository.java +++ b/samples/jafu-reactive-r2dbc/src/main/java/com/sample/UserRepository.java @@ -1,25 +1,16 @@ package com.sample; -import java.io.IOException; -import java.util.List; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import org.springframework.core.io.ClassPathResource; import org.springframework.data.r2dbc.function.DatabaseClient; public class UserRepository { private final DatabaseClient client; - private final ObjectMapper objectMapper; - - public UserRepository(DatabaseClient client, ObjectMapper objectMapper) { + public UserRepository(DatabaseClient client) { this.client = client; - this.objectMapper = objectMapper; } public Mono count() { @@ -44,14 +35,10 @@ public Mono save(User user) { } public void init() { - client.execute().sql("CREATE TABLE IF NOT EXISTS users (login varchar PRIMARY KEY, firstname varchar, lastname varchar);").fetch().one().block(); - deleteAll().block(); - ClassPathResource eventsResource = new ClassPathResource("data/users.json"); - try { - List users = this.objectMapper.readValue(eventsResource.getInputStream(), new TypeReference>() {}); - for (User user : users) { - save(user).subscribe(); - } - } catch(IOException ex) { } + client.execute().sql("CREATE TABLE IF NOT EXISTS users (login varchar PRIMARY KEY, firstname varchar, lastname varchar);").fetch().one().block(); + deleteAll().block(); + save(new User("smaldini", "Stéphane","Maldini")).block(); + save(new User("sdeleuze", "Sébastien","Deleuze")).block(); + save(new User("bclozel", "Brian","Clozel")).block(); } } diff --git a/samples/jafu-reactive-r2dbc/src/main/resources/application.properties b/samples/jafu-reactive-r2dbc/src/main/resources/application.properties deleted file mode 100644 index a7a858a11..000000000 --- a/samples/jafu-reactive-r2dbc/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -sample.message=hello \ No newline at end of file diff --git a/samples/jafu-reactive-r2dbc/src/main/resources/data/users.json b/samples/jafu-reactive-r2dbc/src/main/resources/data/users.json deleted file mode 100644 index a185cb39f..000000000 --- a/samples/jafu-reactive-r2dbc/src/main/resources/data/users.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "login": "smaldini", - "firstname": "Stéphane", - "lastname": "Maldini" - }, - { - "login": "sdeleuze", - "firstname": "Sébastien", - "lastname": "Deleuze" - }, - { - "login": "bclozel", - "firstname": "Brian", - "lastname": "Clozel" - } -] \ No newline at end of file diff --git a/samples/jafu-reactive-r2dbc/src/main/resources/templates/footer.mustache b/samples/jafu-reactive-r2dbc/src/main/resources/templates/footer.mustache deleted file mode 100644 index 691287b6e..000000000 --- a/samples/jafu-reactive-r2dbc/src/main/resources/templates/footer.mustache +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/samples/jafu-reactive-r2dbc/src/main/resources/templates/header.mustache b/samples/jafu-reactive-r2dbc/src/main/resources/templates/header.mustache deleted file mode 100644 index f7d8d2172..000000000 --- a/samples/jafu-reactive-r2dbc/src/main/resources/templates/header.mustache +++ /dev/null @@ -1,5 +0,0 @@ - - - Spring Fu simple webapp - - \ No newline at end of file diff --git a/samples/jafu-reactive-r2dbc/src/main/resources/templates/users.mustache b/samples/jafu-reactive-r2dbc/src/main/resources/templates/users.mustache deleted file mode 100644 index b6b447aac..000000000 --- a/samples/jafu-reactive-r2dbc/src/main/resources/templates/users.mustache +++ /dev/null @@ -1,9 +0,0 @@ -{{> header}} - -
    -{{#users}} -
  • User {{login}}: {{firstname}} {{lastname}}
  • -{{/users}} -
- -{{> footer}} \ No newline at end of file diff --git a/samples/jafu-reactive-r2dbc/src/test/java/com/sample/IntegrationTests.java b/samples/jafu-reactive-r2dbc/src/test/java/com/sample/IntegrationTests.java index 355265a5c..f1bbb5536 100644 --- a/samples/jafu-reactive-r2dbc/src/test/java/com/sample/IntegrationTests.java +++ b/samples/jafu-reactive-r2dbc/src/test/java/com/sample/IntegrationTests.java @@ -19,26 +19,13 @@ void beforeAll() { context = Application.app.run("test"); } - @Test - void requestHTMLEndpoint() { - client.get().uri("/").exchange() - .expectStatus().is2xxSuccessful() - .expectHeader().contentType("text/html;charset=UTF-8"); - } - @Test void requestHttpApiEndpoint() { - client.get().uri("/api/user").exchange() + client.get().uri("/").exchange() .expectStatus().is2xxSuccessful() .expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE); } - @Test - void requestConfEndpoint() { - client.get().uri("/conf").exchange() - .expectStatus().is2xxSuccessful() - .expectHeader().contentType("text/plain;charset=UTF-8"); - } @AfterAll void afterAll() {