diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 5008ddfcf..000000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..293ec1445 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +# EditorConfig is awesome: http://EditorConfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 2 + +[*.java] +indent_size = 4 + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore index 7fcd199f6..1b117bfe4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,36 @@ +### OSX ### +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + + +/build/ +/bin/ +/doc/ +# Created by https://www.gitignore.io + /build/ /bin/ # Created by https://www.gitignore.io @@ -5,6 +38,7 @@ sigar-lib/ tomcat.8080/ tomcat.8081/ +/.groovy/ ### Eclipse ### *.pydevproject @@ -76,6 +110,7 @@ local.properties ## Plugin-specific files: # IntelliJ +.idea/ out/ # mpeltonen/sbt-idea plugin @@ -113,3 +148,5 @@ gradle-app.setting hs_err_pid* +# Package jar files are excluded but gradle-wrapper is required. +!/gradle/wrapper/gradle-wrapper.jar diff --git a/.gradletasknamecache b/.gradletasknamecache new file mode 100644 index 000000000..320b29b4e --- /dev/null +++ b/.gradletasknamecache @@ -0,0 +1,2550 @@ +micro-application-register:assemble +micro-application-register:signArchives +micro-async-data-loader:assemble +micro-async-data-loader:signArchives +micro-async-data-writer:assemble +micro-async-data-writer:signArchives +micro-boot:assemble +micro-boot:signArchives +micro-client:assemble +micro-client:signArchives +micro-core:assemble +micro-core:signArchives +micro-cors:assemble +micro-cors:signArchives +micro-couchbase:assemble +micro-couchbase:signArchives +micro-curator:assemble +micro-curator:signArchives +micro-dbcp:assemble +micro-dbcp:signArchives +micro-dist-lock:assemble +micro-dist-lock:signArchives +micro-error-codes:assemble +micro-error-codes:signArchives +micro-event-metrics:assemble +micro-event-metrics:signArchives +micro-events:assemble +micro-events:signArchives +micro-general-exception-mapper:assemble +micro-general-exception-mapper:signArchives +micro-grizzly:assemble +micro-grizzly:signArchives +micro-grizzly-with-jersey:assemble +micro-grizzly-with-jersey:signArchives +micro-guava:assemble +micro-guava:signArchives +micro-hibernate:assemble +micro-hibernate:signArchives +micro-hikaricp:assemble +micro-hikaricp:signArchives +micro-ip-tracker:assemble +micro-ip-tracker:signArchives +micro-jackson-configuration:assemble +micro-jackson-configuration:signArchives +micro-javaslang:assemble +micro-javaslang:signArchives +micro-jdbc:assemble +micro-jdbc:signArchives +micro-jersey:assemble +micro-jersey:signArchives +micro-jmx-metrics:assemble +micro-jmx-metrics:signArchives +micro-log-streamer:assemble +micro-log-streamer:signArchives +micro-log4j:assemble +micro-log4j:signArchives +micro-logback:assemble +micro-logback:signArchives +micro-machine-stats:assemble +micro-machine-stats:signArchives +micro-manifest-comparator:assemble +micro-manifest-comparator:signArchives +micro-metrics:assemble +micro-metrics:signArchives +micro-metrics-datadog:assemble +micro-metrics-datadog:signArchives +micro-mysql:assemble +micro-mysql:signArchives +micro-reactive:assemble +micro-reactive:signArchives +micro-s3:assemble +micro-s3:signArchives +micro-spring-boot:assemble +micro-spring-boot:signArchives +micro-swagger:assemble +micro-swagger:signArchives +micro-tomcat:assemble +micro-tomcat:signArchives +micro-tomcat-with-jersey:assemble +micro-tomcat-with-jersey:signArchives +micro-transactions:assemble +micro-transactions:signArchives +micro-tutorial:assemble +micro-tutorial:signArchives +micro-application-register:build +micro-async-data-loader:build +micro-async-data-writer:build +micro-boot:build +micro-client:build +micro-core:build +micro-cors:build +micro-couchbase:build +micro-curator:build +micro-dbcp:build +micro-dist-lock:build +micro-error-codes:build +micro-event-metrics:build +micro-events:build +micro-general-exception-mapper:build +micro-grizzly:build +micro-grizzly-with-jersey:build +micro-guava:build +micro-hibernate:build +micro-hikaricp:build +micro-ip-tracker:build +micro-jackson-configuration:build +micro-javaslang:build +micro-jdbc:build +micro-jersey:build +micro-jmx-metrics:build +micro-log-streamer:build +micro-log4j:build +micro-logback:build +micro-machine-stats:build +micro-manifest-comparator:build +micro-metrics:build +micro-metrics-datadog:build +micro-mysql:build +micro-reactive:build +micro-s3:build +micro-spring-boot:build +micro-swagger:build +micro-tomcat:build +micro-tomcat-with-jersey:build +micro-transactions:build +micro-tutorial:build +micro-application-register:buildDependents +micro-async-data-loader:buildDependents +micro-async-data-writer:buildDependents +micro-boot:buildDependents +micro-client:buildDependents +micro-core:buildDependents +micro-cors:buildDependents +micro-couchbase:buildDependents +micro-curator:buildDependents +micro-dbcp:buildDependents +micro-dist-lock:buildDependents +micro-error-codes:buildDependents +micro-event-metrics:buildDependents +micro-events:buildDependents +micro-general-exception-mapper:buildDependents +micro-grizzly:buildDependents +micro-grizzly-with-jersey:buildDependents +micro-guava:buildDependents +micro-hibernate:buildDependents +micro-hikaricp:buildDependents +micro-ip-tracker:buildDependents +micro-jackson-configuration:buildDependents +micro-javaslang:buildDependents +micro-jdbc:buildDependents +micro-jersey:buildDependents +micro-jmx-metrics:buildDependents +micro-log-streamer:buildDependents +micro-log4j:buildDependents +micro-logback:buildDependents +micro-machine-stats:buildDependents +micro-manifest-comparator:buildDependents +micro-metrics:buildDependents +micro-metrics-datadog:buildDependents +micro-mysql:buildDependents +micro-reactive:buildDependents +micro-s3:buildDependents +micro-spring-boot:buildDependents +micro-swagger:buildDependents +micro-tomcat:buildDependents +micro-tomcat-with-jersey:buildDependents +micro-transactions:buildDependents +micro-tutorial:buildDependents +micro-application-register:buildNeeded +micro-async-data-loader:buildNeeded +micro-async-data-writer:buildNeeded +micro-boot:buildNeeded +micro-client:buildNeeded +micro-core:buildNeeded +micro-cors:buildNeeded +micro-couchbase:buildNeeded +micro-curator:buildNeeded +micro-dbcp:buildNeeded +micro-dist-lock:buildNeeded +micro-error-codes:buildNeeded +micro-event-metrics:buildNeeded +micro-events:buildNeeded +micro-general-exception-mapper:buildNeeded +micro-grizzly:buildNeeded +micro-grizzly-with-jersey:buildNeeded +micro-guava:buildNeeded +micro-hibernate:buildNeeded +micro-hikaricp:buildNeeded +micro-ip-tracker:buildNeeded +micro-jackson-configuration:buildNeeded +micro-javaslang:buildNeeded +micro-jdbc:buildNeeded +micro-jersey:buildNeeded +micro-jmx-metrics:buildNeeded +micro-log-streamer:buildNeeded +micro-log4j:buildNeeded +micro-logback:buildNeeded +micro-machine-stats:buildNeeded +micro-manifest-comparator:buildNeeded +micro-metrics:buildNeeded +micro-metrics-datadog:buildNeeded +micro-mysql:buildNeeded +micro-reactive:buildNeeded +micro-s3:buildNeeded +micro-spring-boot:buildNeeded +micro-swagger:buildNeeded +micro-tomcat:buildNeeded +micro-tomcat-with-jersey:buildNeeded +micro-transactions:buildNeeded +micro-tutorial:buildNeeded +micro-application-register:classes +micro-application-register:compileJava +micro-application-register:processResources +micro-async-data-loader:classes +micro-async-data-loader:compileJava +micro-async-data-loader:processResources +micro-async-data-writer:classes +micro-async-data-writer:compileJava +micro-async-data-writer:processResources +micro-boot:classes +micro-boot:compileJava +micro-boot:processResources +micro-client:classes +micro-client:compileJava +micro-client:processResources +micro-core:classes +micro-core:compileJava +micro-core:processResources +micro-cors:classes +micro-cors:compileJava +micro-cors:processResources +micro-couchbase:classes +micro-couchbase:compileGroovy +micro-couchbase:compileJava +micro-couchbase:processResources +micro-curator:classes +micro-curator:compileJava +micro-curator:processResources +micro-dbcp:classes +micro-dbcp:compileJava +micro-dbcp:processResources +micro-dist-lock:classes +micro-dist-lock:compileJava +micro-dist-lock:processResources +micro-error-codes:classes +micro-error-codes:compileJava +micro-error-codes:processResources +micro-event-metrics:classes +micro-event-metrics:compileJava +micro-event-metrics:processResources +micro-events:classes +micro-events:compileJava +micro-events:processResources +micro-general-exception-mapper:classes +micro-general-exception-mapper:compileJava +micro-general-exception-mapper:processResources +micro-grizzly:classes +micro-grizzly:compileJava +micro-grizzly:processResources +micro-grizzly-with-jersey:classes +micro-grizzly-with-jersey:compileJava +micro-grizzly-with-jersey:processResources +micro-guava:classes +micro-guava:compileJava +micro-guava:processResources +micro-hibernate:classes +micro-hibernate:compileJava +micro-hibernate:processResources +micro-hikaricp:classes +micro-hikaricp:compileJava +micro-hikaricp:processResources +micro-ip-tracker:classes +micro-ip-tracker:compileJava +micro-ip-tracker:processResources +micro-jackson-configuration:classes +micro-jackson-configuration:compileJava +micro-jackson-configuration:processResources +micro-javaslang:classes +micro-javaslang:compileJava +micro-javaslang:processResources +micro-jdbc:classes +micro-jdbc:compileJava +micro-jdbc:processResources +micro-jersey:classes +micro-jersey:compileJava +micro-jersey:processResources +micro-jmx-metrics:classes +micro-jmx-metrics:compileJava +micro-jmx-metrics:processResources +micro-log-streamer:classes +micro-log-streamer:compileJava +micro-log-streamer:processResources +micro-log4j:classes +micro-log4j:compileJava +micro-log4j:processResources +micro-logback:classes +micro-logback:compileJava +micro-logback:processResources +micro-machine-stats:classes +micro-machine-stats:compileJava +micro-machine-stats:processResources +micro-manifest-comparator:classes +micro-manifest-comparator:compileJava +micro-manifest-comparator:processResources +micro-metrics:classes +micro-metrics:compileJava +micro-metrics:processResources +micro-metrics-datadog:classes +micro-metrics-datadog:compileJava +micro-metrics-datadog:processResources +micro-mysql:classes +micro-mysql:compileJava +micro-mysql:processResources +micro-reactive:classes +micro-reactive:compileJava +micro-reactive:processResources +micro-s3:classes +micro-s3:compileJava +micro-s3:processResources +micro-spring-boot:classes +micro-spring-boot:compileJava +micro-spring-boot:processResources +micro-swagger:classes +micro-swagger:compileJava +micro-swagger:processResources +micro-tomcat:classes +micro-tomcat:compileJava +micro-tomcat:processResources +micro-tomcat-with-jersey:classes +micro-tomcat-with-jersey:compileJava +micro-tomcat-with-jersey:processResources +micro-transactions:classes +micro-transactions:compileJava +micro-transactions:processResources +micro-tutorial:classes +micro-tutorial:compileJava +micro-tutorial:processResources +micro-application-register:clean +micro-async-data-loader:clean +micro-async-data-writer:clean +micro-boot:clean +micro-client:clean +micro-core:clean +micro-cors:clean +micro-couchbase:clean +micro-curator:clean +micro-dbcp:clean +micro-dist-lock:clean +micro-error-codes:clean +micro-event-metrics:clean +micro-events:clean +micro-general-exception-mapper:clean +micro-grizzly:clean +micro-grizzly-with-jersey:clean +micro-guava:clean +micro-hibernate:clean +micro-hikaricp:clean +micro-ip-tracker:clean +micro-jackson-configuration:clean +micro-javaslang:clean +micro-jdbc:clean +micro-jersey:clean +micro-jmx-metrics:clean +micro-log-streamer:clean +micro-log4j:clean +micro-logback:clean +micro-machine-stats:clean +micro-manifest-comparator:clean +micro-metrics:clean +micro-metrics-datadog:clean +micro-mysql:clean +micro-reactive:clean +micro-s3:clean +micro-spring-boot:clean +micro-swagger:clean +micro-tomcat:clean +micro-tomcat-with-jersey:clean +micro-transactions:clean +micro-tutorial:clean +micro-curator:integTestClasses +micro-curator:compileIntegTestJava +micro-curator:processIntegTestResources +micro-application-register:jar +micro-async-data-loader:jar +micro-async-data-writer:jar +micro-boot:jar +micro-client:jar +micro-core:jar +micro-cors:jar +micro-couchbase:jar +micro-curator:jar +micro-dbcp:jar +micro-dist-lock:jar +micro-error-codes:jar +micro-event-metrics:jar +micro-events:jar +micro-general-exception-mapper:jar +micro-grizzly:jar +micro-grizzly-with-jersey:jar +micro-guava:jar +micro-hibernate:jar +micro-hikaricp:jar +micro-ip-tracker:jar +micro-jackson-configuration:jar +micro-javaslang:jar +micro-jdbc:jar +micro-jersey:jar +micro-jmx-metrics:jar +micro-log-streamer:jar +micro-log4j:jar +micro-logback:jar +micro-machine-stats:jar +micro-manifest-comparator:jar +micro-metrics:jar +micro-metrics-datadog:jar +micro-mysql:jar +micro-reactive:jar +micro-s3:jar +micro-spring-boot:jar +micro-swagger:jar +micro-tomcat:jar +micro-tomcat-with-jersey:jar +micro-transactions:jar +micro-tutorial:jar +micro-application-register:javadocJar +micro-async-data-loader:javadocJar +micro-async-data-writer:javadocJar +micro-boot:javadocJar +micro-client:javadocJar +micro-core:javadocJar +micro-cors:javadocJar +micro-couchbase:javadocJar +micro-curator:javadocJar +micro-dbcp:javadocJar +micro-dist-lock:javadocJar +micro-error-codes:javadocJar +micro-event-metrics:javadocJar +micro-events:javadocJar +micro-general-exception-mapper:javadocJar +micro-grizzly:javadocJar +micro-grizzly-with-jersey:javadocJar +micro-guava:javadocJar +micro-hibernate:javadocJar +micro-hikaricp:javadocJar +micro-ip-tracker:javadocJar +micro-jackson-configuration:javadocJar +micro-javaslang:javadocJar +micro-jdbc:javadocJar +micro-jersey:javadocJar +micro-jmx-metrics:javadocJar +micro-log-streamer:javadocJar +micro-log4j:javadocJar +micro-logback:javadocJar +micro-machine-stats:javadocJar +micro-manifest-comparator:javadocJar +micro-metrics:javadocJar +micro-metrics-datadog:javadocJar +micro-mysql:javadocJar +micro-reactive:javadocJar +micro-s3:javadocJar +micro-spring-boot:javadocJar +micro-swagger:javadocJar +micro-tomcat:javadocJar +micro-tomcat-with-jersey:javadocJar +micro-transactions:javadocJar +micro-tutorial:javadocJar +micro-application-register:sourcesJar +micro-async-data-loader:sourcesJar +micro-async-data-writer:sourcesJar +micro-boot:sourcesJar +micro-client:sourcesJar +micro-core:sourcesJar +micro-cors:sourcesJar +micro-couchbase:sourcesJar +micro-curator:sourcesJar +micro-dbcp:sourcesJar +micro-dist-lock:sourcesJar +micro-error-codes:sourcesJar +micro-event-metrics:sourcesJar +micro-events:sourcesJar +micro-general-exception-mapper:sourcesJar +micro-grizzly:sourcesJar +micro-grizzly-with-jersey:sourcesJar +micro-guava:sourcesJar +micro-hibernate:sourcesJar +micro-hikaricp:sourcesJar +micro-ip-tracker:sourcesJar +micro-jackson-configuration:sourcesJar +micro-javaslang:sourcesJar +micro-jdbc:sourcesJar +micro-jersey:sourcesJar +micro-jmx-metrics:sourcesJar +micro-log-streamer:sourcesJar +micro-log4j:sourcesJar +micro-logback:sourcesJar +micro-machine-stats:sourcesJar +micro-manifest-comparator:sourcesJar +micro-metrics:sourcesJar +micro-metrics-datadog:sourcesJar +micro-mysql:sourcesJar +micro-reactive:sourcesJar +micro-s3:sourcesJar +micro-spring-boot:sourcesJar +micro-swagger:sourcesJar +micro-tomcat:sourcesJar +micro-tomcat-with-jersey:sourcesJar +micro-transactions:sourcesJar +micro-tutorial:sourcesJar +micro-application-register:testClasses +micro-application-register:compileTestJava +micro-application-register:processTestResources +micro-async-data-loader:testClasses +micro-async-data-loader:compileTestJava +micro-async-data-loader:processTestResources +micro-async-data-writer:testClasses +micro-async-data-writer:compileTestJava +micro-async-data-writer:processTestResources +micro-boot:testClasses +micro-boot:compileTestJava +micro-boot:processTestResources +micro-client:testClasses +micro-client:compileTestJava +micro-client:processTestResources +micro-core:testClasses +micro-core:compileTestJava +micro-core:processTestResources +micro-cors:testClasses +micro-cors:compileTestJava +micro-cors:processTestResources +micro-couchbase:testClasses +micro-couchbase:compileTestGroovy +micro-couchbase:compileTestJava +micro-couchbase:processTestResources +micro-curator:testClasses +micro-curator:compileTestJava +micro-curator:processTestResources +micro-dbcp:testClasses +micro-dbcp:compileTestJava +micro-dbcp:processTestResources +micro-dist-lock:testClasses +micro-dist-lock:compileTestJava +micro-dist-lock:processTestResources +micro-error-codes:testClasses +micro-error-codes:compileTestJava +micro-error-codes:processTestResources +micro-event-metrics:testClasses +micro-event-metrics:compileTestJava +micro-event-metrics:processTestResources +micro-events:testClasses +micro-events:compileTestJava +micro-events:processTestResources +micro-general-exception-mapper:testClasses +micro-general-exception-mapper:compileTestJava +micro-general-exception-mapper:processTestResources +micro-grizzly:testClasses +micro-grizzly:compileTestJava +micro-grizzly:processTestResources +micro-grizzly-with-jersey:testClasses +micro-grizzly-with-jersey:compileTestJava +micro-grizzly-with-jersey:processTestResources +micro-guava:testClasses +micro-guava:compileTestJava +micro-guava:processTestResources +micro-hibernate:testClasses +micro-hibernate:compileTestJava +micro-hibernate:processTestResources +micro-hikaricp:testClasses +micro-hikaricp:compileTestJava +micro-hikaricp:processTestResources +micro-ip-tracker:testClasses +micro-ip-tracker:compileTestJava +micro-ip-tracker:processTestResources +micro-jackson-configuration:testClasses +micro-jackson-configuration:compileTestJava +micro-jackson-configuration:processTestResources +micro-javaslang:testClasses +micro-javaslang:compileTestJava +micro-javaslang:processTestResources +micro-jdbc:testClasses +micro-jdbc:compileTestJava +micro-jdbc:processTestResources +micro-jersey:testClasses +micro-jersey:compileTestJava +micro-jersey:processTestResources +micro-jmx-metrics:testClasses +micro-jmx-metrics:compileTestJava +micro-jmx-metrics:processTestResources +micro-log-streamer:testClasses +micro-log-streamer:compileTestJava +micro-log-streamer:processTestResources +micro-log4j:testClasses +micro-log4j:compileTestJava +micro-log4j:processTestResources +micro-logback:testClasses +micro-logback:compileTestJava +micro-logback:processTestResources +micro-machine-stats:testClasses +micro-machine-stats:compileTestJava +micro-machine-stats:processTestResources +micro-manifest-comparator:testClasses +micro-manifest-comparator:compileTestJava +micro-manifest-comparator:processTestResources +micro-metrics:testClasses +micro-metrics:compileTestJava +micro-metrics:processTestResources +micro-metrics-datadog:testClasses +micro-metrics-datadog:compileTestJava +micro-metrics-datadog:processTestResources +micro-mysql:testClasses +micro-mysql:compileTestJava +micro-mysql:processTestResources +micro-reactive:testClasses +micro-reactive:compileTestJava +micro-reactive:processTestResources +micro-s3:testClasses +micro-s3:compileTestJava +micro-s3:processTestResources +micro-spring-boot:testClasses +micro-spring-boot:compileTestJava +micro-spring-boot:processTestResources +micro-swagger:testClasses +micro-swagger:compileTestJava +micro-swagger:processTestResources +micro-tomcat:testClasses +micro-tomcat:compileTestJava +micro-tomcat:processTestResources +micro-tomcat-with-jersey:testClasses +micro-tomcat-with-jersey:compileTestJava +micro-tomcat-with-jersey:processTestResources +micro-transactions:testClasses +micro-transactions:compileTestJava +micro-transactions:processTestResources +micro-tutorial:testClasses +micro-tutorial:compileTestJava +micro-tutorial:processTestResources +micro-application-register:testsJar +micro-async-data-loader:testsJar +micro-async-data-writer:testsJar +micro-boot:testsJar +micro-client:testsJar +micro-core:testsJar +micro-cors:testsJar +micro-couchbase:testsJar +micro-curator:testsJar +micro-dbcp:testsJar +micro-dist-lock:testsJar +micro-error-codes:testsJar +micro-event-metrics:testsJar +micro-events:testsJar +micro-general-exception-mapper:testsJar +micro-grizzly:testsJar +micro-grizzly-with-jersey:testsJar +micro-guava:testsJar +micro-hibernate:testsJar +micro-hikaricp:testsJar +micro-ip-tracker:testsJar +micro-jackson-configuration:testsJar +micro-javaslang:testsJar +micro-jdbc:testsJar +micro-jersey:testsJar +micro-jmx-metrics:testsJar +micro-log-streamer:testsJar +micro-log4j:testsJar +micro-logback:testsJar +micro-machine-stats:testsJar +micro-manifest-comparator:testsJar +micro-metrics:testsJar +micro-metrics-datadog:testsJar +micro-mysql:testsJar +micro-reactive:testsJar +micro-s3:testsJar +micro-spring-boot:testsJar +micro-swagger:testsJar +micro-tomcat:testsJar +micro-tomcat-with-jersey:testsJar +micro-transactions:testsJar +init +micro-couchbase:groovydoc +micro-application-register:javadoc +micro-async-data-loader:javadoc +micro-async-data-writer:javadoc +micro-boot:javadoc +micro-client:javadoc +micro-core:javadoc +micro-cors:javadoc +micro-couchbase:javadoc +micro-curator:javadoc +micro-dbcp:javadoc +micro-dist-lock:javadoc +micro-error-codes:javadoc +micro-event-metrics:javadoc +micro-events:javadoc +micro-general-exception-mapper:javadoc +micro-grizzly:javadoc +micro-grizzly-with-jersey:javadoc +micro-guava:javadoc +micro-hibernate:javadoc +micro-hikaricp:javadoc +micro-ip-tracker:javadoc +micro-jackson-configuration:javadoc +micro-javaslang:javadoc +micro-jdbc:javadoc +micro-jersey:javadoc +micro-jmx-metrics:javadoc +micro-log-streamer:javadoc +micro-log4j:javadoc +micro-logback:javadoc +micro-machine-stats:javadoc +micro-manifest-comparator:javadoc +micro-metrics:javadoc +micro-metrics-datadog:javadoc +micro-mysql:javadoc +micro-reactive:javadoc +micro-s3:javadoc +micro-spring-boot:javadoc +micro-swagger:javadoc +micro-tomcat:javadoc +micro-tomcat-with-jersey:javadoc +micro-transactions:javadoc +micro-tutorial:javadoc +components +micro-application-register:components +micro-async-data-loader:components +micro-async-data-writer:components +micro-boot:components +micro-client:components +micro-core:components +micro-cors:components +micro-couchbase:components +micro-curator:components +micro-dbcp:components +micro-dist-lock:components +micro-error-codes:components +micro-event-metrics:components +micro-events:components +micro-general-exception-mapper:components +micro-grizzly:components +micro-grizzly-with-jersey:components +micro-guava:components +micro-hibernate:components +micro-hikaricp:components +micro-ip-tracker:components +micro-jackson-configuration:components +micro-javaslang:components +micro-jdbc:components +micro-jersey:components +micro-jmx-metrics:components +micro-log-streamer:components +micro-log4j:components +micro-logback:components +micro-machine-stats:components +micro-manifest-comparator:components +micro-metrics:components +micro-metrics-datadog:components +micro-mysql:components +micro-reactive:components +micro-s3:components +micro-spring-boot:components +micro-swagger:components +micro-tomcat:components +micro-tomcat-with-jersey:components +micro-transactions:components +micro-tutorial:components +dependencies +micro-application-register:dependencies +micro-async-data-loader:dependencies +micro-async-data-writer:dependencies +micro-boot:dependencies +micro-client:dependencies +micro-core:dependencies +micro-cors:dependencies +micro-couchbase:dependencies +micro-curator:dependencies +micro-dbcp:dependencies +micro-dist-lock:dependencies +micro-error-codes:dependencies +micro-event-metrics:dependencies +micro-events:dependencies +micro-general-exception-mapper:dependencies +micro-grizzly:dependencies +micro-grizzly-with-jersey:dependencies +micro-guava:dependencies +micro-hibernate:dependencies +micro-hikaricp:dependencies +micro-ip-tracker:dependencies +micro-jackson-configuration:dependencies +micro-javaslang:dependencies +micro-jdbc:dependencies +micro-jersey:dependencies +micro-jmx-metrics:dependencies +micro-log-streamer:dependencies +micro-log4j:dependencies +micro-logback:dependencies +micro-machine-stats:dependencies +micro-manifest-comparator:dependencies +micro-metrics:dependencies +micro-metrics-datadog:dependencies +micro-mysql:dependencies +micro-reactive:dependencies +micro-s3:dependencies +micro-spring-boot:dependencies +micro-swagger:dependencies +micro-tomcat:dependencies +micro-tomcat-with-jersey:dependencies +micro-transactions:dependencies +micro-tutorial:dependencies +dependencyInsight +micro-application-register:dependencyInsight +micro-async-data-loader:dependencyInsight +micro-async-data-writer:dependencyInsight +micro-boot:dependencyInsight +micro-client:dependencyInsight +micro-core:dependencyInsight +micro-cors:dependencyInsight +micro-couchbase:dependencyInsight +micro-curator:dependencyInsight +micro-dbcp:dependencyInsight +micro-dist-lock:dependencyInsight +micro-error-codes:dependencyInsight +micro-event-metrics:dependencyInsight +micro-events:dependencyInsight +micro-general-exception-mapper:dependencyInsight +micro-grizzly:dependencyInsight +micro-grizzly-with-jersey:dependencyInsight +micro-guava:dependencyInsight +micro-hibernate:dependencyInsight +micro-hikaricp:dependencyInsight +micro-ip-tracker:dependencyInsight +micro-jackson-configuration:dependencyInsight +micro-javaslang:dependencyInsight +micro-jdbc:dependencyInsight +micro-jersey:dependencyInsight +micro-jmx-metrics:dependencyInsight +micro-log-streamer:dependencyInsight +micro-log4j:dependencyInsight +micro-logback:dependencyInsight +micro-machine-stats:dependencyInsight +micro-manifest-comparator:dependencyInsight +micro-metrics:dependencyInsight +micro-metrics-datadog:dependencyInsight +micro-mysql:dependencyInsight +micro-reactive:dependencyInsight +micro-s3:dependencyInsight +micro-spring-boot:dependencyInsight +micro-swagger:dependencyInsight +micro-tomcat:dependencyInsight +micro-tomcat-with-jersey:dependencyInsight +micro-transactions:dependencyInsight +micro-tutorial:dependencyInsight +help +micro-application-register:help +micro-async-data-loader:help +micro-async-data-writer:help +micro-boot:help +micro-client:help +micro-core:help +micro-cors:help +micro-couchbase:help +micro-curator:help +micro-dbcp:help +micro-dist-lock:help +micro-error-codes:help +micro-event-metrics:help +micro-events:help +micro-general-exception-mapper:help +micro-grizzly:help +micro-grizzly-with-jersey:help +micro-guava:help +micro-hibernate:help +micro-hikaricp:help +micro-ip-tracker:help +micro-jackson-configuration:help +micro-javaslang:help +micro-jdbc:help +micro-jersey:help +micro-jmx-metrics:help +micro-log-streamer:help +micro-log4j:help +micro-logback:help +micro-machine-stats:help +micro-manifest-comparator:help +micro-metrics:help +micro-metrics-datadog:help +micro-mysql:help +micro-reactive:help +micro-s3:help +micro-spring-boot:help +micro-swagger:help +micro-tomcat:help +micro-tomcat-with-jersey:help +micro-transactions:help +micro-tutorial:help +projects +micro-application-register:projects +micro-async-data-loader:projects +micro-async-data-writer:projects +micro-boot:projects +micro-client:projects +micro-core:projects +micro-cors:projects +micro-couchbase:projects +micro-curator:projects +micro-dbcp:projects +micro-dist-lock:projects +micro-error-codes:projects +micro-event-metrics:projects +micro-events:projects +micro-general-exception-mapper:projects +micro-grizzly:projects +micro-grizzly-with-jersey:projects +micro-guava:projects +micro-hibernate:projects +micro-hikaricp:projects +micro-ip-tracker:projects +micro-jackson-configuration:projects +micro-javaslang:projects +micro-jdbc:projects +micro-jersey:projects +micro-jmx-metrics:projects +micro-log-streamer:projects +micro-log4j:projects +micro-logback:projects +micro-machine-stats:projects +micro-manifest-comparator:projects +micro-metrics:projects +micro-metrics-datadog:projects +micro-mysql:projects +micro-reactive:projects +micro-s3:projects +micro-spring-boot:projects +micro-swagger:projects +micro-tomcat:projects +micro-tomcat-with-jersey:projects +micro-transactions:projects +micro-tutorial:projects +properties +micro-application-register:properties +micro-async-data-loader:properties +micro-async-data-writer:properties +micro-boot:properties +micro-client:properties +micro-core:properties +micro-cors:properties +micro-couchbase:properties +micro-curator:properties +micro-dbcp:properties +micro-dist-lock:properties +micro-error-codes:properties +micro-event-metrics:properties +micro-events:properties +micro-general-exception-mapper:properties +micro-grizzly:properties +micro-grizzly-with-jersey:properties +micro-guava:properties +micro-hibernate:properties +micro-hikaricp:properties +micro-ip-tracker:properties +micro-jackson-configuration:properties +micro-javaslang:properties +micro-jdbc:properties +micro-jersey:properties +micro-jmx-metrics:properties +micro-log-streamer:properties +micro-log4j:properties +micro-logback:properties +micro-machine-stats:properties +micro-manifest-comparator:properties +micro-metrics:properties +micro-metrics-datadog:properties +micro-mysql:properties +micro-reactive:properties +micro-s3:properties +micro-spring-boot:properties +micro-swagger:properties +micro-tomcat:properties +micro-tomcat-with-jersey:properties +micro-transactions:properties +micro-tutorial:properties +tasks +micro-application-register:tasks +micro-async-data-loader:tasks +micro-async-data-writer:tasks +micro-boot:tasks +micro-client:tasks +micro-core:tasks +micro-cors:tasks +micro-couchbase:tasks +micro-curator:tasks +micro-dbcp:tasks +micro-dist-lock:tasks +micro-error-codes:tasks +micro-event-metrics:tasks +micro-events:tasks +micro-general-exception-mapper:tasks +micro-grizzly:tasks +micro-grizzly-with-jersey:tasks +micro-guava:tasks +micro-hibernate:tasks +micro-hikaricp:tasks +micro-ip-tracker:tasks +micro-jackson-configuration:tasks +micro-javaslang:tasks +micro-jdbc:tasks +micro-jersey:tasks +micro-jmx-metrics:tasks +micro-log-streamer:tasks +micro-log4j:tasks +micro-logback:tasks +micro-machine-stats:tasks +micro-manifest-comparator:tasks +micro-metrics:tasks +micro-metrics-datadog:tasks +micro-mysql:tasks +micro-reactive:tasks +micro-s3:tasks +micro-spring-boot:tasks +micro-swagger:tasks +micro-tomcat:tasks +micro-tomcat-with-jersey:tasks +micro-transactions:tasks +micro-tutorial:tasks +micro-application-register:uploadArchives +micro-application-register:signArchives +micro-async-data-loader:uploadArchives +micro-async-data-loader:signArchives +micro-async-data-writer:uploadArchives +micro-async-data-writer:signArchives +micro-boot:uploadArchives +micro-boot:signArchives +micro-client:uploadArchives +micro-client:signArchives +micro-core:uploadArchives +micro-core:signArchives +micro-cors:uploadArchives +micro-cors:signArchives +micro-couchbase:uploadArchives +micro-couchbase:signArchives +micro-curator:uploadArchives +micro-curator:signArchives +micro-dbcp:uploadArchives +micro-dbcp:signArchives +micro-dist-lock:uploadArchives +micro-dist-lock:signArchives +micro-error-codes:uploadArchives +micro-error-codes:signArchives +micro-event-metrics:uploadArchives +micro-event-metrics:signArchives +micro-events:uploadArchives +micro-events:signArchives +micro-general-exception-mapper:uploadArchives +micro-general-exception-mapper:signArchives +micro-grizzly:uploadArchives +micro-grizzly:signArchives +micro-grizzly-with-jersey:uploadArchives +micro-grizzly-with-jersey:signArchives +micro-guava:uploadArchives +micro-guava:signArchives +micro-hibernate:uploadArchives +micro-hibernate:signArchives +micro-hikaricp:uploadArchives +micro-hikaricp:signArchives +micro-ip-tracker:uploadArchives +micro-ip-tracker:signArchives +micro-jackson-configuration:uploadArchives +micro-jackson-configuration:signArchives +micro-javaslang:uploadArchives +micro-javaslang:signArchives +micro-jdbc:uploadArchives +micro-jdbc:signArchives +micro-jersey:uploadArchives +micro-jersey:signArchives +micro-jmx-metrics:uploadArchives +micro-jmx-metrics:signArchives +micro-log-streamer:uploadArchives +micro-log-streamer:signArchives +micro-log4j:uploadArchives +micro-log4j:signArchives +micro-logback:uploadArchives +micro-logback:signArchives +micro-machine-stats:uploadArchives +micro-machine-stats:signArchives +micro-manifest-comparator:uploadArchives +micro-manifest-comparator:signArchives +micro-metrics:uploadArchives +micro-metrics:signArchives +micro-metrics-datadog:uploadArchives +micro-metrics-datadog:signArchives +micro-mysql:uploadArchives +micro-mysql:signArchives +micro-reactive:uploadArchives +micro-reactive:signArchives +micro-s3:uploadArchives +micro-s3:signArchives +micro-spring-boot:uploadArchives +micro-spring-boot:signArchives +micro-swagger:uploadArchives +micro-swagger:signArchives +micro-tomcat:uploadArchives +micro-tomcat:signArchives +micro-tomcat-with-jersey:uploadArchives +micro-tomcat-with-jersey:signArchives +micro-transactions:uploadArchives +micro-transactions:signArchives +micro-tutorial:uploadArchives +micro-tutorial:signArchives +micro-application-register:check +micro-async-data-loader:check +micro-async-data-writer:check +micro-boot:check +micro-client:check +micro-core:check +micro-cors:check +micro-couchbase:check +micro-curator:check +micro-curator:integTest +micro-dbcp:check +micro-dist-lock:check +micro-error-codes:check +micro-event-metrics:check +micro-events:check +micro-general-exception-mapper:check +micro-grizzly:check +micro-grizzly-with-jersey:check +micro-guava:check +micro-hibernate:check +micro-hikaricp:check +micro-ip-tracker:check +micro-jackson-configuration:check +micro-javaslang:check +micro-jdbc:check +micro-jersey:check +micro-jmx-metrics:check +micro-log-streamer:check +micro-log4j:check +micro-logback:check +micro-machine-stats:check +micro-manifest-comparator:check +micro-metrics:check +micro-metrics-datadog:check +micro-mysql:check +micro-reactive:check +micro-s3:check +micro-spring-boot:check +micro-swagger:check +micro-tomcat:check +micro-tomcat-with-jersey:check +micro-transactions:check +micro-tutorial:check +micro-application-register:test +micro-async-data-loader:test +micro-async-data-writer:test +micro-boot:test +micro-client:test +micro-core:test +micro-cors:test +micro-couchbase:test +micro-curator:test +micro-dbcp:test +micro-dist-lock:test +micro-error-codes:test +micro-event-metrics:test +micro-events:test +micro-general-exception-mapper:test +micro-grizzly:test +micro-grizzly-with-jersey:test +micro-guava:test +micro-hibernate:test +micro-hikaricp:test +micro-ip-tracker:test +micro-jackson-configuration:test +micro-javaslang:test +micro-jdbc:test +micro-jersey:test +micro-jmx-metrics:test +micro-log-streamer:test +micro-log4j:test +micro-logback:test +micro-machine-stats:test +micro-manifest-comparator:test +micro-metrics:test +micro-metrics-datadog:test +micro-mysql:test +micro-reactive:test +micro-s3:test +micro-spring-boot:test +micro-swagger:test +micro-tomcat:test +micro-tomcat-with-jersey:test +micro-transactions:test +micro-tutorial:test +micro-application-register:install +micro-application-register:signArchives +micro-async-data-loader:install +micro-async-data-loader:signArchives +micro-async-data-writer:install +micro-async-data-writer:signArchives +micro-boot:install +micro-boot:signArchives +micro-client:install +micro-client:signArchives +micro-core:install +micro-core:signArchives +micro-cors:install +micro-cors:signArchives +micro-couchbase:install +micro-couchbase:signArchives +micro-curator:install +micro-curator:signArchives +micro-dbcp:install +micro-dbcp:signArchives +micro-dist-lock:install +micro-dist-lock:signArchives +micro-error-codes:install +micro-error-codes:signArchives +micro-event-metrics:install +micro-event-metrics:signArchives +micro-events:install +micro-events:signArchives +micro-general-exception-mapper:install +micro-general-exception-mapper:signArchives +micro-grizzly:install +micro-grizzly:signArchives +micro-grizzly-with-jersey:install +micro-grizzly-with-jersey:signArchives +micro-guava:install +micro-guava:signArchives +micro-hibernate:install +micro-hibernate:signArchives +micro-hikaricp:install +micro-hikaricp:signArchives +micro-ip-tracker:install +micro-ip-tracker:signArchives +micro-jackson-configuration:install +micro-jackson-configuration:signArchives +micro-javaslang:install +micro-javaslang:signArchives +micro-jdbc:install +micro-jdbc:signArchives +micro-jersey:install +micro-jersey:signArchives +micro-jmx-metrics:install +micro-jmx-metrics:signArchives +micro-log-streamer:install +micro-log-streamer:signArchives +micro-log4j:install +micro-log4j:signArchives +micro-logback:install +micro-logback:signArchives +micro-machine-stats:install +micro-machine-stats:signArchives +micro-manifest-comparator:install +micro-manifest-comparator:signArchives +micro-metrics:install +micro-metrics:signArchives +micro-metrics-datadog:install +micro-metrics-datadog:signArchives +micro-mysql:install +micro-mysql:signArchives +micro-reactive:install +micro-reactive:signArchives +micro-s3:install +micro-s3:signArchives +micro-spring-boot:install +micro-spring-boot:signArchives +micro-swagger:install +micro-swagger:signArchives +micro-tomcat:install +micro-tomcat:signArchives +micro-tomcat-with-jersey:install +micro-tomcat-with-jersey:signArchives +micro-transactions:install +micro-transactions:signArchives +micro-tutorial:install +micro-tutorial:signArchives +wrapper +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +assemble +signArchives +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +build +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildDependents +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +buildNeeded +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileGroovy +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +classes +compileJava +processResources +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +clean +integTestClasses +compileIntegTestJava +processIntegTestResources +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +jar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +javadocJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +sourcesJar +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestGroovy +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testClasses +compileTestJava +processTestResources +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +testsJar +init +groovydoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +javadoc +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +components +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencies +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +dependencyInsight +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +help +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +projects +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +properties +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +tasks +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +uploadArchives +signArchives +check +check +check +check +check +check +check +check +check +integTest +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +check +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +test +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +install +signArchives +wrapper diff --git a/.travis.yml b/.travis.yml index 8308af0f3..77978f992 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,8 @@ +sudo: true language: java -install: gradle clean build +install: ./gradlew clean jdk: - - oraclejdk8 + - openjdk8 + +script: + - ./gradlew check -i diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..8dada3eda --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 000000000..26bee39ed --- /dev/null +++ b/README.md @@ -0,0 +1,375 @@ + +# Microserver + +[![Build Status](https://travis-ci.org/aol/micro-server.svg)](https://travis-ci.org/aol/micro-server) +[![Join the chat at https://gitter.im/aol/micro-server](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/aol/micro-server?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +A convenient modular engine for Microservices. Microserver plugins offer seamless integration with Spring (core), Jersey, Guava, Tomcat, Grizzly, reactive programming, Hibernate (& Spring Data), Spring Boot, Codahale Metrics, Swagger and more to come! + +* [Microserver screencast : getting started with plugins](https://www.youtube.com/watch?v=sYn2cVTkfcM) + +![screen shot 2016-05-06 at 12 30 26 pm](https://cloud.githubusercontent.com/assets/9964792/15588807/8da91440-2387-11e6-979b-f24d456541f5.png) + +### Microserver plugins video +[![Getting started video](https://cloud.githubusercontent.com/assets/9964792/6361863/9991c50c-bc7e-11e4-8d28-746b0b87b1da.png)](https://youtu.be/sYn2cVTkfcM) + + + +## Quick start + +Install Microserver with Grizzly, Jackson and Jersey (Gradle config below) +```groovy + compile group: 'com.oath.microservices', name:'micro-grizzly-with-jersey', version:'x.yz' +``` +Install Microserver with Tomcat, Jackson and Jersey (Gradle config below) + ```groovy + compile group: 'com.oath.microservices', name:'micro-tomcat-with-jersey', version:'x.yz' + ``` +Create and run a simple app + ```java + @Rest + @Path("/test") + public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()->"test-app").run(); + } + @GET + public String myEndPoint(){ + return "hello world!"; + } + } +``` + +Browse to *http://localhost:8080/test-app/test* + +See the response *hello world!* + +Add plugins by adding them to your build file - rerun the app to get new end points, Spring beans and more! + +## Easy to use async NIO based REST + +Return any reactive-streams Publisher from your REST end point to make them execute asynchronously automatically. + +E.g. Using Future from [cyclops-react](cyclops-react.io) + +```java + @GET + public Future myEndPoint(){ + return Future.of(()->{ + sleep(); + return "hello world!"; + }, Executors.newFixedThreadPool(1)); + } +``` + +Would be equivalent to the following code + +```java + @GET + public void myEndPoint(@Suspended AsyncResponse asyncResponse){ + Future.of(()->{ + sleep(); + asyncResponse.resume("hello world!"); + return 1; + }, Executors.newFixedThreadPool(1)); +} +``` + +# Why Microserver? + +Microserver is a plugin engine for building Spring and Spring Boot based microservices. Microserver supports pure microservice and micro-monolith development styles. The micro-monolith style involves packaging multiple services into a single deployment - offering developers the productivity of microservice development without the operational risk. This can help teams adopt a Microservices architecture on projects that are currently monoliths. + +Microserver plugins are orthogonal to Microservices. They solve a common problem in Microservice development whereby services are broken up and deployed separately but the code remains entangled in a monolithic common library. By making use of a plugin system that follows the same modular architectural principals as microservice development, teams can keep cross-service concerns and infrastructure in properly size, coherent and cohesive plugin modules. + +# Tutorial and overview + +[Tutorial](https://github.com/aol/micro-server/wiki/Getting-started-:-Tutorial) + +[Tutorial code](https://github.com/aol/micro-server/tree/master/micro-tutorial) + +## Note on Fat Jars + +Microserver (& Cyclops) have a plugin architecture and make use of the Java Service Loader mechanism. Make sure your Fat Jar implementation is configured to aggregate services. With the Gradle Shadow Jar you do this with + ```groovy + shadowJar { + mergeServiceFiles() + } + ``` + + +### Quick start youtube video + +[![Getting started video](https://cloud.githubusercontent.com/assets/9964792/6361863/9991c50c-bc7e-11e4-8d28-746b0b87b1da.png)](https://www.youtube.com/watch?v=McXy9oGRpfA&feature=youtu.be) + + +Note the main launch class has been changed from MicroServerStartup to MicroserverApp + +## Blurb + +Microserver is a zero configuration, standards based, battle hardened library to run Java Rest Microservices via a standard Java main class. It has been used in production in AOL since July 2014. + + +## Get Microserver + + +![Build health](https://travis-ci.org/aol/micro-server.svg) + +* micro-grizzly-with-jersey +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-grizzly-with-jersey/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-grizzly-with-jersey) +* micro-tomcat-with-jersey +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-tomcat-with-jersey/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-tomcat-with-jersey) +* micro-core +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-core) +* micro-boot : Microserver driving Spring Boot +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-boot/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-boot) +* micro-spring-boot : Spring Boot driving Microserver +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-spring-boot/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-spring-boot) + + +## Info + +[wiki](https://github.com/aol/micro-server/wiki) + +[Google Group](https://groups.google.com/forum/#!forum/micro-server) + +[Example Apps : Microserver Core with Grizzly and Jersey](https://github.com/aol/micro-server/tree/master/micro-grizzly/src/test/java/app) + +[Example Apps : Microserver Boot](https://github.com/aol/micro-server/tree/master/micro-boot/src/test/java/app) + +[Java Doc : Microserver Core](http://www.javadoc.io/doc/com.oath.microservices/micro-core/0.62) + +[Java Doc : Microserver Boot](http://www.javadoc.io/doc/com.oath.microservices/micro-core/0.62) + + + +### Maven dependency + +Microserver Grizzly with Jersey + ```xml + + com.oath.microservices + micro-grizzly-with-jersey + x.yz + +``` +Microserver Spring Boot + ```xml + + com.oath.microservices + micro-spring-boot + x.yz + + ``` + + +### Gradle dependency + +Microserver core + ```groovy + compile group: 'com.oath.microservices', name:'micro-core', version:'x.yz' + ``` +Microserver Spring Boot + ```groovy + compile group: 'com.oath.microservices', name:'micro-spring-boot', version:'x.yz' + ``` +## Tech Stack + +Microserver core is a lightweight server configuration engine built using Spring, Cyclops and Jackson. + + + +## Zero Configuration + +No directory structure is imposed by the server and no XML is required. There is no framework config. Just a jar file and your application. You can, of course, configure your application without limit. + +Example working application :- + +### The main class :- + +```java + public class AppRunnerTest { + + + public static void main(String[] args) throws InterruptedException { + new MicroserverApp(() -> "test-app").run(); + } + + } + ``` + +This will deploy a REST server on port 8080 (configurable by test-app.port in application.properties), it will also automagically capture any Rest end points (Spring & Jersey annotations) that implement the tag interface RestResource (see below for an example). + +### A rest end point + +```java +@Rest +@Path("/status") +public class StatusResource { + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} +``` +### Configuration Options + +If you find you need configuration options for your application you have two options. + +1. Override some of the available options on the Module interface (ConfigurableModule provides a builder mechanism for this) +2. [Implement a custom plugin](https://github.com/aol/micro-server/wiki/Creating-a-Microserver-plugin) (the cleanest option, which also promotes reuse across services). + +### Application configuration (for Grizzly with Jersey) + +The core of Microserver is a Spring 4.x Dependency Injection container which is used to store all the main classes of your Microservice (s). The Spring Dependency Injection container can be configured by the @Microservice Annotation on your main class, or by the Config object (optionally passed as a parameter to startup). + +### Micro-monolith Architectural Overview + +Each Microservice is a Jersey REST Application, these can be deployed independently as pure Microservices or together as a micro-monolith. Multiple Microservices can run on the same server, by adding them to the classpath at runtime. They share a common Spring Dependency Injection container (as they are smaller services, we feel it makes sense to share resources such as ThreadPools, Datasources etc), but act as totally separate Rest applications. + +When creating embedded Microservices (multiple services colocated on the same JVM and Spring container), the development project should be independent, but the colocated instances should be tested as they will be deployed in production. There will be more info to follow on the wiki, on how and why we have implemented and scaled this pattern (the goal is to achieve both the benefits of a full Microservice architecture, but minimise the costs as articulated by Robert (Uncle Bob) C. Martin and others - e.g. [here: Microservices and Jars](http://blog.cleancoder.com/uncle-bob/2014/09/19/MicroServicesAndJars.html) . + +Jersey REST Applications are configured by the Module interface (at least one of which must be specified on startup). + +![high level architecture](https://cloud.githubusercontent.com/assets/9964792/6375067/a6e4f65a-bd0c-11e4-85dc-82ae0d95d44b.png) + + +#### Rest configuration + +The configuration of your Rest endpoints can be managed via the Module interface. The Module interface has a number of Java 8 default methods and a single abstract method (getContext). It behaves as a functional interface, and can be defined by a lambda expression. When used in this way the lambda represents the context the Microserver will create Rest end points on. + +e.g. + + ```java + new MicroserverApp(() -> "context").start(); + ``` + +() -> "context" is a Module! + + +#### Configurable Options + +Module provides the following default methods, that clients can override + + ```java + default Map getPropertyOverrides(){ + return Maps.newHashMap(); + } + default Set getSpringConfigurationClasses(){ + return Sets.newHashSet(Classes.CORE_CLASSES.getClasses()); + } + default List getRestResourceClasses() { + return Arrays.asList(RestResource.class); + } + default List getRestAnnotationClasses() { + return Arrays.asList(Rest.class); + } + + default List getDefaultJaxRsPackages(){ + return Arrays.asList("com.wordnik.swagger.sample.resource", + "com.wordnik.swagger.sample.util" ); + } + + default List getDefaultResources(){ + return Arrays.asList(JacksonFeature.class, + //SWAGGER CLASSES + ApiListingResourceJSON.class,JerseyApiDeclarationProvider.class, + JerseyResourceListingProvider.class); + } + + default List getListeners(ServerData data){ + return ImmutableList.of(new ContextLoaderListener(data + .getRootContext()), + new JerseySpringIntegrationContextListener(data), + new SwaggerInitializer(data)); + } + default Map getFilters(ServerData data) { + return ImmutableMap.of("/*",new QueryIPRetriever()); + } + default Map getServlets(ServerData data) { + return ImmutableMap.of(); + } + + default String getJaxWsRsApplication(){ + return JerseyRestApplication.class.getCanonicalName(); + } + default String getProviders(){ + return "com.aol.micro.server.rest.providers"; + } + ``` +RestResource class defines the tag interface used to identify Rest end points for this module. + +Filters provides a map of Servlet filters and the paths to which they should be applied + +Providers allows client code to change the Jersey Providers packages + +JaxWsRsApplication allows client code to completely override the Microserver jax.ws.rs.Application + +#### Property file configuration + +Microserver supports auto-discovery of application.properties. Microserver will assume a default file name of 'application.properties'. Microserver will check for a properties in the following order + +1. System property 'application.property.file' and if present will load the property file from disk using that. + +2. Otherwise, Microserver will look for a System Property 'application.env' and will load the application property file from the classpath using the resource name 'application-${application.env}.properties. + +3. Alternatively, Microserver will load application.properties directly from the classpath. + +4. If still not found Microserver will load application.properties from disk in the current directory + +The default file name application.properties can be configured by exception (use PropertyFileConfig.setApplicationPropertyFileName(String filename). + +Microserver application properties loading is configured by the class PropertyFileConfig. You can replace this with your own Spring configuration file to load property files by a different set of rules (by passing in your class to the constructor of Microserver). + +## Embed and colocate Microservices + +Microserver supports the embedding of multiple microservices within a single Microserver, this is not the default mode of operation and involves a little more work to setup. All Microservices will share a single Spring context, so some care needs to be taken when authoring such Microservices to avoid conflicts. This does mean that they can share resources (such as database connections) where it makes sense to do so. + +Embedded microservices should be collated at '''runtime only'''. There should be no compile time dependency between embedded microservices (otherwise you are not building microservices but a monolithic application). + +Embedding microservices is an optimisation that allows better performance, enhanced robustness and reliability and easier management of microservices - while still maintaining the advantages of horizontal scalability offered by the microservices approach. + +### Embedded Microservices example + +This example will start two different Rest endpoints - one on context "test-app" and another on context "alternative-app". +"test-app" will automagically wire in any Jersey endpoints that implement TestAppRestResource. +"alternative-app" will automagically wire in any Jersey endpoints that implement AltAppRestResource. + ```java + @Microserver + public class EmbeddedAppRunnerTest { + + public static void main(String[] args) throws InterruptedException { + new MicroserverApp(EmbeddedAppRunnerTest.class, + new EmbeddedModule(TestAppRestResource.class,"test-app"), + new EmbeddedModule(AltAppRestResource.class,"alternative-app")).start(); + + + + } + } + + ``` + + +## Building a 'fat' Jar + +We recommend the Gradle plugin Shadow Jar. For Gradle 2.0 simply define it in your plugins section -> + ```groovy +plugins { + id 'java' // or 'groovy' Must be explicitly applied + id 'com.github.johnrengelman.shadow' version '1.2.0' +} + ``` +Maven users can use Shade plugin or equivalent (Maven assembly plugin). + +# Thanks to our Sponsors + +* ![YourKit Logo](https://www.yourkit.com/images/yklogo.png) YourKit supports open source projects with innovative and intelligent tools +for monitoring and profiling Java and .NET applications. +YourKit is the creator of YourKit Java Profiler, +YourKit .NET Profiler, +and YourKit YouMonitor. diff --git a/build.gradle b/build.gradle index afd81a6e5..d4b678dfd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,67 +1,65 @@ -def custom ={ "$rootDir/gradle/${it}.gradle"} +def custom = { "$rootDir/gradle/${it}.gradle" } buildscript { - repositories { jcenter() - maven { - url 'https://github.com/serkan-ozal/maven-repository/raw/master/' - url "https://oss.sonatype.org/content/repositories/snapshots" - - } - - } - - dependencies { - classpath 'com.bmuschko:gradle-nexus-plugin:2.2' - // classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.0' - classpath 'com.github.lkishalmi.gradle:gradle-bom-plugin:0.3' - - } + repositories { + jcenter() + maven { + url 'https://github.com/serkan-ozal/maven-repository/raw/master/' + url "https://oss.sonatype.org/content/repositories/snapshots" + } + + } + dependencies { + classpath 'com.bmuschko:gradle-nexus-plugin:2.2' + classpath 'com.github.lkishalmi.gradle:gradle-bom-plugin:0.3' + + } } +subprojects { + apply plugin: 'java' + apply plugin: 'groovy' + apply plugin: 'maven' -task wrapper(type: Wrapper) { - gradleVersion = '2.3' -} + if (project.name != "micro-tutorial") { + apply plugin: 'com.bmuschko.nexus' + } -subprojects { - apply plugin:'java' -// apply plugin: 'com.github.johnrengelman.shadow' - apply plugin: 'com.bmuschko.nexus' - sourceCompatibility = 1.8 - targetCompatibility = 1.8 + sourceCompatibility = 1.8 + targetCompatibility = 1.8 + + jar { + manifest { + attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version + } + } - jar { - manifest { - attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version - } - } + repositories { + mavenCentral() + maven { url "http://repo.maven.apache.org/maven2" } + jcenter() + } + dependencies { + compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.16.18' - repositories { - mavenCentral() - maven { url "http://repo.maven.apache.org/maven2" } - jcenter() - } + testCompile group: 'junit', name: 'junit', version: '4.12' + testCompile group: 'org.mockito', name: 'mockito-core', version: '1.9.5' + testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: hamcrestVersion - dependencies { - + testCompileOnly group: 'org.projectlombok', name: 'lombok', version: '1.16.18' - testCompile group: 'junit', name: 'junit', version:'4.12' - testCompile group: 'org.mockito', name: 'mockito-core', version:'1.9.5' - testCompile group: 'org.hamcrest', name: 'hamcrest-all', version:hamcrestVersion - + } - compile(group: 'org.projectlombok', name: 'lombok', version:'1.16.2') { - /* This dependency was originally in the Maven provided scope, but the project was not of type war. - This behavior is not yet supported by Gradle, so this dependency has been converted to a compile dependency. - Please review and delete this closure when resolved. */ - } - } + test { + systemProperties 'property': 'value' - test { systemProperties 'property': 'value' } + testLogging { + events "started", "passed", "skipped", "failed" + } + } - } diff --git a/gradle.properties b/gradle.properties index 9c4525df7..3537f3600 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,31 +1,29 @@ -version=0.84 -springVersion=4.2.6.RELEASE -springBootVersion=1.3.5.RELEASE -jerseyVersion=2.22.2 -grizzlyVersion=2.3.24 -cyclopsReactVersion=1.0.0-RC3 -cyclopsVersion=8.0.0 +version=1.2.7 +springVersion=5.1.8.RELEASE +springBootVersion=2.1.6.RELEASE +jerseyVersion=2.28 +grizzlyVersion=2.4.4 +cyclopsVersion=10.3.3 hamcrestVersion=1.3 -hibernateVersion=5.0.5.Final -hibernateValidator=5.2.2.Final -springDataJPA=1.9.1.RELEASE -guavaVersion=19.0 -javaslangDatatypeVersion=2.0.2 -javaslangVersion=2.0.2 -jacksonVersion=2.6.3 -guavaDatatypeVersion=2.6.3 +hibernateVersion=5.4.2.Final +hibernateValidator=6.0.16.Final +springDataJPA=2.1.8.RELEASE +guavaVersion=27.1-jre +jacksonVersion=2.9.8 +guavaDatatypeVersion=2.9.8 logbackVersion=1.1.3 -slf4jVersion=1.7.13 +slf4jVersion=1.7.26 aspectJVersion=1.8.7 jtaVersion=1.1 springMetricsVersion=3.1.3 +datadogMetricsVersion=1.1.6 apacheHttpClientVersion=4.5.1 apacheHttpClientVersionAsync=4.1.1 -hikariCPVersion=2.4.2 -curatorVersion=2.9.1 +hikariCPVersion=3.3.1 +curatorVersion=3.1.0 ebayCORSVersion=1.0.1 -dbcp2Version=2.1.1 +dbcp2Version=2.6.0 log4jVersion=1.2.17 s3Version=1.10.42 -tomcatVersion=9.0.0.M4 +tomcatVersion=9.0.19 commonsIOVersion=2.5 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..ed88a042a Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..738dba9f4 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sat Oct 21 00:10:43 EDT 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip diff --git a/gradlew b/gradlew new file mode 100755 index 000000000..f5eadce96 --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your microserverEnvironment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your microserverEnvironment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 000000000..219bdeb3f --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your microserverEnvironment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your microserverEnvironment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/licence.txt b/licence.txt deleted file mode 100644 index 5b1e02eaf..000000000 --- a/licence.txt +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2015 AOL - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/micro-alive-handler/build.gradle b/micro-alive-handler/build.gradle deleted file mode 100644 index 5e3446628..000000000 --- a/micro-alive-handler/build.gradle +++ /dev/null @@ -1,67 +0,0 @@ -description = 'micro-alive-handler' - -dependencies { - compile project(':micro-core') - - testCompile project(':micro-grizzly-with-jersey') -} - -modifyPom { - project { - name 'Microserver alive handler' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-alive-handler' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - developer { - id 'earlzero' - name 'Nikita Sapozhnikov' - email 'nikita.sapozhnikov@teamaol.com' - } - } - - } -} - -extraArchive { - sources = true - tests = true - javadoc = true -} - -nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' -} - diff --git a/micro-alive-handler/readme.md b/micro-alive-handler/readme.md deleted file mode 100644 index f9bbcbba0..000000000 --- a/micro-alive-handler/readme.md +++ /dev/null @@ -1,66 +0,0 @@ -# AliveHandler Plugin - -Problem of implementing alive handler often arise in production tasks (either it required by load balancer or by monitoring system). This module can solve this problem by providing simple framework for building this handlers. - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-alive-handler/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-alive-handler) - -Simply add to the classpath - -Maven -```xml - - com.aol.microservices - micro-alive-handler - x.yz - -``` -Gradle -```groovy - compile 'com.aol.microservices:micro-alive-handler:x.yz' -``` -## Usage -Since requirements for alive handlers can vary between systems, you should write your own handling logic. It can be done by implementing AliveHandlerController. Next example provide alive handler which will just return code 200 if service is enabled, or 404 if not. -```java -@Component -public class AliveHandlerControllerApi implements AliveHandlerController { - - private volatile boolean enabled = true; - - @Override - public Response process() { - if(enabled) { - return Response.ok().build(); - } else { - return Response.status(404).build(); - } - } - - @Override - public void enable() { - enabled = true; - } - - @Override - public void disable() { - enabled = false; - } - -} -``` -Since there could be multiple services bundled together, you also should write repository, which contains all of your AliveHandlerControllers with their urls. For example -```java -@Component -public class AliveHandlerControllerRepositoryImpl implements AliveHandlerControllerRepository { - private Map map = ImmutableMap.of("ping", new AliveHandlerControllerApi()); - - @Override - public Optional get(String name) { - System.out.println(name); - return Optional.ofNullable(map.get(name)); - } - -} -``` -So in previous case, if base rest resource address is "/services/test", "/services/test/ping" will be your alive handler url. diff --git a/micro-alive-handler/src/main/java/com/aol/micro/server/alivehandler/AliveHandlerController.java b/micro-alive-handler/src/main/java/com/aol/micro/server/alivehandler/AliveHandlerController.java deleted file mode 100644 index e90ae1454..000000000 --- a/micro-alive-handler/src/main/java/com/aol/micro/server/alivehandler/AliveHandlerController.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.aol.micro.server.alivehandler; - -import javax.ws.rs.core.Response; - -public interface AliveHandlerController { - Response process(); - void enable(); - void disable(); -} diff --git a/micro-alive-handler/src/main/java/com/aol/micro/server/alivehandler/AliveHandlerControllerRepository.java b/micro-alive-handler/src/main/java/com/aol/micro/server/alivehandler/AliveHandlerControllerRepository.java deleted file mode 100644 index 75bbbb24f..000000000 --- a/micro-alive-handler/src/main/java/com/aol/micro/server/alivehandler/AliveHandlerControllerRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.aol.micro.server.alivehandler; - -import java.util.Optional; - -public interface AliveHandlerControllerRepository { - Optional get(String name); -} diff --git a/micro-alive-handler/src/main/java/com/aol/micro/server/alivehandler/AliveHandlerPlugin.java b/micro-alive-handler/src/main/java/com/aol/micro/server/alivehandler/AliveHandlerPlugin.java deleted file mode 100644 index ee335c6a0..000000000 --- a/micro-alive-handler/src/main/java/com/aol/micro/server/alivehandler/AliveHandlerPlugin.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.aol.micro.server.alivehandler; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; - -public class AliveHandlerPlugin implements Plugin { - @Override - public PSetX springClasses() { - return PSetX.of(AliveHandlerRest.class); - } - -} diff --git a/micro-alive-handler/src/main/java/com/aol/micro/server/alivehandler/AliveHandlerRest.java b/micro-alive-handler/src/main/java/com/aol/micro/server/alivehandler/AliveHandlerRest.java deleted file mode 100644 index 2c5ce3df5..000000000 --- a/micro-alive-handler/src/main/java/com/aol/micro/server/alivehandler/AliveHandlerRest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.aol.micro.server.alivehandler; - -import java.util.Optional; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.core.Response; - -import org.springframework.beans.factory.annotation.Autowired; - -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.auto.discovery.RestResource; - -@Rest -@Path("/{name}") -public class AliveHandlerRest implements RestResource { - - private final AliveHandlerControllerRepository repository; - - @Autowired - public AliveHandlerRest(AliveHandlerControllerRepository repository) { - this.repository = repository; - } - - @Override - public boolean isSingleton() { - return true; - } - - @GET - public Response checkAlive(@PathParam("name") String name) { - Optional controller = repository.get(name); - return controller.map(c -> c.process()).orElse(Response.status(404).build()); - } -} diff --git a/micro-alive-handler/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-alive-handler/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 389ea4a7a..000000000 --- a/micro-alive-handler/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.alivehandler.AliveHandlerPlugin \ No newline at end of file diff --git a/micro-alive-handler/src/test/java/com/aol/micro/server/alivehandler/AliveHandlerControllerTest.java b/micro-alive-handler/src/test/java/com/aol/micro/server/alivehandler/AliveHandlerControllerTest.java deleted file mode 100644 index 2d1c6f8a2..000000000 --- a/micro-alive-handler/src/test/java/com/aol/micro/server/alivehandler/AliveHandlerControllerTest.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.aol.micro.server.alivehandler; - -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; -import java.util.Optional; - -import javax.ws.rs.core.Response; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.springframework.context.annotation.Bean; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; - -import jersey.repackaged.com.google.common.collect.ImmutableMap; - -@Microserver -public class AliveHandlerControllerTest { - private MicroserverApp server; - - @Before - public void startServer() throws InterruptedException { - server = new MicroserverApp(()->"simple-app"); - - Thread.sleep(1000); - server.start(); - } - - @After - public void stopServer() { - server.stop(); - } - - @Bean - public AliveHandlerControllerRepository getAliveHandlerControllerRepository() { - - final AliveHandlerController controller = new AliveHandlerController() { - - @Override - public Response process() { - return Response.ok().build(); - } - - @Override - public void enable() { - // TODO Auto-generated method stub - - } - - @Override - public void disable() { - // TODO Auto-generated method stub - - } - }; - - return new AliveHandlerControllerRepository() { - - private Map map = ImmutableMap.of("ping", controller); - - @Override - public Optional get(String name) { - return Optional.ofNullable(map.get(name)); - } - }; - - } - - @Test - public void alive() throws Exception { - Assert.assertEquals(200, getStatusCode("http://localhost:8080/simple-app/ping")); - } - - @Test - public void dead() throws Exception { - Assert.assertEquals(404, getStatusCode("http://localhost:8080/simple-app/wrong_ping")); - } - @Test - public void alt() throws Exception { - Assert.assertEquals(200, getStatusCode("http://localhost:8080/simple-app/status/ping")); - } - - private int getStatusCode(String urlString) throws Exception { - URL url = new URL(urlString); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("GET"); - return conn.getResponseCode(); - } -} diff --git a/micro-alive-handler/src/test/java/com/aol/micro/server/alivehandler/MyEndPoint.java b/micro-alive-handler/src/test/java/com/aol/micro/server/alivehandler/MyEndPoint.java deleted file mode 100644 index c4260779d..000000000 --- a/micro-alive-handler/src/test/java/com/aol/micro/server/alivehandler/MyEndPoint.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.aol.micro.server.alivehandler; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Path("/wrong_ping") -public class MyEndPoint implements RestResource { - - @GET - public String value(){ - return "hello"; - } -} diff --git a/micro-alive-handler/src/test/java/com/aol/micro/server/alivehandler/StatusResource.java b/micro-alive-handler/src/test/java/com/aol/micro/server/alivehandler/StatusResource.java deleted file mode 100644 index b5ef7252f..000000000 --- a/micro-alive-handler/src/test/java/com/aol/micro/server/alivehandler/StatusResource.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.aol.micro.server.alivehandler; - -import com.aol.micro.server.auto.discovery.Rest; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -@Rest -@Path("/status") -public class StatusResource { - /** - * GET ping endpoint. - * @return string - */ - @GET - @Path("ping") - public String ping() { - return "pong"; - } -} diff --git a/micro-application-register/README.md b/micro-application-register/README.md new file mode 100644 index 000000000..7338468b0 --- /dev/null +++ b/micro-application-register/README.md @@ -0,0 +1,72 @@ +# Application / Service Registry Client Plugin + +[micro-application-register example apps](https://github.com/aol/micro-server/tree/master/micro-application-register/src/test/java/app) + +This plugin turns any service into a Service Registry client (and optionally server). A scheduled job will run at configurable intervals (default is every 5 minutes) and post some info on the instance to the Service Registry server (url also configurable). The server will persist data on active services to a configurable location. + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-application-register/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-application-register) + +Simply add this plugin to the classpath on your Microserver app. + +Maven +```xml + + com.oath.microservices + micro-application-registry + x.yz + +``` +Gradle +```groovy + compile 'com.oath.microservices:micro-application-registry:x.yz' +``` +## Depends on + + micro-client + micro-reactive + +Import this plugin to add ServiceRegistry functionality, Rest Resource available on + + /app-path/service-registry + +Functionality + + [service registry server] + /app-path/service-registry/list : list active services + /app-path/service-registry/register : register an active service + /app-path/service-registry/schedule : run the scheduled job for this instance + to register with the service registry + + +## Properties + + service.registry.delay:300000 + service.registry.entry.max.live:43200000 + service.registry.dir:java.io.tmpdir/services + service.registry.url: url to register services on (http://hostname:port/context) + +### Configure a custom host address + +Use the property, host.address to set the host address (otherwise InetAddress.getLocalHost().getHostName() is used, which may cause some problems when using containers). + + host.address=custom.host.addrress + +### Use caller ip + +To configure the application register to use the callers ip (rather than the senders hostname), the sender should configure host.address as follows + + host.address=use-ip + +### Health checks + +Any Spring Beans that implement the HealthStatus interface will be executed on send + +### Configure a target address (e.g. a VIP or load balancer) + +Use the property target.endpoint to define an end point which should be used to communicate with the service being registered. + +I.e. this is not the service registry URL (see above), this is a Load balancer that should be used instead of the host that is registring itself own end point. If you have 4 services of the same type behind a load balancer, each will register their host addresses, but you can also configure a common target address, that let's clients of the service registry know not to communicate directly to each host but to use their target (or load balancer address instead). + + target.endpoint=https://www.myendpoint.com/api diff --git a/micro-application-register/build.gradle b/micro-application-register/build.gradle index 3abc1632a..40908f51c 100644 --- a/micro-application-register/build.gradle +++ b/micro-application-register/build.gradle @@ -1,60 +1,58 @@ description = 'micro-application-register' + dependencies { - - compile 'org.apache.commons:commons-io:1.3.2' - compile project(':micro-core') - compile project(':micro-client') - compile project(':micro-ip-tracker') - testCompile project(':micro-grizzly-with-jersey') - testCompile group: 'org.hamcrest', name: 'hamcrest-all', version:hamcrestVersion + compile 'commons-io:commons-io:' + commonsIOVersion + compile project(':micro-core') + compile project(':micro-client') + compile project(':micro-ip-tracker') + testCompile project(':micro-grizzly-with-jersey') + testCompile 'org.hamcrest:hamcrest-all:' + hamcrestVersion } modifyPom { - project { - name 'Microserver application register' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-application-register' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - } - - } + project { + name 'Microserver application register' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-application-register' + version "$version" + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-application-register/readme.md b/micro-application-register/readme.md deleted file mode 100644 index f5faf1600..000000000 --- a/micro-application-register/readme.md +++ /dev/null @@ -1,69 +0,0 @@ -# Application / Service Registry Client Plugin - -[micro-application-register example apps](https://github.com/aol/micro-server/tree/master/micro-application-register/src/test/java/app) - -This plugin turns any service into a Service Registry client (and optionally server). A scheduled job will run at configurable intervals (default is every 5 minutes) and post some info on the instance to the Service Registry server (url also configurable). The server will persist data on active services to a configurable location. - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-application-register/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-application-register) - -Simply add this plugin to the classpath on your Microserver app. - -Maven -```xml - - com.aol.microservices - micro-application-registry - x.yz - -``` -Gradle -```groovy - compile 'com.aol.microservices:micro-application-registry:x.yz' -``` -## Depends on - - micro-client - micro-reactive - -Import this plugin to add ServiceRegistry functionality, Rest Resource available on - - /app-path/service-registry - -Functionality - - [service registry server] - /app-path/service-registry/list : list active services - /app-path/service-registry/register : register an active service - /app-path/service-registry/schedule : run the scheduled job for this instance - to register with the service registry - - -## Properties - - service.registry.delay:300000 - service.registry.entry.max.live:43200000 - service.registry.dir:java.io.tmpdir/services - service.registry.url: url to register services on (http://hostname:port/context) - -### Configure a custom host address - -Use the property, host.address to set the host address (otherwise InetAddress.getLocalHost().getHostName() is used, which may cause some problems when using containers). - - host.address=custom.host.addrress - -### Use caller ip - -To configure the application register to use the callers ip (rather than the senders hostname), the sender should configure host.address as follows - - host.address=use-ip - - -### Configure a target address (e.g. a VIP or load balancer) - -Use the property target.endpoint to define an end point which should be used to communicate with the service being registered. - -I.e. this is not the service registry URL (see above), this is a Load balancer that should be used instead of the host that is registring itself own end point. If you have 4 services of the same type behind a load balancer, each will register their host addresses, but you can also configure a common target address, that let's clients of the service registry know not to communicate directly to each host but to use their target (or load balancer address instead). - - target.endpoint=https://www.myendpoint.com/api diff --git a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Application.java b/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Application.java deleted file mode 100644 index cd8058379..000000000 --- a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Application.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.aol.micro.server.application.registry; - -import java.util.Iterator; -import java.util.List; - -import lombok.AccessLevel; -import lombok.experimental.FieldDefaults; - -import org.pcollections.ConsPStack; -import org.pcollections.PStack; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -@FieldDefaults(makeFinal=true, level=AccessLevel.PRIVATE) -public class Application implements Iterable{ - - - PStack entries; - - public Application(final List entries) { - this.entries = ConsPStack.from(entries); - } - - @Override - public Iterator iterator() { - return entries.iterator(); - } - - public String toString(){ - return JacksonUtil.serializeToJson(entries); - } - - -} diff --git a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/ApplicationRegisterImpl.java b/micro-application-register/src/main/java/com/aol/micro/server/application/registry/ApplicationRegisterImpl.java deleted file mode 100644 index 04ba4a2e4..000000000 --- a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/ApplicationRegisterImpl.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.aol.micro.server.application.registry; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Optional; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import lombok.Getter; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import com.aol.cyclops.util.ExceptionSoftener; -import com.aol.micro.server.servers.ApplicationRegister; -import com.aol.micro.server.servers.model.ServerData; - -@Component -public class ApplicationRegisterImpl implements ApplicationRegister { - private final Logger logger = LoggerFactory.getLogger(getClass()); - @Getter - private volatile Application application; - - - private final String customHostname; - private final String targetEndpoint; - - @Autowired - public ApplicationRegisterImpl(@Value("${host.address:#{null}}")String customHostname, - @Value("${target.endpoint:#{null}}")String targetEndpoint){ - - this.customHostname=customHostname; - this.targetEndpoint = targetEndpoint; - - } - - public ApplicationRegisterImpl() { - this(null,null); - } - - @Override - public void register(ServerData[] data) { - - try { - final String hostname = Optional.ofNullable(customHostname).orElse( InetAddress.getLocalHost().getHostName()); - application = new Application(Stream - .of(data) - .map(next -> new RegisterEntry(next.getPort(), hostname, next.getModule().getContext(), next - .getModule().getContext(), null,targetEndpoint)).collect(Collectors.toList())); - logger.info("Registered application {} ", application); - } catch (UnknownHostException e) { - throw ExceptionSoftener.throwSoftenedException(e); - } - } -} diff --git a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Cleaner.java b/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Cleaner.java deleted file mode 100644 index 72d08d275..000000000 --- a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Cleaner.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.aol.micro.server.application.registry; - -import java.io.File; -import java.util.Date; -import java.util.stream.Stream; - -import javax.annotation.PostConstruct; - -import org.apache.commons.io.FileUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -@Component -public class Cleaner { - - private final RegisterConfig config; - private final int maxLive; - - @Autowired - public Cleaner(RegisterConfig config, @Value("${service.registry.entry.max.live:43200000}") int maxLive) { - this.config = config; - this.maxLive = maxLive; - } - - @PostConstruct - public void deleteOldFilesAfterEachStartup() { - cleanDir(new File(config.getOutputDir()), true); - } - - public void clean() { - cleanDir(new File(config.getOutputDir()), false); - } - - private void cleanDir(File dir, boolean deleteWithoutCheck) { - if (dir.listFiles() != null) { - Stream.of(dir.listFiles()).forEach((next) -> { - if (next.isDirectory()) { - cleanDir(next, deleteWithoutCheck); - } - - if (next.isFile()) { - if (deleteWithoutCheck) { - next.delete(); - } else { - checkFile(next); - } - } - - }); - } - } - - private void checkFile(File f) { - try { - RegisterEntry entry = JacksonUtil.convertFromJson(FileUtils.readFileToString(f), RegisterEntry.class); - if (new Date().getTime() - maxLive > entry.getTime().getTime()) - f.delete(); - } catch (Exception e) { - f.delete(); - } - } -} diff --git a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Finder.java b/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Finder.java deleted file mode 100644 index 57e3d13eb..000000000 --- a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Finder.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.aol.micro.server.application.registry; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Stream; - -import org.apache.commons.io.FileUtils; -import org.pcollections.ConsPStack; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -@Component -public class Finder { - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final RegisterConfig config; - - @Autowired - public Finder(RegisterConfig config) { - this.config = config; - } - - public List find() { - return findDir(new File(config.getOutputDir())); - } - - private List findDir(File dir) { - List result = new ArrayList<>(); - - Stream.of(dir.listFiles()).forEach( - (next) -> { - - if (next.isDirectory()) - result.addAll(findDir(next)); - if (next.isFile()) { - try { - String fileString = FileUtils.readFileToString(next); - result.add(JacksonUtil.convertFromJson(fileString, RegisterEntry.class)); - } catch (Exception e) { - logger.error("Error loading service entry from disk {}", e, - next.getAbsolutePath()); - - } - } - }); - return ConsPStack.from(result); - } -} diff --git a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Job.java b/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Job.java deleted file mode 100644 index 9d037a08f..000000000 --- a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Job.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.aol.micro.server.application.registry; - -import java.util.Date; -import java.util.UUID; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.rest.jackson.JacksonUtil; - -@Component -public class Job { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final AsyncRestClient rest = new AsyncRestClient(100,2000); - private final String apiUrl; - private final ApplicationRegisterImpl app; - private final String uuid = UUID.randomUUID().toString(); - private final String resourcePath; - - @Autowired - public Job(@Value("${service.registry.url:null}") String apiUrl, ApplicationRegisterImpl app, - @Value("${resource.path:/service-registry/register}") String resourcePath) { - - this.apiUrl = apiUrl; - this.app = app; - this.resourcePath = resourcePath; - - } - - @Scheduled(fixedDelayString = "${service.registry.delay:300000}") - public synchronized void schedule() { - if(app.getApplication()!=null && apiUrl!=null) - app.getApplication().forEach(moduleEntry -> sendPing(moduleEntry)); - } - - private void sendPing(RegisterEntry moduleEntry) { - final RegisterEntry entry = moduleEntry.withTime(new Date()) - .withUuid(uuid); - try { - - logger.info("Posting {} to " + apiUrl + resourcePath, JacksonUtil.serializeToJson(entry)); - rest.post(apiUrl + resourcePath, JacksonUtil.serializeToJson(entry)).join(); - } catch (Exception e) { - logger.warn("Failed posting {} to {}"+resourcePath, JacksonUtil.serializeToJson(entry), apiUrl); - - } - } -} diff --git a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Register.java b/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Register.java deleted file mode 100644 index d148512b3..000000000 --- a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/Register.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.aol.micro.server.application.registry; - -import java.io.File; -import java.io.IOException; - -import lombok.val; - -import org.apache.commons.io.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.ip.tracker.*; -import com.aol.micro.server.rest.jackson.JacksonUtil; - - -@Component -public class Register { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final RegisterConfig config; - - @Autowired - public Register(RegisterConfig config) { - this.config = config; - } - - public void register(final RegisterEntry entry) { - - File dir = new File(config.getOutputDir(), "" + entry.getModule()); - dir.mkdirs(); - - File file = new File(dir, entry.getHostname() + "-" + entry.getModule() + "-" + entry.getUuid()); - try { - final RegisterEntry entryToUse = "use-ip".equals(entry.getHostname()) ? - entry.withHostname(QueryIPRetriever.getIpAddress()) : entry; - - - FileUtils.writeStringToFile(file, JacksonUtil.serializeToJson(entryToUse)); - } catch (IOException e) { - logger.error("Error registering service to disk {}", JacksonUtil.serializeToJson(entry)); - } - } -} diff --git a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/RegisterConfig.java b/micro-application-register/src/main/java/com/aol/micro/server/application/registry/RegisterConfig.java deleted file mode 100644 index 997c2d031..000000000 --- a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/RegisterConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.aol.micro.server.application.registry; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.experimental.FieldDefaults; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) -@Getter -@Component -public class RegisterConfig { - - String outputDir; - - @Autowired - public RegisterConfig(@Value("${service.registry.dir:#{systemProperties['java.io.tmpdir']}/services}") String outputDir) { - this.outputDir = outputDir; - } - -} diff --git a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/RegisterEntry.java b/micro-application-register/src/main/java/com/aol/micro/server/application/registry/RegisterEntry.java deleted file mode 100644 index ce85ee0fb..000000000 --- a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/RegisterEntry.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.aol.micro.server.application.registry; - -import java.util.Date; -import java.util.UUID; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.experimental.FieldDefaults; -import lombok.experimental.Wither; - -@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) -@XmlAccessorType(XmlAccessType.FIELD) -@XmlRootElement(name = "register-entry") -@XmlType(name = "") -@Getter -@Wither -@Builder -public class RegisterEntry { - - int port; - String hostname; - String module; - String context; - Date time; - String uuid; - String target; - - public RegisterEntry() { - this(-1, null, null, null, null, null, null); - } - - public RegisterEntry(int port, String hostname, String module, String context, Date time, - String uuid, String target) { - this.port = port; - this.hostname = hostname; - this.module = module; - this.context = context; - this.time = time; - this.uuid = uuid; - this.target = target; - } - - public RegisterEntry(int port, String hostname, String module, String context, - Date time,String target) { - this(port, hostname, module, context, time, UUID.randomUUID().toString(),target); - } -} diff --git a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/ServiceRegistryResource.java b/micro-application-register/src/main/java/com/aol/micro/server/application/registry/ServiceRegistryResource.java deleted file mode 100644 index 585428890..000000000 --- a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/ServiceRegistryResource.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.aol.micro.server.application.registry; - -import java.util.Arrays; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.container.Suspended; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.micro.server.WorkerThreads; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.utility.HashMapBuilder; - - -@Rest -@Path("/service-registry") -public class ServiceRegistryResource{ - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final Cleaner cleaner; - private final Finder finder; - private final Register register; - private final Job job; - - @Autowired - public ServiceRegistryResource(Cleaner cleaner, Finder finder, Register register, Job job) { - - this.cleaner = cleaner; - this.finder = finder; - this.register = register; - this.job = job; - } - - @GET - @Path("/list") - @Produces("application/json") - public void list(@Suspended AsyncResponse response) { - ReactiveSeq.of(this) - .futureOperations(WorkerThreads.ioExecutor.get()) - .forEach(next -> { - try{ - cleaner.clean(); - response.resume(finder.find()); - }catch(Exception e){ - logger.error(e.getMessage(),e); - response.resume(Arrays.asList("failed due to error")); - } - }); - - } - - @POST - @Path("/schedule") - @Consumes("application/json") - @Produces("application/json") - public void schedule(@Suspended AsyncResponse response) { - ReactiveSeq.of(this) - .futureOperations(WorkerThreads.ioExecutor.get()) - .forEach(next -> { - try{ - job.schedule(); - response.resume(HashMapBuilder.of("status", "success")); - }catch(Exception e){ - logger.error(e.getMessage(),e); - response.resume(HashMapBuilder.of("status", "failure")); - } - }); - - } - - @POST - @Path("/register") - @Consumes("application/json") - @Produces("application/json") - public void register(@Suspended AsyncResponse response,RegisterEntry entry) { - ReactiveSeq.of(this) - .futureOperations(WorkerThreads.ioExecutor.get()) - .forEach(next -> { - try{ - register.register(entry); - response.resume(HashMapBuilder.of("status", "complete")); - }catch(Exception e){ - logger.error(e.getMessage(),e); - response.resume(HashMapBuilder.of("status", "failure")); - } - }); - - } - -} diff --git a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/plugin/ApplicationRegistryPlugin.java b/micro-application-register/src/main/java/com/aol/micro/server/application/registry/plugin/ApplicationRegistryPlugin.java deleted file mode 100644 index b518de5a2..000000000 --- a/micro-application-register/src/main/java/com/aol/micro/server/application/registry/plugin/ApplicationRegistryPlugin.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aol.micro.server.application.registry.plugin; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.application.registry.ApplicationRegisterImpl; -import com.aol.micro.server.application.registry.Cleaner; -import com.aol.micro.server.application.registry.Finder; -import com.aol.micro.server.application.registry.Job; -import com.aol.micro.server.application.registry.Register; -import com.aol.micro.server.application.registry.RegisterConfig; -import com.aol.micro.server.application.registry.ServiceRegistryResource; - -public class ApplicationRegistryPlugin implements Plugin { - - @Override - public PSetX springClasses() { - return PSetX.of(ApplicationRegisterImpl.class, - Cleaner.class,Register.class, ServiceRegistryResource.class, - RegisterConfig.class,Job.class, Finder.class); - } - -} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Application.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Application.java new file mode 100644 index 000000000..101e58911 --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Application.java @@ -0,0 +1,33 @@ +package com.oath.micro.server.application.registry; + +import java.util.Iterator; +import java.util.List; + +import com.oath.cyclops.types.persistent.PersistentList; +import cyclops.data.Seq; +import lombok.AccessLevel; +import lombok.experimental.FieldDefaults; + + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) +public class Application implements Iterable { + + PersistentList entries; + + public Application(final List entries) { + this.entries = Seq.fromIterable(entries); + } + + @Override + public Iterator iterator() { + return entries.iterator(); + } + + public String toString() { + return JacksonUtil.serializeToJson(entries); + } + + +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/ApplicationRegisterImpl.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/ApplicationRegisterImpl.java new file mode 100644 index 000000000..b0731f423 --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/ApplicationRegisterImpl.java @@ -0,0 +1,85 @@ +package com.oath.micro.server.application.registry; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Optional; +import java.util.Properties; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.oath.cyclops.util.ExceptionSoftener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.servers.ApplicationRegister; +import com.oath.micro.server.servers.model.ServerData; + +import lombok.Getter; + +@Component +public class ApplicationRegisterImpl implements ApplicationRegister { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final String customHostname; + private final String targetEndpoint; + private final Properties props; + @Getter + private volatile Application application; + + @Autowired + public ApplicationRegisterImpl(@Value("${host.address:#{null}}") String customHostname, + @Value("${target.endpoint:#{null}}") String targetEndpoint, + @Qualifier("propertyFactory") Properties props) { + + this.customHostname = customHostname; + this.targetEndpoint = targetEndpoint; + this.props = props; + } + + public ApplicationRegisterImpl() { + this(null, null, new Properties()); + } + + @Override + public void register(ServerData[] data) { + + try { + final String hostname = Optional.ofNullable(customHostname) + .orElse(InetAddress.getLocalHost() + .getHostName()); + + application = new Application( + Stream.of(data) + .map(next -> new RegisterEntry( + next.getPort(), + hostname, + next.getModule().getContext(), + next.getModule().getContext(), + null, + targetEndpoint, + externalPort(next))) + .collect(Collectors.toList())); + logger.info("Registered application {} ", application); + } catch (UnknownHostException e) { + throw ExceptionSoftener.throwSoftenedException(e); + } + } + + private int externalPort(ServerData next) { + String ep = props.getProperty("external.port." + next.getModule().getContext()); + if (ep == null) { + return next.getPort(); + } + try { + return Integer.valueOf(ep); + } catch (NumberFormatException e) { + return next.getPort(); + } + + } +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Cleaner.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Cleaner.java new file mode 100644 index 000000000..248996145 --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Cleaner.java @@ -0,0 +1,68 @@ +package com.oath.micro.server.application.registry; + +import java.io.File; +import java.util.Date; +import java.util.stream.Stream; + +import javax.annotation.PostConstruct; + +import org.apache.commons.io.FileUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +@Component +public class Cleaner { + + private final RegisterConfig config; + private final int maxLive; + + @Autowired + public Cleaner(RegisterConfig config, + @Value("${service.registry.entry.max.live:43200000}") int maxLive) { + this.config = config; + this.maxLive = maxLive; + } + + @PostConstruct + public void deleteOldFilesAfterEachStartup() { + cleanDir(new File(config.getOutputDir()), true); + } + + public void clean() { + cleanDir(new File(config.getOutputDir()), false); + } + + private void cleanDir(File dir, boolean deleteWithoutCheck) { + if (dir.listFiles() != null) { + Stream.of(dir.listFiles()).forEach((next) -> { + if (next.isDirectory()) { + cleanDir(next, deleteWithoutCheck); + } + + if (next.isFile()) { + if (deleteWithoutCheck) { + next.delete(); + } else { + checkFile(next); + } + } + + }); + } + } + + private void checkFile(File f) { + try { + RegisterEntry entry = JacksonUtil + .convertFromJson(FileUtils.readFileToString(f), RegisterEntry.class); + if (new Date().getTime() - maxLive > entry.getTime().getTime()) { + f.delete(); + } + } catch (Exception e) { + f.delete(); + } + } +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Finder.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Finder.java new file mode 100644 index 000000000..ff7b52b45 --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Finder.java @@ -0,0 +1,68 @@ +package com.oath.micro.server.application.registry; + +import java.io.File; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import cyclops.reactive.collections.mutable.ListX; +import org.apache.commons.io.FileUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +@Component +public class Finder { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final RegisterConfig config; + + @Autowired + public Finder(RegisterConfig config) { + this.config = config; + } + + public List find(final Optional re) { + try { + List entries = findDir(new File(config.getOutputDir())); + if (re.isPresent()) { + entries = entries.stream().filter(e -> e.matches(re.get())) + .collect(Collectors.toList()); + } + return entries; + } catch (Exception e) { + logger.error("Failed to find entries. Error: {}", e.getMessage(), e); + return Collections.emptyList(); + } + } + + private List findDir(File dir) { + List result = new ArrayList<>(); + + Stream.of(dir.listFiles()).forEach( + (next) -> { + + if (next.isDirectory()) { + result.addAll(findDir(next)); + } + if (next.isFile()) { + try { + String fileString = FileUtils.readFileToString(next, Charset.defaultCharset()); + result.add(JacksonUtil.convertFromJson(fileString, RegisterEntry.class)); + } catch (Exception e) { + logger.error("Error loading service entry from disk {}, Error: {}", next.getAbsolutePath(), e.getMessage(), e); + } + } + }); + return ListX.fromIterable(result); + } +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Health.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Health.java new file mode 100644 index 000000000..d8ba4c061 --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Health.java @@ -0,0 +1,5 @@ +package com.oath.micro.server.application.registry; + +public enum Health { + OK, ERROR +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Job.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Job.java new file mode 100644 index 000000000..4b75ce32a --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Job.java @@ -0,0 +1,86 @@ +package com.oath.micro.server.application.registry; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.annotation.PostConstruct; + +import lombok.Getter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.rest.jackson.JacksonUtil; + +@Component +public class Job { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final AsyncRestClient rest = new AsyncRestClient(100, 2000); + private final String apiUrl; + private final ApplicationRegisterImpl app; + private final String uuid = UUID.randomUUID().toString(); + private final String resourcePath; + private final RegistryHealthChecker checker; + private final RegistryStatsChecker statsChecker; + @Getter + private int scheduled =0; + + @Autowired + public Job(@Value("${service.registry.url:#{null}}") String apiUrl, ApplicationRegisterImpl app, + @Value("${resource.path:/service-registry/register}") String resourcePath, + RegistryHealthChecker checker, + RegistryStatsChecker statsChecker) { + + this.apiUrl = apiUrl; + this.app = app; + this.resourcePath = resourcePath; + this.checker = checker; + this.statsChecker = statsChecker; + + } + + @PostConstruct + @Scheduled(fixedDelayString = "${service.registry.delay:1000}") + public synchronized void schedule() { + scheduled++; + try { + if (app.getApplication() != null && apiUrl != null) { + app.getApplication() + .forEach(this::sendPing); + } + } catch (Exception e) { + logger.error("Failed to register services due to exception {}", e.getMessage(), e); + } + } + + private void sendPing(RegisterEntry moduleEntry) { + final RegisterEntry entry = moduleEntry.withTime(new Date()) + .withUuid(uuid) + .withHealth(checker.isOk() ? Health.OK : Health.ERROR) + .withStats(nonEmptyOrNull(statsChecker.stats())); + + String payload = JacksonUtil.serializeToJson(entry); + + try { + logger.debug("Posting {} to {}{}", payload, apiUrl, resourcePath); + rest.post(apiUrl + resourcePath, payload).join(); + } catch (Exception e) { + logger.warn("Failed posting {} to {}{}, Error: {}", payload, apiUrl, resourcePath, e.getMessage(), e); + } + } + + private List>> nonEmptyOrNull( + List>> stats) { + if (stats == null || stats.isEmpty()) { + return null; + } + return stats; + } +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/ManifestLoader.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/ManifestLoader.java new file mode 100644 index 000000000..d8f68d201 --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/ManifestLoader.java @@ -0,0 +1,63 @@ +package com.oath.micro.server.application.registry; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import cyclops.function.FluentFunctions; +import cyclops.reactive.ReactiveSeq; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ManifestLoader { + + public final static ManifestLoader instance = new ManifestLoader(); + private final Logger logger = LoggerFactory.getLogger(getClass()); + Supplier> fn = FluentFunctions.of(this::manifest).memoize(); + + public Map getManifest() { + return fn.get(); + } + + private Map manifest() { + + try { + return ReactiveSeq.of("META-INF/MANIFEST.MF") + .map(url -> this.getClass() + .getClassLoader() + .getResourceAsStream(url)) + .map(this::getManifest) + .single() + .orElse(null); + } catch (Exception e) { + logger.warn("Warning : can't load manifest due to exception {}", e.getMessage()); + } + return null; + + } + + public Map getManifest(final InputStream input) { + + final Map retMap = new HashMap(); + try { + Manifest manifest = new Manifest(); + manifest.read(input); + final Attributes attributes = manifest.getMainAttributes(); + for (final Map.Entry attribute : attributes.entrySet()) { + retMap.put(attribute.getKey().toString(), attribute.getValue().toString()); + } + } catch (final Exception ex) { + logger.error("Failed to load manifest ", ex); + } + + return retMap; + } +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Register.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Register.java new file mode 100644 index 000000000..937da613a --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/Register.java @@ -0,0 +1,43 @@ +package com.oath.micro.server.application.registry; + +import java.io.File; +import java.io.IOException; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.ip.tracker.*; +import com.oath.micro.server.rest.jackson.JacksonUtil; + + +@Component +public class Register { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final RegisterConfig config; + + @Autowired + public Register(RegisterConfig config) { + this.config = config; + } + + public void register(final RegisterEntry entry) { + + File dir = new File(config.getOutputDir(), "" + entry.getModule()); + dir.mkdirs(); + + File file = new File(dir, + entry.getHostname() + "-" + entry.getModule() + "-" + entry.getUuid()); + try { + final RegisterEntry entryToUse = "use-ip".equals(entry.getHostname()) ? + entry.withHostname(QueryIPRetriever.getIpAddress()) : entry; + + FileUtils.writeStringToFile(file, JacksonUtil.serializeToJson(entryToUse)); + } catch (IOException e) { + logger.error("Error registering service to disk {}", JacksonUtil.serializeToJson(entry)); + } + } +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/RegisterConfig.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/RegisterConfig.java new file mode 100644 index 000000000..61d625761 --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/RegisterConfig.java @@ -0,0 +1,24 @@ +package com.oath.micro.server.application.registry; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.experimental.FieldDefaults; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) +@Getter +@Component +public class RegisterConfig { + + String outputDir; + + @Autowired + public RegisterConfig( + @Value("${service.registry.dir:#{systemProperties['java.io.tmpdir']}/services}") String outputDir) { + this.outputDir = outputDir; + } + +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/RegisterEntry.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/RegisterEntry.java new file mode 100644 index 000000000..696d97048 --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/RegisterEntry.java @@ -0,0 +1,119 @@ +package com.oath.micro.server.application.registry; + +import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; + +import java.text.SimpleDateFormat; +import java.util.*; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.FieldDefaults; +import lombok.experimental.Wither; + +@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "register-entry") +@XmlType(name = "") +@Getter +@Wither +@Builder +@ToString +public class RegisterEntry { + + private static SimpleDateFormat f = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); + @Wither + private final int port; + @Wither + private final String hostname; + @Wither + private final String module; + @Wither + private final String context; + private final Date time; + @Wither + private final String uuid; + @Wither + private final String target; + private final String formattedDate; + private final Map manifest = new HashMap<>(); + @Wither + private final Health health; + @Wither + private final List>> stats; + @Wither + private final int externalPort; + + public RegisterEntry() { + this(-1, null, null, null, null, null, null, -1); + } + + public RegisterEntry(int port, String hostname, String module, String context, Date time, + String uuid, + String target, int externalPort) { + this(port, hostname, module, context, time, uuid, target, null, Health.OK, null, + externalPort); + } + + public RegisterEntry(int port, String hostname, String module, String context, Date time, + String target, + int externalPort) { + this(port, hostname, module, context, time, UUID.randomUUID().toString(), target, + externalPort); + } + + private RegisterEntry(int port, String hostname, String module, String context, Date time, + String uuid, + String target, String ignoreDate, Health health, + List>> stats, + int externalPort) { + this.port = port; + this.hostname = hostname; + this.module = module; + this.context = context; + this.time = time; + this.uuid = uuid; + this.target = target; + this.health = health; + this.stats = stats; + this.externalPort = externalPort; + + if (time != null) { + this.formattedDate = f.format(this.time); + } else { + this.formattedDate = null; + } + + this.manifest.putAll(ManifestLoader.instance.getManifest()); + + } + + public boolean matches(RegisterEntry re) { + //Only the fields which make sense to query is added for now. + return (re.port == -1 || re.port == port) && + (isNull(re.hostname) || nonNull(hostname) && hostname.startsWith(re.hostname)) && + (isNull(re.module) || nonNull(module) && module.startsWith(re.module)) && + (isNull(re.context) || nonNull(context) && context.startsWith(re.context)) && + (isNull(re.health) || re.health.equals(health)) && + (re.externalPort == -1 || re.externalPort == externalPort) && + (isNull(re.manifest) || re.manifest.isEmpty() || matchManifest(re.manifest)); + } + + private boolean matchManifest(Map manifest) { + return match(manifest, this.manifest, "Implementation-revision") && + match(manifest, this.manifest, "Implementation-Timestamp") && + match(manifest, this.manifest, "Implementation-Version"); + } + + private boolean match(Map map1, Map map2, String key) { + return !map1.containsKey(key) || (map2.containsKey(key) && map2.get(key) + .startsWith(map1.get(key))); + } +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/RegistryHealthChecker.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/RegistryHealthChecker.java new file mode 100644 index 000000000..760f64a30 --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/RegistryHealthChecker.java @@ -0,0 +1,31 @@ +package com.oath.micro.server.application.registry; + +import java.util.List; + +import cyclops.companion.Semigroups; +import cyclops.reactive.collections.mutable.ListX; +import cyclops.function.Monoid; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.HealthStatusChecker; + +@Component +public class RegistryHealthChecker { + + private final ListX status; + + public RegistryHealthChecker() { + status = ListX.empty(); + } + + @Autowired(required = false) + public RegistryHealthChecker(final List status) { + this.status = ListX.fromIterable(status); + } + + public boolean isOk() { + return status.map(HealthStatusChecker::isOk) + .foldLeft(Monoid.of(true, Semigroups.booleanConjunction)); + } +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/RegistryStatsChecker.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/RegistryStatsChecker.java new file mode 100644 index 000000000..e003d814b --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/RegistryStatsChecker.java @@ -0,0 +1,39 @@ +package com.oath.micro.server.application.registry; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import cyclops.reactive.collections.mutable.ListX; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.StatsSupplier; + +@Component +public class RegistryStatsChecker { + + private final ListX status; + private final boolean active; + + public RegistryStatsChecker() { + status = ListX.empty(); + this.active = false; + } + + @Autowired(required = false) + public RegistryStatsChecker(final List status, + @Value("${service.registry.stats.active:true}") boolean active) { + this.status = ListX.fromIterable(status); + this.active = active; + } + + public List>> stats() { + if (!active) { + return null; + } + return status.map(StatsSupplier::get).filter(Objects::nonNull); + } +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/ServiceRegistryResource.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/ServiceRegistryResource.java new file mode 100644 index 000000000..471444b46 --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/ServiceRegistryResource.java @@ -0,0 +1,91 @@ +package com.oath.micro.server.application.registry; + +import java.util.Arrays; + +import javax.ws.rs.*; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.UriInfo; + +import cyclops.reactive.ReactiveSeq; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + + +import com.oath.micro.server.WorkerThreads; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.utility.HashMapBuilder; + + +@Rest +@Path("/service-registry") +public class ServiceRegistryResource { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final Cleaner cleaner; + private final Finder finder; + private final Register register; + private final Job job; + + @Autowired + public ServiceRegistryResource(Cleaner cleaner, Finder finder, Register register, Job job) { + + this.cleaner = cleaner; + this.finder = finder; + this.register = register; + this.job = job; + } + + @GET + @Path("/list") + @Produces("application/json") + public void list(@Context UriInfo uriInfo, @Suspended AsyncResponse response) { + ReactiveSeq.of(this).foldFuture(WorkerThreads.ioExecutor.get(), + s -> s.forEach(Long.MAX_VALUE, next -> { + try { + cleaner.clean(); + response.resume(finder.find(UriInfoParser.toRegisterEntry(uriInfo))); + } catch (Exception e) { + logger.error("list failed with error: {}", e.getMessage(), e); + response.resume(Arrays.asList("Bad Request: " + e.getMessage())); + } + })); + } + + @POST + @Path("/schedule") + @Consumes("application/json") + @Produces("application/json") + public void schedule(@Suspended AsyncResponse response) { + ReactiveSeq.of(this).foldFuture(WorkerThreads.ioExecutor.get(), s -> + s.forEach(Long.MAX_VALUE, next -> { + try { + job.schedule(); + response.resume(HashMapBuilder.of("status", "success")); + } catch (Exception e) { + logger.error("schedule failed with error: {}", e.getMessage(), e); + response.resume(HashMapBuilder.of("status", "failure")); + } + })); + + } + + @POST + @Path("/register") + @Consumes("application/json") + @Produces("application/json") + public void register(@Suspended AsyncResponse response, RegisterEntry entry) { + ReactiveSeq.of(this).foldFuture(WorkerThreads.ioExecutor.get(), + s -> s.forEach(Long.MAX_VALUE, next -> { + try { + register.register(entry); + response.resume(HashMapBuilder.of("status", "complete")); + } catch (Exception e) { + logger.error("register failed with error: {}", e.getMessage(), e); + response.resume(HashMapBuilder.of("status", "failure")); + } + })); + } +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/UriInfoParser.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/UriInfoParser.java new file mode 100644 index 000000000..97845128a --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/UriInfoParser.java @@ -0,0 +1,66 @@ +package com.oath.micro.server.application.registry; + +import cyclops.reactive.ReactiveSeq; + +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.UriInfo; +import java.util.Arrays; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +public class UriInfoParser { + + public static Optional toRegisterEntry(UriInfo uriInfo) { + if (uriInfo.getQueryParameters().isEmpty()) { + return Optional.empty(); + } else { + MultivaluedMap parameters = uriInfo.getQueryParameters(); + RegisterEntry re = RegisterEntry.builder() + .context(parameters.getFirst("context")) + .hostname(parameters.getFirst("hostname")) + .port(toInt(parameters.getFirst("port"))) + .target(parameters.getFirst("target")) + .externalPort(toInt(parameters.getFirst("externalPort"))) + .module(parameters.getFirst("module")) + .health(toHealth(parameters.getFirst("health"))) + .build(); + + Map manifest = ReactiveSeq.fromIterable(parameters.entrySet()) + .filter(e -> e.getKey().startsWith("manifest.")) + .toMap(e -> e.getKey().replace("manifest.", ""), + e -> parameters.getFirst(e.getKey())); + + re.getManifest().clear(); + re.getManifest().putAll(manifest); + + return Optional.of(re); + } + } + + private static Health toHealth(String health) { + if (Objects.nonNull(health)) { + try { + return Health.valueOf(health); + } catch (Exception e) { + throw new IllegalArgumentException( + "'" + health + "' is not valid, valid values are " + + Arrays.asList(Health.values())); + } + } + return null; + } + + private static int toInt(String port) { + if (Objects.isNull(port)) { + return -1; + } + + try { + return Integer.valueOf(port); + } catch (Exception e) { + throw new IllegalArgumentException("'" + port + "' is not a valid number."); + } + } + +} diff --git a/micro-application-register/src/main/java/com/oath/micro/server/application/registry/plugin/ApplicationRegistryPlugin.java b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/plugin/ApplicationRegistryPlugin.java new file mode 100644 index 000000000..d139ea662 --- /dev/null +++ b/micro-application-register/src/main/java/com/oath/micro/server/application/registry/plugin/ApplicationRegistryPlugin.java @@ -0,0 +1,34 @@ +package com.oath.micro.server.application.registry.plugin; + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.application.registry.ApplicationRegisterImpl; +import com.oath.micro.server.application.registry.Cleaner; +import com.oath.micro.server.application.registry.Finder; +import com.oath.micro.server.application.registry.RegistryHealthChecker; +import com.oath.micro.server.application.registry.Job; +import com.oath.micro.server.application.registry.Register; +import com.oath.micro.server.application.registry.RegisterConfig; +import com.oath.micro.server.application.registry.ServiceRegistryResource; +import com.oath.micro.server.application.registry.RegistryStatsChecker; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +public class ApplicationRegistryPlugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of( + ApplicationRegisterImpl.class, + Cleaner.class, + Register.class, + ServiceRegistryResource.class, + RegisterConfig.class, + Job.class, + Finder.class, + RegistryHealthChecker.class, + RegistryStatsChecker.class + ); + } + +} diff --git a/micro-application-register/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-application-register/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 0118af46a..000000000 --- a/micro-application-register/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.application.registry.plugin.ApplicationRegistryPlugin \ No newline at end of file diff --git a/micro-application-register/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-application-register/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..5c1d6e16f --- /dev/null +++ b/micro-application-register/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.application.registry.plugin.ApplicationRegistryPlugin \ No newline at end of file diff --git a/micro-application-register/src/test/java/app/registry/com/aol/micro/server/RegistryAppRunner.java b/micro-application-register/src/test/java/app/registry/com/aol/micro/server/RegistryAppRunner.java deleted file mode 100644 index 103071c00..000000000 --- a/micro-application-register/src/test/java/app/registry/com/aol/micro/server/RegistryAppRunner.java +++ /dev/null @@ -1,74 +0,0 @@ -package app.registry.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.assertThat; - -import java.util.Date; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.application.registry.RegisterEntry; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.rest.jackson.JacksonUtil; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(properties={"service.registry.url","http://localhost:8080/registry-app", - "target.endpoint","configured-target"}) -public class RegistryAppRunner { - - - RestAgent rest = new RestAgent(); - private final AsyncRestClient restAsync = new AsyncRestClient(100,2000); - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( ()-> "registry-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - Thread.sleep(1000); - - assertThat(rest.post("http://localhost:8080/registry-app/service-registry/schedule"),is("{\"status\":\"success\"}")); - Thread.sleep(1000); - assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"),containsString("[{\"port\":8080,")); - - sendPing(new RegisterEntry(8081,"use-ip","hello","world", new Date(),"my-target")); - Thread.sleep(1000); - System.out.println(rest.getJson("http://localhost:8080/registry-app/service-registry/list")); - assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"),containsString("[{\"port\":8081,")); - assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"),containsString("\"target\":\"my-target\"")); - assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"),containsString("\"target\":\"configured-target\"")); - assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"),not(containsString("\"hostname\":\"test-host\""))); - - } - - private void sendPing(RegisterEntry entry) { - - try { - - restAsync.post("http://localhost:8080/registry-app/service-registry/register", JacksonUtil.serializeToJson(entry)).join(); - } catch (Exception e) { - - } - } - - - - -} \ No newline at end of file diff --git a/micro-application-register/src/test/java/app/registry/com/oath/micro/server/RegistryAppRunner.java b/micro-application-register/src/test/java/app/registry/com/oath/micro/server/RegistryAppRunner.java new file mode 100644 index 000000000..c508b4e87 --- /dev/null +++ b/micro-application-register/src/test/java/app/registry/com/oath/micro/server/RegistryAppRunner.java @@ -0,0 +1,176 @@ +package app.registry.com.oath.micro.server; + +import static java.util.stream.Collectors.joining; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertThat; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.stream.Stream; + +import com.fasterxml.jackson.core.type.TypeReference; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.application.registry.RegisterEntry; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { + "service.registry.url", + "http://localhost:8080/registry-app", + "target.endpoint", + "configured-target" +}) +public class RegistryAppRunner { + + private final AsyncRestClient restAsync = new AsyncRestClient(100, 2000); + RestAgent rest = new RestAgent(); + MicroserverApp server; + + String baseUrl = "http://localhost:8080/registry-app/service-registry"; + + @Before + public void startServer() { + server = new MicroserverApp(() -> "registry-app"); + server.start(); + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + SimpleDateFormat f = new SimpleDateFormat("EEE"); + String date = f.format(new Date()); + Thread.sleep(1000); + + assertThat(rest.post(baseUrl + "/schedule"), is("{\"status\":\"success\"}")); + Thread.sleep(1000); + + String listResponse = rest.getJson(baseUrl + "/list"); + + assertThat(listResponse, containsString("[{\"port\":8080,")); + assertThat(listResponse, containsString("externalPort\":8080")); + + sendPing("1", 8081, "use-ip", "hello", "world", "my-target", 8082); + Thread.sleep(1000); + + listResponse = rest.getJson(baseUrl + "/list"); + + assertThat(listResponse, containsString("{\"port\":8081,")); + assertThat(listResponse, containsString("\"target\":\"my-target\"")); + assertThat(listResponse, containsString("\"target\":\"configured-target\"")); + assertThat(listResponse, not(containsString("\"hostname\":\"test-host\""))); + assertThat(listResponse, containsString("\"formattedDate\"")); + assertThat(listResponse, containsString("\"manifest\"")); + assertThat(listResponse, containsString("Manifest-Version")); + assertThat(listResponse, containsString(date)); + + } + + @Test + public void filterTest() throws Exception { + Thread.sleep(1000); + + List entries = list(); + assertThat(entries.size(), is(1)); + + sendPing("121", 8080, "host1", "module1", "context1", "target1", 9080); + sendPing("122", 8080, "host2", "module1", "context1", "target1", 9080); + sendPing("131", 6080, "host3", "module2", "context2", "target2", 7080); + sendPing("132", 6080, "host4", "module2", "context2", "target2", 7080); + + entries = list(); + assertThat(entries.size(), is(5)); + + entries = list("port=8080"); + assertThat(entries.size(), is(3)); + + entries = list("port=8080", "externalPort=9080"); + System.out.println(entries); + assertThat(entries.size(), is(2)); + + entries = list("port=8080", "externalPort=9080", "module=module", "context=context1"); + assertThat(entries.size(), is(2)); + + entries = list("port=8080", "externalPort=9080", "module=module", "context=context1", + "hostname=host1"); + assertThat(entries.size(), is(1)); + + entries = list("port=8080", "externalPort=9080", "module=module1", "context=context2"); + assertThat(entries.size(), is(0)); + + entries = list("manifest.Implementation-Version=version"); + assertThat(entries.size(), is(4)); + + entries = list("manifest.Implementation-Version=version1"); + assertThat(entries.size(), is(4)); + + entries = list("manifest.Implementation-Version=version121"); + assertThat(entries.size(), is(1)); + + entries = list("manifest.Implementation-revision=rev12"); + assertThat(entries.size(), is(2)); + + entries = list("manifest.Implementation-Timestamp=2017_13"); + assertThat(entries.size(), is(2)); + + entries = list("health=OK"); + assertThat(entries.size(), is(5)); + + List list = JacksonUtil.convertFromJson(rest.getJson(baseUrl + "/list?port=OK"), + new TypeReference>() { + }); + assertThat(list.size(), is(1)); + assertThat(list.get(0), is("Bad Request: 'OK' is not a valid number.")); + + list = JacksonUtil.convertFromJson(rest.getJson(baseUrl + "/list?health=Suspended"), + new TypeReference>() { + }); + assertThat(list.size(), is(1)); + assertThat(list.get(0), + is("Bad Request: 'Suspended' is not valid, valid values are [OK, ERROR]")); + } + + private List list(String... parameters) { + String url = baseUrl + "/list?" + Stream.of(parameters).collect(joining("&")); + return JacksonUtil + .convertFromJson(rest.getJson(url), new TypeReference>() { + }); + } + + private void sendPing(String uuid, int port, String hostName, String module, String context, + String target, int externalPort) { + try { + RegisterEntry re = RegisterEntry.builder() + .port(port) + .hostname(hostName) + .module(module) + .context(context) + .time(new Date()) + .uuid(uuid) + .target(target) + .externalPort(externalPort) + .build(); + re.getManifest().put("Implementation-revision", "rev" + uuid); + re.getManifest().put("Implementation-Version", "version" + uuid); + re.getManifest().put("Implementation-Timestamp", "2017_" + uuid); + restAsync.post("http://localhost:8080/registry-app/service-registry/register", + JacksonUtil.serializeToJson(re)) + .get(); + } catch (Exception e) { + } + } +} diff --git a/micro-application-register/src/test/java/app/registry/config/com/aol/micro/server/RegistryAppRunner.java b/micro-application-register/src/test/java/app/registry/config/com/aol/micro/server/RegistryAppRunner.java deleted file mode 100644 index 174dc87eb..000000000 --- a/micro-application-register/src/test/java/app/registry/config/com/aol/micro/server/RegistryAppRunner.java +++ /dev/null @@ -1,73 +0,0 @@ -package app.registry.config.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.assertThat; - -import java.util.Date; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.application.registry.RegisterEntry; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.rest.jackson.JacksonUtil; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(properties={"service.registry.url","http://localhost:8080/registry-app", - "host.address","test-host"}) -public class RegistryAppRunner { - - - RestAgent rest = new RestAgent(); - private final AsyncRestClient restAsync = new AsyncRestClient(100,2000); - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( ()-> "registry-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - Thread.sleep(1000); - - assertThat(rest.post("http://localhost:8080/registry-app/service-registry/schedule"),is("{\"status\":\"success\"}")); - Thread.sleep(1000); - assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"),containsString("[{\"port\":8080,")); - - sendPing(new RegisterEntry(8081,"use-ip","hello","world", new Date(),"my-target")); - Thread.sleep(1000); - System.out.println(rest.getJson("http://localhost:8080/registry-app/service-registry/list")); - assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"),containsString("[{\"port\":8081,")); - assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"),containsString("\"hostname\":\"test-host\"")); - assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"),not(containsString("\"target\":\"configured-target\""))); - - } - - private void sendPing(RegisterEntry entry) { - - try { - - restAsync.post("http://localhost:8080/registry-app/service-registry/register", JacksonUtil.serializeToJson(entry)).join(); - } catch (Exception e) { - - } - } - - - - -} \ No newline at end of file diff --git a/micro-application-register/src/test/java/app/registry/config/com/oath/micro/server/HealthCheckerResource.java b/micro-application-register/src/test/java/app/registry/config/com/oath/micro/server/HealthCheckerResource.java new file mode 100644 index 000000000..7a0f8a05e --- /dev/null +++ b/micro-application-register/src/test/java/app/registry/config/com/oath/micro/server/HealthCheckerResource.java @@ -0,0 +1,45 @@ +package app.registry.config.com.oath.micro.server; + +import java.util.Map; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import com.oath.micro.server.HealthStatusChecker; +import com.oath.micro.server.StatsSupplier; +import com.oath.micro.server.auto.discovery.Rest; +import cyclops.reactive.companion.MapXs; + + +@Rest +@Path("/health") +public class HealthCheckerResource implements HealthStatusChecker, StatsSupplier { + + private volatile boolean ok = true; + private volatile Map> stats = null; + + @Override + public boolean isOk() { + return ok; + } + + @GET + @Path("/error") + public String error() { + ok = false; + return "error set"; + } + + @GET + @Path("/stats") + public String stats() { + stats = MapXs.of("hello", MapXs.of("world", "boo!")); + return "stats set"; + } + + @Override + public Map> get() { + return stats; + } + +} diff --git a/micro-application-register/src/test/java/app/registry/config/com/oath/micro/server/RegistryAppRunner.java b/micro-application-register/src/test/java/app/registry/config/com/oath/micro/server/RegistryAppRunner.java new file mode 100644 index 000000000..00a097912 --- /dev/null +++ b/micro-application-register/src/test/java/app/registry/config/com/oath/micro/server/RegistryAppRunner.java @@ -0,0 +1,98 @@ +package app.registry.config.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertThat; + +import java.util.Date; +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.application.registry.RegisterEntry; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { + "external.port.registry-app", + "9090", + "service.registry.url", + "http://localhost:8080/registry-app", + "host.address", + "test-host" +}) +public class RegistryAppRunner { + + private final AsyncRestClient restAsync = new AsyncRestClient( + 100, 2000); + RestAgent rest = new RestAgent(); + MicroserverApp server; + + @Before + public void startServer() { + server = new MicroserverApp(() -> "registry-app"); + server.start(); + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + Thread.sleep(1000); + + assertThat(rest.post("http://localhost:8080/registry-app/service-registry/schedule"), + is("{\"status\":\"success\"}")); + Thread.sleep(1000); + assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"), + containsString("[{\"port\":8080,")); + assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"), + containsString("externalPort\":9090")); + + sendPing(new RegisterEntry( + 8081, "use-ip", "hello", "world", new Date(), "my-target", 8082)); + Thread.sleep(1000); + System.out + .println(rest.getJson("http://localhost:8080/registry-app/service-registry/list")); + assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"), + containsString("{\"port\":8081,")); + assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"), + containsString("\"hostname\":\"test-host\"")); + assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"), + containsString("\"health\":\"OK\"")); + assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"), + not(containsString("\"target\":\"configured-target\""))); + + assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"), + not(containsString("\"stats\""))); + rest.getJson("http://localhost:8080/health/error"); + rest.getJson("http://localhost:8080/health/stats"); + rest.post("http://localhost:8080/registry-app/service-registry/schedule"); + Thread.sleep(1000); + assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"), + containsString("\"health\":\"ERROR\"")); + assertThat(rest.getJson("http://localhost:8080/registry-app/service-registry/list"), + containsString("\"stats\"")); + + } + + private void sendPing(RegisterEntry entry) { + try { + restAsync.post("http://localhost:8080/registry-app/service-registry/register", + JacksonUtil.serializeToJson(entry)) + .join(); + } catch (Exception e) { + + } + } + +} diff --git a/micro-application-register/src/test/java/com/aol/micro/server/application/registry/ApplicationRegisterTest.java b/micro-application-register/src/test/java/com/aol/micro/server/application/registry/ApplicationRegisterTest.java deleted file mode 100644 index 58c5c5958..000000000 --- a/micro-application-register/src/test/java/com/aol/micro/server/application/registry/ApplicationRegisterTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.aol.micro.server.application.registry; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.servers.model.ServerData; - - -public class ApplicationRegisterTest { - - private ApplicationRegisterImpl applicationRegister; - private int count; - - @Before - public void setUp() { - count = 0; - } - - @Test - public void testConstructor() { - applicationRegister = new ApplicationRegisterImpl(); - - assertThat(applicationRegister.getApplication(), is(nullValue())); - } - - @Test - public void testRegister() { - ServerData data1 = new ServerData(8080, new ArrayList<>(), null, "url", () -> ""); - ServerData data2 = new ServerData(8080, new ArrayList<>(), null, "url", () -> ""); - ServerData data3 = new ServerData(8080, new ArrayList<>(), null, "url", () -> ""); - - List datas = Arrays.asList(data1, data2, data3); - - applicationRegister = new ApplicationRegisterImpl(); - - ServerData[] dataArray = new ServerData[datas.size()]; - applicationRegister.register(datas.toArray(dataArray)); - applicationRegister.getApplication().forEach(it -> count++); - assertThat(count, is(3)); - } -} diff --git a/micro-application-register/src/test/java/com/aol/micro/server/application/registry/CleanerTest.java b/micro-application-register/src/test/java/com/aol/micro/server/application/registry/CleanerTest.java deleted file mode 100644 index 4866e44ac..000000000 --- a/micro-application-register/src/test/java/com/aol/micro/server/application/registry/CleanerTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.aol.micro.server.application.registry; - -import static org.junit.Assert.assertThat; - -import java.io.File; -import java.util.Date; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; -import static org.hamcrest.CoreMatchers.*; - - -public class CleanerTest { - - Cleaner cleaner; - Register writer; - RegisterEntry entry; - Finder finder; - RegisterConfig registerConfig; - @Before - public void setUp() throws Exception { - try{ - new File(System.getProperty("java.io.tmpdir"),"lana-service-reg-cleaner").delete(); - }catch(Exception e){ - } - - new File(System.getProperty("java.io.tmpdir"),"lana-service-reg-cleaner").mkdirs(); - registerConfig = new RegisterConfig(new File(System.getProperty("java.io.tmpdir"),"lana-service-reg-cleaner").getAbsolutePath()); - writer = new Register(registerConfig); - finder = new Finder(registerConfig); - cleaner = new Cleaner(registerConfig,1); - - entry= new RegisterEntry(8080,"host","module","context",new Date(),null); - - } - - @Test - public void testClean() { - writer.register(entry.withTime(new Date(System.currentTimeMillis()-2000))); - - cleaner.clean(); - List list = finder.find(); - assertThat( list.size(),equalTo(0)); - } -} diff --git a/micro-application-register/src/test/java/com/aol/micro/server/application/registry/FinderTest.java b/micro-application-register/src/test/java/com/aol/micro/server/application/registry/FinderTest.java deleted file mode 100644 index d894a54b3..000000000 --- a/micro-application-register/src/test/java/com/aol/micro/server/application/registry/FinderTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.aol.micro.server.application.registry; - -import static org.junit.Assert.*; - -import java.io.File; -import java.util.Date; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import static org.hamcrest.Matchers.*; - -public class FinderTest { - - Register writer; - RegisterEntry entry; - Finder finder; - RegisterConfig registerConfig; - @Before - public void setUp() throws Exception { - try{ - new File(System.getProperty("java.io.tmpdir"),"service-reg-finder").delete(); - }catch(Exception e){ - } - - new File(System.getProperty("java.io.tmpdir"),"service-reg-finder").mkdirs(); - registerConfig = new RegisterConfig(new File(System.getProperty("java.io.tmpdir"),"service-reg-finder") - .getAbsolutePath()); - writer = new Register(registerConfig); - finder = new Finder(registerConfig); - - entry= new RegisterEntry(8080,"host","module","context",new Date(),null); - } - - @Test - public void testFind() { - writer.register(entry); - List list = finder.find(); - assertThat(list.size(),greaterThan(0)); - assertThat(list.get(0).getContext(),equalTo("context")); - } -} diff --git a/micro-application-register/src/test/java/com/aol/micro/server/application/registry/RegisterEntryTest.java b/micro-application-register/src/test/java/com/aol/micro/server/application/registry/RegisterEntryTest.java deleted file mode 100644 index 5a0178208..000000000 --- a/micro-application-register/src/test/java/com/aol/micro/server/application/registry/RegisterEntryTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.aol.micro.server.application.registry; - -import static org.junit.Assert.*; -import java.util.Date; - -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - - - -public class RegisterEntryTest { - - RegisterEntry entry; - - @Before - public void setUp() throws Exception { - entry = new RegisterEntry(8080, "hostname", "name", "context", new Date(),null); - } - - @Test - public void test() { - - assertTrue( JacksonUtil.serializeToJson(entry).contains("\"context\":\"context")); - } -} diff --git a/micro-application-register/src/test/java/com/aol/micro/server/application/registry/WriterTest.java b/micro-application-register/src/test/java/com/aol/micro/server/application/registry/WriterTest.java deleted file mode 100644 index 0dc201182..000000000 --- a/micro-application-register/src/test/java/com/aol/micro/server/application/registry/WriterTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aol.micro.server.application.registry; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; - -import java.io.File; -import java.util.Date; - -import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Test; - -public class WriterTest { - - Register writer; - RegisterEntry entry; - @Before - public void setUp() throws Exception { - try{ - FileUtils.deleteDirectory(new File(System.getProperty("java.io.tmpdir"),"service-reg-writer")); - }catch(Exception e){ - } - - new File(System.getProperty("java.io.tmpdir"),"service-reg-writer").mkdirs(); - writer = new Register(new RegisterConfig(new File(System.getProperty("java.io.tmpdir"),"service-reg-writer").getAbsolutePath())); - - entry= new RegisterEntry(8080,"host","module","context",new Date(),null); - } - - @Test - public void testRegister() { - writer.register(entry); - File dir = new File(new File(System.getProperty("java.io.tmpdir"),"service-reg-writer"), "module"); - assertThat( dir.listFiles().length,equalTo(1)); - } -} diff --git a/micro-application-register/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-application-register/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index 987e06335..000000000 --- a/micro-application-register/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - public String post(String url) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(null,String.class); - - } - - -} diff --git a/micro-application-register/src/test/java/com/oath/micro/server/application/registry/ApplicationRegisterTest.java b/micro-application-register/src/test/java/com/oath/micro/server/application/registry/ApplicationRegisterTest.java new file mode 100644 index 000000000..ebb002139 --- /dev/null +++ b/micro-application-register/src/test/java/com/oath/micro/server/application/registry/ApplicationRegisterTest.java @@ -0,0 +1,48 @@ +package com.oath.micro.server.application.registry; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.Assert.assertThat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.servers.model.ServerData; + + +public class ApplicationRegisterTest { + + private ApplicationRegisterImpl applicationRegister; + private int count; + + @Before + public void setUp() { + count = 0; + } + + @Test + public void testConstructor() { + applicationRegister = new ApplicationRegisterImpl(); + assertThat(applicationRegister.getApplication(), is(nullValue())); + } + + @Test + public void testRegister() { + ServerData data1 = new ServerData(8080, new ArrayList<>(), null, "url", () -> ""); + ServerData data2 = new ServerData(8080, new ArrayList<>(), null, "url", () -> ""); + ServerData data3 = new ServerData(8080, new ArrayList<>(), null, "url", () -> ""); + + List datas = Arrays.asList(data1, data2, data3); + + applicationRegister = new ApplicationRegisterImpl(); + + ServerData[] dataArray = new ServerData[datas.size()]; + applicationRegister.register(datas.toArray(dataArray)); + applicationRegister.getApplication().forEach(it -> count++); + assertThat(count, is(3)); + } +} diff --git a/micro-application-register/src/test/java/com/oath/micro/server/application/registry/CleanerTest.java b/micro-application-register/src/test/java/com/oath/micro/server/application/registry/CleanerTest.java new file mode 100644 index 000000000..17106a0aa --- /dev/null +++ b/micro-application-register/src/test/java/com/oath/micro/server/application/registry/CleanerTest.java @@ -0,0 +1,51 @@ +package com.oath.micro.server.application.registry; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.io.File; +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.junit.Before; +import org.junit.Test; + +public class CleanerTest { + + Cleaner cleaner; + Register writer; + RegisterEntry entry; + Finder finder; + RegisterConfig registerConfig; + + @Before + public void setUp() throws Exception { + try { + new File( + System.getProperty("java.io.tmpdir"), "lana-service-reg-cleaner").delete(); + } catch (Exception e) { + } + + new File( + System.getProperty("java.io.tmpdir"), "lana-service-reg-cleaner").mkdirs(); + registerConfig = new RegisterConfig( + new File( + System.getProperty("java.io.tmpdir"), + "lana-service-reg-cleaner").getAbsolutePath()); + writer = new Register(registerConfig); + finder = new Finder(registerConfig); + cleaner = new Cleaner(registerConfig, 1); + + entry = new RegisterEntry( + 8080, "host", "module", "context", new Date(), null, 8080); + } + + @Test + public void testClean() { + writer.register(entry.withTime(new Date(System.currentTimeMillis() - 2000))); + cleaner.clean(); + List list = finder.find(Optional.empty()); + assertThat(list.size(), equalTo(0)); + } +} diff --git a/micro-application-register/src/test/java/com/oath/micro/server/application/registry/FinderTest.java b/micro-application-register/src/test/java/com/oath/micro/server/application/registry/FinderTest.java new file mode 100644 index 000000000..bc3f3fbdc --- /dev/null +++ b/micro-application-register/src/test/java/com/oath/micro/server/application/registry/FinderTest.java @@ -0,0 +1,47 @@ +package com.oath.micro.server.application.registry; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThan; +import static org.junit.Assert.assertThat; + +import java.io.File; +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.junit.Before; +import org.junit.Test; + +public class FinderTest { + + Register writer; + RegisterEntry entry; + Finder finder; + RegisterConfig registerConfig; + + @Before + public void setUp() throws Exception { + try { + new File( + System.getProperty("java.io.tmpdir"), "service-reg-finder").delete(); + } catch (Exception e) { + } + + new File(System.getProperty("java.io.tmpdir"), "service-reg-finder").mkdirs(); + registerConfig = new RegisterConfig( + new File(System.getProperty("java.io.tmpdir"), + "service-reg-finder").getAbsolutePath()); + writer = new Register(registerConfig); + finder = new Finder(registerConfig); + entry = new RegisterEntry( + 8080, "host", "module", "context", new Date(), null, 8080); + } + + @Test + public void testFind() { + writer.register(entry); + List list = finder.find(Optional.empty()); + assertThat(list.size(), greaterThan(0)); + assertThat(list.get(0).getContext(), equalTo("context")); + } +} diff --git a/micro-application-register/src/test/java/com/oath/micro/server/application/registry/RegisterEntryTest.java b/micro-application-register/src/test/java/com/oath/micro/server/application/registry/RegisterEntryTest.java new file mode 100644 index 000000000..89d8b9e9f --- /dev/null +++ b/micro-application-register/src/test/java/com/oath/micro/server/application/registry/RegisterEntryTest.java @@ -0,0 +1,73 @@ +package com.oath.micro.server.application.registry; + +import static junit.framework.TestCase.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Date; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RegisterEntryTest { + + RegisterEntry entry; + + @Before + public void setUp() throws Exception { + entry = RegisterEntry.builder() + .port(8080) + .hostname("host") + .module("module") + .context("context") + .time(new Date()) + .uuid("1") + .target("target") + .externalPort(9090) + .build(); + Map manifest = entry.getManifest(); + manifest.put("Implementation-revision", "a2edfe4bc"); + manifest.put("Implementation-Version", "version"); + manifest.put("Implementation-Timestamp", "2017_1201"); + } + + @Test + public void test() { + assertTrue(JacksonUtil.serializeToJson(entry).contains("\"context\":\"context")); + } + + @Test + public void matches() throws Exception { + RegisterEntry re = new RegisterEntry(); + re.getManifest().clear(); + assertFalse(entry.matches(re)); + + re = RegisterEntry.builder().port(8080).externalPort(-1).build(); + re.getManifest().clear(); + assertTrue(entry.matches(re)); + + re = RegisterEntry.builder().port(8080).externalPort(9090).build(); + re.getManifest().clear(); + assertTrue(entry.matches(re)); + + re = RegisterEntry.builder().port(8080).hostname("host").externalPort(9090).build(); + re.getManifest().clear(); + assertTrue(entry.matches(re)); + + re = RegisterEntry.builder().port(8080).hostname("host1").externalPort(9090).build(); + re.getManifest().clear(); + assertFalse(entry.matches(re)); + + re = RegisterEntry.builder().port(8080).hostname("host").externalPort(9090).build(); + re.getManifest().clear(); + re.getManifest().put("Implementation-revision", "a2edfe4bc"); + assertTrue(entry.matches(re)); + + re = RegisterEntry.builder().port(8080).hostname("host").externalPort(9090).build(); + re.getManifest().clear(); + re.getManifest().put("Implementation-Version", "version1"); + assertFalse(entry.matches(re)); + } +} diff --git a/micro-application-register/src/test/java/com/oath/micro/server/application/registry/UriInfoParserTest.java b/micro-application-register/src/test/java/com/oath/micro/server/application/registry/UriInfoParserTest.java new file mode 100644 index 000000000..639533088 --- /dev/null +++ b/micro-application-register/src/test/java/com/oath/micro/server/application/registry/UriInfoParserTest.java @@ -0,0 +1,58 @@ +package com.oath.micro.server.application.registry; + +import org.junit.Test; +import org.mockito.Mockito; + +import javax.ws.rs.core.*; + +import java.util.Arrays; +import java.util.Optional; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; +import static org.mockito.Mockito.when; + +public class UriInfoParserTest { + + @Test + public void toRegisterEntryFromQueryParameters() throws Exception { + UriInfo uriInfo = Mockito.mock(UriInfo.class); + MultivaluedMap data = new MultivaluedHashMap<>(); + data.put("port", Arrays.asList("8080")); + data.put("externalPort", Arrays.asList("9090")); + data.put("hostname", Arrays.asList("host1")); + data.put("module", Arrays.asList("module1")); + data.put("context", Arrays.asList("context1")); + data.put("target", Arrays.asList("target1")); + data.put("health", Arrays.asList("OK")); + data.put("manifest.Implementation-revision", Arrays.asList("revision1")); + data.put("manifest.Implementation-Timestamp", Arrays.asList("2017_001")); + data.put("manifest.Implementation-Version", Arrays.asList("v1")); + + when(uriInfo.getQueryParameters()).thenReturn(data); + + Optional reOptional = UriInfoParser.toRegisterEntry(uriInfo); + assertTrue(reOptional.isPresent()); + + RegisterEntry re = reOptional.get(); + assertThat(re.getPort(), is(8080)); + assertThat(re.getExternalPort(), is(9090)); + assertThat(re.getHostname(), is("host1")); + assertThat(re.getModule(), is("module1")); + assertThat(re.getContext(), is("context1")); + assertThat(re.getTarget(), is("target1")); + assertThat(re.getHealth(), is(Health.OK)); + assertThat(re.getManifest().get("Implementation-revision"), is("revision1")); + assertThat(re.getManifest().get("Implementation-Timestamp"), is("2017_001")); + assertThat(re.getManifest().get("Implementation-Version"), is("v1")); + } + + @Test + public void toRegisterEntryFromEmptyQueryParameter() throws Exception { + UriInfo uriInfo = Mockito.mock(UriInfo.class); + when(uriInfo.getQueryParameters()).thenReturn(new MultivaluedHashMap<>()); + + Optional re = UriInfoParser.toRegisterEntry(uriInfo); + assertFalse(re.isPresent()); + } +} diff --git a/micro-application-register/src/test/java/com/oath/micro/server/application/registry/WriterTest.java b/micro-application-register/src/test/java/com/oath/micro/server/application/registry/WriterTest.java new file mode 100644 index 000000000..84c65edec --- /dev/null +++ b/micro-application-register/src/test/java/com/oath/micro/server/application/registry/WriterTest.java @@ -0,0 +1,46 @@ +package com.oath.micro.server.application.registry; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.io.File; +import java.util.Date; + +import org.apache.commons.io.FileUtils; +import org.junit.Before; +import org.junit.Test; + +public class WriterTest { + + Register writer; + RegisterEntry entry; + + @Before + public void setUp() throws Exception { + try { + FileUtils.deleteDirectory(new File( + System.getProperty("java.io.tmpdir"), "service-reg-writer")); + } catch (Exception e) { + } + + new File(System.getProperty("java.io.tmpdir"), "service-reg-writer").mkdirs(); + writer = new Register( + new RegisterConfig( + new File( + System.getProperty("java.io.tmpdir"), + "service-reg-writer").getAbsolutePath())); + + entry = new RegisterEntry( + 8080, "host", "module", "context", new Date(), null, 8080); + } + + @Test + public void testRegister() { + writer.register(entry); + File dir = new File( + new File( + System.getProperty("java.io.tmpdir"), "service-reg-writer"), + "module"); + assertThat(dir.listFiles().length, equalTo(1)); + } +} diff --git a/micro-application-register/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-application-register/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b6e29190b --- /dev/null +++ b/micro-application-register/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,65 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload, Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request + .post(Entity.entity(JacksonUtil.serializeToJson(payload), MediaType.APPLICATION_JSON), + type); + } + + public String post(String url) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(null, String.class); + } + + +} diff --git a/micro-application-register/src/test/resources/META-INF/MANIFEST.MF b/micro-application-register/src/test/resources/META-INF/MANIFEST.MF new file mode 100644 index 000000000..11aa42ba5 --- /dev/null +++ b/micro-application-register/src/test/resources/META-INF/MANIFEST.MF @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Implementation-Vendor: TEST +Implementation-Title: TITLE +Implementation-Version: 10.2 + diff --git a/micro-async-data-loader/README.md b/micro-async-data-loader/README.md new file mode 100644 index 000000000..0e8a034f5 --- /dev/null +++ b/micro-async-data-loader/README.md @@ -0,0 +1,130 @@ +# Async Data Writer Plugin + +[micro-async-data-loader example apps](https://github.com/aol/micro-server/tree/master/micro-async-data-loader/src/test/java/app) + +This plugin supports asyncrhonously reading data from a store such as S3 or Couchbase (via micro-s3 or micro-couchbase plugins), using the Manifest Comparator pattern (see micro-manifest-comparator). This is a technique that allows a Microservice to generate data for another Microservice to use. The writer stores the data and a version in the datastore. The reader checks for version changes and asynchronously loads the data on change. With micro-async-data-writer and micro-async-data-loader in conjunction with either micro-s3 or micro-couchbase Microserver provides the infrastructure and client code need only configure data access and pass the data to the AsyncDataWriter bean. By adding micro-async-data-loader to the classpath of your consuming service (and configuring your datasource and manifest comparator key name), changes will be automatically detected and loaded asynchronously into that service. + + +# Async Data Loader Plugin Features + +1. Scheduled job to load data into your ManifestComparator instance +2. Load data immediately on startup +3. Integrates with micro-events to capture load events +4. Supports automatic loading from multiple configured ManifestComparator beans + + +## Configuring and using the AsyncDataLoader + +This plugin must be used in conjunction with an implementation of the interfaces in micro-manifest-comparator (either micro-s3 or micro-couchbase should be on the classpath). The first steps to using the AsyncDataLoader should be to configure access to your data store as per the appropriate plugin (configure access keys for S3, servers / user / password for Couchbase). + +To configure a manifest comparator for Couchbase please set this property + +couchbase.manifest.comparison.key= + +To configure a manifest comparator for S3 please set this property + +s3.manifest.comparator.key= + +### Additional properties are + +async.data.schedular.cron.loader=0 * * * * * + +How often loader should check for changes in data (uses a quartz expression and attempts a load every minute by default). + +By default data will be loaded from all configured ManifestComparators using the default cron. + +async.data.schedular.threads=no. of threads for asynchronous loading + +The default value is 5. + +async.data.writer.multi=true / false + +By default writing to multiple services is disabled, if more than one ManifestComparator bean is found on the classpath only the first is configured in an AsyncDataWriter. If async.data.writer.multi is set to true all ManifestComparators will be wrapped by a single MultiDataWriter bean. Calling saveAndIncrement with new data on this bean will write that data to all sources. + +### Configuring multiple ManifestComparators + +micro-s3 or micro-couchbase will each configure a default ManifestComparator bean. You can create new ManifestComparator instances that will store/read data under a different key within the same S3 or couchbase bucket via ManifestComparator#newKey. + +e.g. + + ```java + + @Configuration + public MySpringConfig{ + + @Autowired + private ManifestComparator mainComparator; + + @Bean + public ManifestComparator comparator2(){ + return mainComparator.withKey("key2"); + } + } + ``` + +### Configuring loading from Multiple ManifestComparators on separate crons + +If you have configured multiple ManifestComparator and want to check for changes to the data on differing schedules, simply configure a DataLoader that contains the ManifestComparator e.g. + +```java + + @Configuration + public MySpringConfig{ + + @Value("${my.data.schedular.cron.loader2:0 * * * * *}") + private String dataLoader2Cron; + @Autowired + private ManifestComparator mainComparator; + + @Bean + public ManifestComparator comparator2(){ + return mainComparator.withKey("key2"); + } + @Bean + public DataLoader dataLoader2(){ + return new DataLoader(comparator2(),dataLoader2Cron); + } + } +``` + + +## Accessing data which has been loaded asynchronously + +Simply inject your ManifestComparator Bean into the service that needs the data and call getData! + +```java + + @Service + public class MyService{ + + private final ManifestComparator mc; + + public MyService(ManifestComparator mc){ + this.mc = mc; + } + + public ProcessedData processData(Processor processor){ + //data is loaded asynchronously into the ManifestComparator by micro-async-loader + return processor.process(mc.getData()); + } + + } + +``` + +## Getting The Microserver Async Data Loader Plugin + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-async-data-loader/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-async-data-loader) + +### Maven +```xml + + com.oath.microservices + micro-async-data-loader + x.yz + +``` +### Gradle +```groovy + compile 'com.oath.microservices:micro-async-data-loader:x.yz' + ``` diff --git a/micro-async-data-loader/build.gradle b/micro-async-data-loader/build.gradle new file mode 100644 index 000000000..08a5d844c --- /dev/null +++ b/micro-async-data-loader/build.gradle @@ -0,0 +1,73 @@ +description = 'micro-async-data-loader' + +repositories { + maven { url "https://jitpack.io" } +} + +dependencies { + compile 'com.oath.cyclops:cyclops:' + cyclopsVersion + compile project(':micro-events') + compile project(':micro-manifest-comparator') + testCompile project(':micro-grizzly-with-jersey') + testCompile project(':micro-couchbase') +} + +modifyPom { + + project { + name 'Microserver async data loading' + description 'Plugin for loading data asyncrhonously via a micro-manifest-comparator implementation' + url 'https://github.com/aol/micro-server' + inceptionYear '2016' + + groupId 'com.oath.microservices' + artifactId 'micro-async-data-loader' + version "$version" + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } + + } +} + +extraArchive { + sources = true + tests = true + javadoc = true +} + +nexus { + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' +} + diff --git a/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/ConditionallyLoad.java b/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/ConditionallyLoad.java new file mode 100644 index 000000000..780eec150 --- /dev/null +++ b/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/ConditionallyLoad.java @@ -0,0 +1,6 @@ +package com.oath.micro.server.async.data.loader; + +public interface ConditionallyLoad { + + public boolean shouldLoad(); +} diff --git a/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/ConfigureSchedulingAsyncDataLoader.java b/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/ConfigureSchedulingAsyncDataLoader.java new file mode 100644 index 000000000..f1526b32e --- /dev/null +++ b/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/ConfigureSchedulingAsyncDataLoader.java @@ -0,0 +1,63 @@ +package com.oath.micro.server.async.data.loader; + +import java.util.List; +import java.util.concurrent.Executors; +import java.util.function.BinaryOperator; + +import cyclops.reactive.collections.mutable.ListX; +import cyclops.reactive.collections.mutable.SetX; +import cyclops.reactive.ReactiveSeq; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.manifest.ManifestComparator; +import com.google.common.eventbus.EventBus; + +@Configuration +public class ConfigureSchedulingAsyncDataLoader { + + @Value("${async.data.schedular.cron.loader:0 * * * * ?}") + private String defaultCron; + + @Value("${async.data.schedular.threads:5}") + private int schedularThreads; + + @Autowired(required = false) + private List dataLoaders = ListX.empty(); + + @Autowired + private EventBus bus; + + @Autowired(required = false) + private List defaultComparators = ListX.empty(); + @Autowired(required = false) + private List predicates = ListX.empty(); + + private ListX dataLoaders() { + SetX comparatorSet = SetX.fromIterable(dataLoaders) + .map(dl -> dl.comparator); + return ListX.fromIterable(defaultComparators) + .filter(i -> !comparatorSet.contains(i)) + .map(mc -> new DataLoader(mc, defaultCron)) + .appendAll(dataLoaders) + .toListX(); + } + + @Bean + public LoaderSchedular asyncDataLoader() { + ConditionallyLoad cc = () -> true; + BinaryOperator accumulator = (cc1, cc2) -> () -> cc1.shouldLoad() && cc2 + .shouldLoad(); + + LoaderSchedular schedular = new LoaderSchedular( + dataLoaders(), + Executors.newScheduledThreadPool(schedularThreads), + bus, + predicates.stream().reduce(cc, accumulator)); + schedular.schedule(); + return schedular; + } + +} diff --git a/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/DataLoader.java b/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/DataLoader.java new file mode 100644 index 000000000..c3ad94bd2 --- /dev/null +++ b/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/DataLoader.java @@ -0,0 +1,48 @@ +package com.oath.micro.server.async.data.loader; + +import com.oath.micro.server.events.ScheduledJob; +import com.oath.micro.server.events.SystemData; +import com.oath.micro.server.manifest.ManifestComparator; +import com.oath.micro.server.utility.HashMapBuilder; +import cyclops.reactive.collections.mutable.MapX; +import java.util.Random; +import java.util.function.Supplier; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public class DataLoader implements ScheduledJob { + + public static final String MANIFEST_COMPARATOR_DATA_LOADER_KEY = "Manifest Comparator Data Loader"; + final ManifestComparator comparator; + @Getter + private final String cron; + private final Random r = new Random(); + + @Override + public SystemData scheduleAndLog() { + + String correlationId = "" + System.currentTimeMillis() + ":" + r.nextLong(); + Supplier> dataMap = () -> MapX + .fromMap(HashMapBuilder.map(MANIFEST_COMPARATOR_DATA_LOADER_KEY, + comparator.toString()).build()); + try { + boolean changed = comparator.load(); + + return SystemData.builder() + .correlationId(correlationId) + .dataMap(dataMap.get()) + .errors(0) + .processed(changed ? 1 : 0) + .build(); + } catch (Exception e) { + return SystemData.builder() + .correlationId(correlationId) + .dataMap(dataMap.get().plus("Error", e.getMessage())) + .errors(1) + .processed(0) + .build(); + } + } + +} diff --git a/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/LoaderSchedular.java b/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/LoaderSchedular.java new file mode 100644 index 000000000..22a44acc5 --- /dev/null +++ b/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/LoaderSchedular.java @@ -0,0 +1,39 @@ +package com.oath.micro.server.async.data.loader; + +import java.util.concurrent.ScheduledExecutorService; + + +import com.oath.micro.server.events.SystemData; +import com.google.common.eventbus.EventBus; + +import cyclops.reactive.collections.mutable.ListX; +import cyclops.reactive.ReactiveSeq; +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class LoaderSchedular { + + private ListX loader; + private final ScheduledExecutorService executor; + private final EventBus bus; + private final ConditionallyLoad condition; + + public void schedule() { + + loader.forEach(dl -> { + + // run on startup + create(dl).limit(1).foldFuture(executor, s -> s.forEach(Long.MAX_VALUE, l -> {})); + + // schedule + create(dl).schedule(dl.getCron(), executor); + }); + } + + private ReactiveSeq> create(DataLoader dl) { + return ReactiveSeq.generate(() -> 1) + .filter(in -> condition.shouldLoad()) + .map(in -> dl.scheduleAndLog()) + .peek(sd -> bus.post(sd)); + } +} diff --git a/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/plugin/AsyncDataLoaderPlugin.java b/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/plugin/AsyncDataLoaderPlugin.java new file mode 100644 index 000000000..a50549832 --- /dev/null +++ b/micro-async-data-loader/src/main/java/com/oath/micro/server/async/data/loader/plugin/AsyncDataLoaderPlugin.java @@ -0,0 +1,17 @@ +package com.oath.micro.server.async.data.loader.plugin; + +import java.util.Set; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.async.data.loader.ConfigureSchedulingAsyncDataLoader; +import cyclops.reactive.collections.mutable.SetX; + +public class AsyncDataLoaderPlugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of(ConfigureSchedulingAsyncDataLoader.class); + } + +} diff --git a/micro-async-data-loader/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-async-data-loader/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..eeb768665 --- /dev/null +++ b/micro-async-data-loader/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.async.data.loader.plugin.AsyncDataLoaderPlugin \ No newline at end of file diff --git a/micro-async-data-loader/src/test/java/app/loader/configured/com/oath/micro/server/ManifestComparatorResource.java b/micro-async-data-loader/src/test/java/app/loader/configured/com/oath/micro/server/ManifestComparatorResource.java new file mode 100644 index 000000000..139bdafb9 --- /dev/null +++ b/micro-async-data-loader/src/test/java/app/loader/configured/com/oath/micro/server/ManifestComparatorResource.java @@ -0,0 +1,42 @@ +package app.loader.configured.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.manifest.ManifestComparator; + +@Path("/comparator") +@Rest +public class ManifestComparatorResource { + + private final ManifestComparator comparator; + private volatile int count = 1; + + @Autowired + public ManifestComparatorResource(ManifestComparator comparator) { + this.comparator = comparator; + } + + @GET + @Path("/increment") + public String bucket() { + comparator.saveAndIncrement("hello" + (count++)); + return "incremented"; + } + + @GET + @Path("/get") + public String get() { + return comparator.getData(); + } + + @GET + @Path("/check") + public String check() { + return "" + !comparator.isOutOfDate(); + + } +} diff --git a/micro-async-data-loader/src/test/java/app/loader/configured/com/oath/micro/server/ManifestComparatorRunnerTest.java b/micro-async-data-loader/src/test/java/app/loader/configured/com/oath/micro/server/ManifestComparatorRunnerTest.java new file mode 100644 index 000000000..09689a87a --- /dev/null +++ b/micro-async-data-loader/src/test/java/app/loader/configured/com/oath/micro/server/ManifestComparatorRunnerTest.java @@ -0,0 +1,61 @@ +package app.loader.configured.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.couchbase.mock.CouchbaseMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { + "couchbaseServers", "http://localhost:8091/pools", + "couchbasePassword", "", + "couchbaseBucket", "beer-sample", + "couchbase.manifest.comparison.key", "test-key", + "async.data.schedular.cron.loader", "* * * * * ?" +}) +public class ManifestComparatorRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + try { + // couchbase already running? + rest.get("http://localhost:8091/pools"); + } catch (Exception e) { + // start mock couchbase + CouchbaseMock.main(new String[]{"-S"}); + } + server = new MicroserverApp(() -> "simple-app"); + server.start(); + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + rest.get("http://localhost:8080/simple-app/comparator/increment"); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/check"), equalTo("true")); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"), equalTo("hello1")); + rest.get("http://localhost:8080/simple-app/comparator/increment"); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"), equalTo("hello2")); + rest.get("http://localhost:8080/simple-app/comparator2/increment"); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/check"), equalTo("false")); + Thread.sleep(2000); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"), equalTo("hellob")); + } + +} diff --git a/micro-async-data-loader/src/test/java/app/loader/configured/com/oath/micro/server/SecondComparatorResource.java b/micro-async-data-loader/src/test/java/app/loader/configured/com/oath/micro/server/SecondComparatorResource.java new file mode 100644 index 000000000..71204c7be --- /dev/null +++ b/micro-async-data-loader/src/test/java/app/loader/configured/com/oath/micro/server/SecondComparatorResource.java @@ -0,0 +1,44 @@ +package app.loader.configured.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.manifest.ManifestComparator; + +@Path("/comparator2") +@Rest +public class SecondComparatorResource { + + private final ManifestComparator comparator; + + @Autowired + public SecondComparatorResource(ManifestComparator comparator) { + this.comparator = comparator.withKey("test-key"); + } + + @GET + @Path("/increment") + public String bucket() { + comparator.saveAndIncrement("hellob"); + return "increment"; + } + + @GET + @Path("/get") + public String get() { + comparator.load(); + return comparator.getData() + .toString(); + + } + + @GET + @Path("/check") + public String check() { + return "" + !comparator.isOutOfDate(); + + } +} diff --git a/micro-async-data-loader/src/test/java/app/loader/scheduled/com/oath/micro/server/CouchbaseResource.java b/micro-async-data-loader/src/test/java/app/loader/scheduled/com/oath/micro/server/CouchbaseResource.java new file mode 100644 index 000000000..f05069660 --- /dev/null +++ b/micro-async-data-loader/src/test/java/app/loader/scheduled/com/oath/micro/server/CouchbaseResource.java @@ -0,0 +1,61 @@ +package app.loader.scheduled.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import cyclops.reactive.collections.immutable.LinkedListX; +import cyclops.control.Maybe; +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.distributed.DistributedMap; +import com.oath.micro.server.events.SystemData; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +@Path("/couchbase") +@Rest +public class CouchbaseResource { + + private final DistributedMap client; + private volatile LinkedListX dataLoads = LinkedListX.empty(); + + @Autowired + public CouchbaseResource(DistributedMap client, EventBus bus) { + this.client = client; + bus.register(this); + } + + @Subscribe + public synchronized void events(SystemData event) { + dataLoads = dataLoads.plus(event); + } + + @GET + @Path("/loading-events") + @Produces("application/json") + public synchronized LinkedListX loadingEvents() { + return dataLoads; + } + + @GET + @Path("/maybe") + @Produces("application/json") + public Maybe maybe() { + return Maybe.just("hello-world"); + } + + @GET + @Path("/get") + public String bucket() { + return client.get("hello").toString(); + } + + @GET + @Path("/put") + public String put() { + client.put("hello", "world"); + return "added"; + } +} diff --git a/micro-async-data-loader/src/test/java/app/loader/scheduled/com/oath/micro/server/CouchbaseRunnerTest.java b/micro-async-data-loader/src/test/java/app/loader/scheduled/com/oath/micro/server/CouchbaseRunnerTest.java new file mode 100644 index 000000000..5a0cd097f --- /dev/null +++ b/micro-async-data-loader/src/test/java/app/loader/scheduled/com/oath/micro/server/CouchbaseRunnerTest.java @@ -0,0 +1,64 @@ +package app.loader.scheduled.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +import org.couchbase.mock.CouchbaseMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { + "couchbaseServers", "http://localhost:8091/pools", + "couchbasePassword", "", + "couchbaseBucket", "beer-sample", + "async.data.schedular.cron.loader", "* * * * * ?", + "async.data.schedular.cron.cleaner", "* * * * * ?" +}) +public class CouchbaseRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + try { + // couchbase already running? + rest.get("http://localhost:8091/pools"); + } catch (Exception e) { + // start mock couchbase + CouchbaseMock.main(new String[]{"-S"}); + } + server = new MicroserverApp(ConfigurableModule.builder().context("simple-app").build()); + server.start(); + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + rest.get("http://localhost:8080/simple-app/couchbase/put"); + assertThat(rest.get("http://localhost:8080/simple-app/couchbase/get"), + containsString("world")); + + Thread.sleep(2000); + String json = rest.getJson("http://localhost:8080/simple-app/couchbase/loading-events"); + List list = JacksonUtil.convertFromJson(json, List.class); + System.out.println(list); + assertTrue(list.size() > 0); + } +} diff --git a/micro-async-data-loader/src/test/java/app/loader/scheduled/off/com/oath/micro/server/CouchbaseResource.java b/micro-async-data-loader/src/test/java/app/loader/scheduled/off/com/oath/micro/server/CouchbaseResource.java new file mode 100644 index 000000000..873757e91 --- /dev/null +++ b/micro-async-data-loader/src/test/java/app/loader/scheduled/off/com/oath/micro/server/CouchbaseResource.java @@ -0,0 +1,61 @@ +package app.loader.scheduled.off.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import cyclops.reactive.collections.immutable.LinkedListX; +import cyclops.control.Maybe; +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.distributed.DistributedMap; +import com.oath.micro.server.events.SystemData; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +@Path("/couchbase") +@Rest +public class CouchbaseResource { + + private final DistributedMap client; + private volatile LinkedListX dataLoads = LinkedListX.empty(); + + @Autowired + public CouchbaseResource(DistributedMap client, EventBus bus) { + this.client = client; + bus.register(this); + } + + @Subscribe + public synchronized void events(SystemData event) { + dataLoads = dataLoads.plus(event); + } + + @GET + @Path("/loading-events") + @Produces("application/json") + public synchronized LinkedListX loadingEvents() { + return dataLoads; + } + + @GET + @Path("/maybe") + @Produces("application/json") + public Maybe maybe() { + return Maybe.just("hello-world"); + } + + @GET + @Path("/get") + public String bucket() { + return client.get("hello").toString(); + } + + @GET + @Path("/put") + public String put() { + client.put("hello", "world"); + return "added"; + } +} diff --git a/micro-async-data-loader/src/test/java/app/loader/scheduled/off/com/oath/micro/server/CouchbaseRunnerTest.java b/micro-async-data-loader/src/test/java/app/loader/scheduled/off/com/oath/micro/server/CouchbaseRunnerTest.java new file mode 100644 index 000000000..aa5a29140 --- /dev/null +++ b/micro-async-data-loader/src/test/java/app/loader/scheduled/off/com/oath/micro/server/CouchbaseRunnerTest.java @@ -0,0 +1,71 @@ +package app.loader.scheduled.off.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +import org.couchbase.mock.CouchbaseMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { + "couchbaseServers", "http://localhost:8091/pools", + "couchbasePassword", "", + "couchbaseBucket", "beer-sample", + "async.data.schedular.cron.loader", "* * * * * ?", + "async.data.schedular.cron.cleaner", "* * * * * ?" +}) +public class CouchbaseRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + try { + // couchbase already running? + rest.get("http://localhost:8091/pools"); + } catch (Exception e) { + // start mock couchbase + CouchbaseMock.main(new String[]{"-S"}); + } + server = new MicroserverApp( + ConfigurableModule.builder() + .context("simple-app") + .build()); + + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + rest.get("http://localhost:8080/simple-app/couchbase/put"); + assertThat(rest.get("http://localhost:8080/simple-app/couchbase/get"), + containsString("world")); + + Thread.sleep(2000); + String json = rest.getJson("http://localhost:8080/simple-app/couchbase/loading-events"); + List list = JacksonUtil.convertFromJson(json, List.class); + System.out.println(list); + assertTrue(list.size() == 0); + + } + +} diff --git a/micro-async-data-loader/src/test/java/app/loader/scheduled/off/com/oath/micro/server/TurnOff.java b/micro-async-data-loader/src/test/java/app/loader/scheduled/off/com/oath/micro/server/TurnOff.java new file mode 100644 index 000000000..3d74501a9 --- /dev/null +++ b/micro-async-data-loader/src/test/java/app/loader/scheduled/off/com/oath/micro/server/TurnOff.java @@ -0,0 +1,15 @@ +package app.loader.scheduled.off.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.async.data.loader.ConditionallyLoad; + +@Component +public class TurnOff implements ConditionallyLoad { + + @Override + public boolean shouldLoad() { + return false; + } + +} diff --git a/micro-async-data-loader/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-async-data-loader/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..64802357d --- /dev/null +++ b/micro-async-data-loader/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,54 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload, Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post( + Entity.entity(JacksonUtil.serializeToJson(payload), MediaType.APPLICATION_JSON), type + ); + } + + +} diff --git a/micro-async-data-writer/README.md b/micro-async-data-writer/README.md new file mode 100644 index 000000000..225665faa --- /dev/null +++ b/micro-async-data-writer/README.md @@ -0,0 +1,135 @@ +# Async Data Writer Plugin + +[micro-async-data-writer example apps](https://github.com/aol/micro-server/tree/master/micro-async-data-writer/src/test/java/app) + +This plugin supports asyncrhonously writing data to a store such as S3 or Couchbase (via micro-s3 or micro-couchbase plugins), using the Manifest Comparator pattern (see micro-manifest-comparator). This is a technique that allows a Microservice to generate data for another Microservice to use. The writer stores the data and a version in the datastore. The reader checks for version changes and asynchronously loads the data on change. With micro-async-data-writer and micro-async-data-loader in conjunction with either micro-s3 or micro-couchbase Microserver provides the infrastructure and client code need only configure data access and pass the data to the AsyncDataWriter bean. By adding micro-async-data-loader to the classpath of your consuming service (and configuring your datasource and manifest comparator key name), changes will be automatically detected and loaded asynchronously into that service. + + +# Async Data Writer Plugin Features + +1. AsyncDataWriter for asynchronous data storage +2. DataCleaner for scheduled removal of old data keys +3. MultiDataWriter for data migration (supports writing to multiple stores at once) +4. All updates and loads trigger events written to a Guava Event Bus + +## Configuring and using the AsyncDataWriter + +This plugin must be used in conjunction with an implementation of the interfaces in micro-manifest-comparator (either micro-s3 or micro-couchbase should be on the classpath). The first steps to using the AsyncDataWriter should be to configure access to your data store as per the appropriate plugin (configure access keys for S3, servers / user / password for Couchbase). + + +### Additional properties are + +async.data.writer.threads=no. of threads for asynchronous writing + +1 Thread is the default and is generally enough unless multiple AsyncDataWriters are to be configured to use the same thread pool. + +async.data.writer.multi=true / false + +By default writing to multiple services is disabled, if more than one ManifestComparator bean is found on the classpath only the first is configured in an AsyncDataWriter. If async.data.writer.multi is set to true all ManifestComparators will be wrapped by a single MultiDataWriter bean. Calling saveAndIncrement with new data on this bean will write that data to all sources. + +### Using AsyncDataWriter + +Inject in the AsyncDataWriter as a Spring Bean to your Service + + ```java + private final AsyncDataWriter comparator; + + @Autowired + public MyService(AsyncDataWriter comparator) { + this.comparator = comparator; + } + + ``` + + Save data to the remote store via saveAndIncrement + + ```java + FutureW task = comparator.saveAndIncrement(newData); + ``` + + All methods on AsyncDataWriter return a FutureW and execute asynchronously. Users can block by calling get() on the FutureW task and recieve any result (Void tasks will return null). Additional operations can be chained via map / peek etc. + + ### Using MultiDataWriter + + Both AsyncDataWriter and MultiDataWriter implement the same interface DataWriter. Simply inject the MultiDataWriter into your Service bean and turn on the feature. + + ```java + private final DataWriter comparator; + + @Autowired + public MyService(MultiDataWriter comparator) { + this.comparator = comparator; + } + + ``` + + We can save the data to all configured stores via saveAndIncrement + + ```java + FutureW task = comparator.saveAndIncrement(newData); + ``` + + ### Configuring multiple different writers + + Best practice is to configure one writer per Microservice, but if you really need more, they can be configured independently as Spring Beans or Programmatically. + +Use AsyncDataWriter#asyncDataWriter to create a new instance - passing in an Executor, a ManifestComparator and optionally a Guava event bus. + + ```java +AsyncDataWriter dataWriter = AsyncDataWriter.asyncDataWriter(executor,manifestComparator,eventBus); + ``` + +New ManifestComparators targeting a different data key can be created from preconfigured ManifestComparators via ManifestComparator#withKey + + + ```java + + public ManifestComparator createManifestComparatorFromExisting(ManifestComparator existing){ + return existing.withKey("new-data-key"); + } + +``` + +# Data Cleaner Plugin Features + +The Data Cleaner removes old versions of the versioning key from the data store (Couchbase or S3). It runs on a schedule configurable via a Quartz cron expression. The default is to run hourly - + +async.data.schedular.cron.cleaner=0 0 * * * ? + +When the cleaner runs it triggers an event with processing and error stats published to a Guava Event Bus. + +## Conditionally turning the cleaner off + +The DataCleaner can be truned off conditionally by having a Spring Bean implement ConditionallyClean. shouldClean is called everytime the DataCleaner is scheduled to determine if it is run. + +```java + +@Component +public class TurnOff implements ConditionallyClean { + + @Override + public boolean shouldClean() { + + return false; + } + +} + +``` + +## Getting The Microserver Async Data Writer Plugin + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-async-data-writer/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-async-data-writer) + +### Maven +```xml + + com.oath.microservices + micro-async-data-writer + x.yz + +``` +### Gradle +```groovy + compile 'com.oath.microservices:micro-async-data-writer:x.yz' + ``` diff --git a/micro-async-data-writer/build.gradle b/micro-async-data-writer/build.gradle new file mode 100644 index 000000000..d0fe1d84f --- /dev/null +++ b/micro-async-data-writer/build.gradle @@ -0,0 +1,73 @@ +description = 'micro-async-data-writer' + +repositories { + maven { url "https://jitpack.io" } +} + +dependencies { + compile("com.oath.cyclops:cyclops:$cyclopsVersion") + compile project(':micro-events') + compile project(':micro-manifest-comparator') + testCompile project(':micro-grizzly-with-jersey') + testCompile project(':micro-couchbase') +} + +modifyPom { + project { + name 'Microserver async data writing' + description 'Plugin for writing and cleaning data asyncrhonously via a micro-manifest-comparator implementation' + url 'https://github.com/aol/micro-server' + inceptionYear '2016' + + groupId 'com.oath.microservices' + artifactId 'micro-async-data-writer' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } + + } +} + +extraArchive { + sources = true + tests = true + javadoc = true +} + +nexus { + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' +} + diff --git a/micro-async-data-writer/settings.gradle b/micro-async-data-writer/settings.gradle new file mode 100644 index 000000000..760cb5f0b --- /dev/null +++ b/micro-async-data-writer/settings.gradle @@ -0,0 +1,19 @@ +/* + * This settings file was auto generated by the Gradle buildInit task + * by 'johnmcclean' at '7/4/16 12:28 PM' with Gradle 2.13 + * + * The settings file is used to specify which projects to include in your build. + * In a single project build this file can be empty or even removed. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user guide at https://docs.gradle.org/2.13/userguide/multi_project_builds.html + */ + +/* +// To declare projects as part of a multi-project build use the 'include' method +include 'shared' +include 'api' +include 'services:webservice' +*/ + +rootProject.name = 'micro-async-data-writer' diff --git a/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/cleaner/CleanerSchedular.java b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/cleaner/CleanerSchedular.java new file mode 100644 index 000000000..bf3980dfa --- /dev/null +++ b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/cleaner/CleanerSchedular.java @@ -0,0 +1,29 @@ +package com.oath.micro.server.async.data.cleaner; + +import java.util.concurrent.ScheduledExecutorService; + + +import com.google.common.eventbus.EventBus; + +import cyclops.reactive.collections.mutable.ListX; +import cyclops.reactive.ReactiveSeq; +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class CleanerSchedular { + + private final ListX cleaner; + private final ScheduledExecutorService executor; + private final EventBus bus; + private final ConditionallyClean condition; + + public void schedule() { + cleaner.forEach(cl -> { + ReactiveSeq.generate(() -> 1) + .filter(in -> condition.shouldClean()) + .map(i -> cl.scheduleAndLog()) + .peek(sd -> bus.post(sd)) + .schedule(cl.getCron(), executor); + }); + } +} diff --git a/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/cleaner/ConditionallyClean.java b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/cleaner/ConditionallyClean.java new file mode 100644 index 000000000..2890330e8 --- /dev/null +++ b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/cleaner/ConditionallyClean.java @@ -0,0 +1,6 @@ +package com.oath.micro.server.async.data.cleaner; + +public interface ConditionallyClean { + + public boolean shouldClean(); +} diff --git a/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/cleaner/ConfigureSchedulingAsyncDataWriter.java b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/cleaner/ConfigureSchedulingAsyncDataWriter.java new file mode 100644 index 000000000..421a9a4a1 --- /dev/null +++ b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/cleaner/ConfigureSchedulingAsyncDataWriter.java @@ -0,0 +1,59 @@ +package com.oath.micro.server.async.data.cleaner; + +import java.util.List; +import java.util.concurrent.Executors; +import java.util.function.BinaryOperator; + +import cyclops.reactive.collections.mutable.ListX; +import cyclops.control.Maybe; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +import com.oath.micro.server.manifest.ManifestComparator; +import com.google.common.eventbus.EventBus; + +@Configuration +public class ConfigureSchedulingAsyncDataWriter { + + @Value("${async.data.schedular.cron.cleaner:0 0 * * * ?}") + private String defaultCronCleaner; + @Value("${async.data.schedular.threads:1}") + private int schedularThreads; + + @Autowired(required = false) + private List dataCleaners = ListX.empty(); + @Autowired(required = false) + private List predicates = ListX.empty(); + + @Autowired + private EventBus bus; + + @Autowired(required = false) + private List defaultComparators; + + private ListX dataCleaners() { + Maybe defaultDataCleaner = defaultComparators.size() == 1 ? Maybe.just(new DataCleaner( + defaultComparators.get(0), + defaultCronCleaner)) + : Maybe.nothing(); + return ListX.fromIterable(defaultDataCleaner) + .plusAll(dataCleaners); + + } + + @Bean + public CleanerSchedular asyncDataCleaner() { + ConditionallyClean cc = () -> true; + BinaryOperator accumulator = (cc1, cc2) -> () -> cc1.shouldClean() && cc2.shouldClean(); + CleanerSchedular schedular = new CleanerSchedular( + dataCleaners(), + Executors.newScheduledThreadPool(schedularThreads), bus, + predicates.stream() + .reduce(cc, accumulator)); + schedular.schedule(); + return schedular; + } +} diff --git a/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/cleaner/DataCleaner.java b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/cleaner/DataCleaner.java new file mode 100644 index 000000000..55c200de2 --- /dev/null +++ b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/cleaner/DataCleaner.java @@ -0,0 +1,52 @@ +package com.oath.micro.server.async.data.cleaner; + +import java.util.Random; +import java.util.function.Supplier; + + +import com.oath.micro.server.events.ScheduledJob; +import com.oath.micro.server.events.SystemData; +import com.oath.micro.server.manifest.ManifestComparator; +import com.oath.micro.server.utility.HashMapBuilder; + +import cyclops.reactive.collections.mutable.MapX; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public class DataCleaner implements ScheduledJob { + + public static final String MANIFEST_COMPARATOR_DATA_CLEANER_KEY = "Manifest Comparator Data Cleaner"; + private final ManifestComparator comparator; + @Getter + private final String cron; + private final Random r = new Random(); + + @Override + public SystemData scheduleAndLog() { + String correlationId = "" + System.currentTimeMillis() + ":" + r.nextLong(); + Supplier> dataMap = () -> MapX.fromMap(HashMapBuilder.map(MANIFEST_COMPARATOR_DATA_CLEANER_KEY, + comparator.toString()) + .build()); + + try { + comparator.cleanAll(); + return SystemData. builder() + .correlationId(correlationId) + .dataMap(dataMap.get()) + .errors(0) + .processed(1) + .build(); + } catch (Exception e) { + return SystemData. builder() + .correlationId(correlationId) + .dataMap(dataMap.get() + .plus("Error", e.getMessage())) + .errors(1) + .processed(0) + .build(); + } + + } + +} diff --git a/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/AsyncDataWriter.java b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/AsyncDataWriter.java new file mode 100644 index 000000000..b923a1358 --- /dev/null +++ b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/AsyncDataWriter.java @@ -0,0 +1,93 @@ +package com.oath.micro.server.async.data.writer; + +import java.util.Random; +import java.util.concurrent.Executor; +import java.util.function.Supplier; + +import cyclops.control.Future; +import cyclops.reactive.collections.mutable.MapX; +import cyclops.data.tuple.Tuple; + + +import com.oath.micro.server.events.SystemData; +import com.oath.micro.server.manifest.ManifestComparator; +import com.oath.micro.server.utility.HashMapBuilder; +import com.google.common.eventbus.EventBus; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class AsyncDataWriter implements DataWriter { + public static final String MANIFEST_COMPARATOR_DATA_LOADER_KEY = "Manifest Comparator AsyncDataWriter Load Operation"; + public static final String MANIFEST_COMPARATOR_DATA_WRITER_KEY = "Manifest Comparator AsyncDataWriter Save and increment Operation"; + + private final Executor executorService; + private final ManifestComparator comparator; + private final Random r = new Random(); + private final EventBus bus; + + public static AsyncDataWriter asyncDataWriter(Executor executorService, ManifestComparator comparator) { + return asyncDataWriter(executorService, comparator, new EventBus()); + } + + public static AsyncDataWriter asyncDataWriter(Executor executorService, ManifestComparator comparator, + EventBus bus) { + return new AsyncDataWriter<>( + executorService, comparator, bus); + } + + @Override + public Future loadAndGet() { + String correlationId = "" + System.currentTimeMillis() + ":" + r.nextLong(); + Supplier> dataMap = () -> MapX.fromMap(HashMapBuilder.map(MANIFEST_COMPARATOR_DATA_LOADER_KEY, + comparator.toString()) + .build()); + + return Future.of(() -> Tuple.tuple(comparator.load(), comparator.getData()), executorService) + .peek(t -> bus.post(SystemData. builder() + .correlationId(correlationId) + .dataMap(dataMap.get()) + .errors(0) + .processed(t._1() ? 1 : 0) + .build())) // add + // recover + // option + // here + // also + // with + // cyclops-react + // 1.0.0-final + .map(t -> t._2()); + } + + @Override + public Future saveAndIncrement(T data) { + String correlationId = "" + System.currentTimeMillis() + ":" + r.nextLong(); + Supplier> dataMap = () -> MapX.fromMap(HashMapBuilder.map(MANIFEST_COMPARATOR_DATA_WRITER_KEY, + comparator.toString()) + .build()); + return Future. of(() -> { + comparator.saveAndIncrement(data); + return null; + } , executorService) + .peek(t -> bus.post(SystemData. builder() + .correlationId(correlationId) + .dataMap(dataMap.get()) + .errors(0) + .processed(1) + .build())); // add + // recover + // option + // here + // also + // with + // cyclops-react + // 1.0.0-final + + } + + @Override + public Future isOutOfDate() { + return Future.of(() -> comparator.isOutOfDate(), executorService); + } +} diff --git a/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/ConfigureDataWriter.java b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/ConfigureDataWriter.java new file mode 100644 index 000000000..b36aadb90 --- /dev/null +++ b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/ConfigureDataWriter.java @@ -0,0 +1,59 @@ +package com.oath.micro.server.async.data.writer; + +import java.util.List; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +import cyclops.reactive.collections.mutable.ListX; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +import com.oath.micro.server.manifest.ManifestComparator; +import com.google.common.eventbus.EventBus; + +@Configuration +public class ConfigureDataWriter { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + @Autowired(required = false) + private List defaultComparators = ListX.empty(); + @Value("${async.data.writer.threads:1}") + private int writerThreads = 1; + @Value("${async.data.writer.multi:false}") + private boolean multiWriterOn = false; + + @Autowired + private EventBus bus; + + @Bean + public AsyncDataWriter defaultDataWriter() { + if (defaultComparators.size() > 0) { + System.err.println("Warning :: multiple ManifestComparators configured as Spring bean, using the first configured bean for the Default AsyncDataWriter, recommended approach is to configure your own DataWriters as needed."); + logger.warn("Warning :: multiple ManifestComparators configured as Spring bean, using the first configured bean for the Default AsyncDataWriter, recommended approach is to configure your own DataWriters as needed."); + } + return new AsyncDataWriter( + asyncDataWriterThreadPool(), defaultComparators.get(0), bus); + } + + @Bean + public MultiDataWriter defaultMultiDataWriter() { + if (multiWriterOn) + return new MultiDataWriter( + ListX.fromIterable(defaultComparators) + .map(mc -> new AsyncDataWriter( + asyncDataWriterThreadPool(), mc, bus))); + return new MultiDataWriter( + ListX.empty()); + } + + @Bean + public Executor asyncDataWriterThreadPool() { + return Executors.newFixedThreadPool(writerThreads); + } + +} diff --git a/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/DataWriter.java b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/DataWriter.java new file mode 100644 index 000000000..5980042fe --- /dev/null +++ b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/DataWriter.java @@ -0,0 +1,14 @@ +package com.oath.micro.server.async.data.writer; + + +import cyclops.control.Future; + +public interface DataWriter { + + Future loadAndGet(); + + Future saveAndIncrement(T data); + + Future isOutOfDate(); + +} diff --git a/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/MultiDataWriter.java b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/MultiDataWriter.java new file mode 100644 index 000000000..bc52f42bd --- /dev/null +++ b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/MultiDataWriter.java @@ -0,0 +1,34 @@ +package com.oath.micro.server.async.data.writer; + + + +import cyclops.control.Future; +import cyclops.reactive.collections.mutable.ListX; +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class MultiDataWriter implements DataWriter { + + private final ListX> comparators; + + @Override + public Future loadAndGet() { + return comparators.map(c -> c.loadAndGet()) + .foldLeft((acc, next) -> acc.zip(next, (v1, v2) -> v1)) + .orElse(Future.ofResult(null)); + } + + @Override + public Future saveAndIncrement(T data) { + return comparators.map(c -> c.saveAndIncrement(data)) + .foldLeft((acc, next) -> acc.zip(next, (v1, v2) -> v1)) + .orElse(Future.ofResult(null)); + } + + @Override + public Future isOutOfDate() { + return comparators.map(c -> c.isOutOfDate()) + .foldLeft((acc, next) -> acc.zip(next, (v1, v2) -> v1 || v2)) + .orElse(Future.ofResult(false)); + } +} diff --git a/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/plugin/AsyncDataWriterPlugin.java b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/plugin/AsyncDataWriterPlugin.java new file mode 100644 index 000000000..ecc6133b2 --- /dev/null +++ b/micro-async-data-writer/src/main/java/com/oath/micro/server/async/data/writer/plugin/AsyncDataWriterPlugin.java @@ -0,0 +1,18 @@ +package com.oath.micro.server.async.data.writer.plugin; + +import java.util.Set; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.async.data.cleaner.ConfigureSchedulingAsyncDataWriter; +import com.oath.micro.server.async.data.writer.ConfigureDataWriter; +import cyclops.reactive.collections.mutable.SetX; + +public class AsyncDataWriterPlugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of(ConfigureSchedulingAsyncDataWriter.class, ConfigureDataWriter.class); + } + +} diff --git a/micro-async-data-writer/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-async-data-writer/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..a05010df2 --- /dev/null +++ b/micro-async-data-writer/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.async.data.writer.plugin.AsyncDataWriterPlugin \ No newline at end of file diff --git a/micro-async-data-writer/src/test/java/app/cleaner/off/scheduled/com/oath/micro/server/CouchbaseResource.java b/micro-async-data-writer/src/test/java/app/cleaner/off/scheduled/com/oath/micro/server/CouchbaseResource.java new file mode 100644 index 000000000..b7535c8b2 --- /dev/null +++ b/micro-async-data-writer/src/test/java/app/cleaner/off/scheduled/com/oath/micro/server/CouchbaseResource.java @@ -0,0 +1,64 @@ +package app.cleaner.off.scheduled.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import cyclops.reactive.collections.immutable.LinkedListX; +import cyclops.control.Maybe; +import org.springframework.beans.factory.annotation.Autowired; + + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.distributed.DistributedMap; +import com.oath.micro.server.events.SystemData; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +@Path("/couchbase") +@Rest +public class CouchbaseResource { + + private final DistributedMap client; + + private volatile LinkedListX dataCleans = LinkedListX.empty(); + + @Autowired + public CouchbaseResource(DistributedMap client, EventBus bus) { + this.client = client; + bus.register(this); + } + + @Subscribe + public synchronized void events(SystemData event) { + dataCleans = dataCleans.plus(event); + } + + @GET + @Path("/cleaning-events") + @Produces("application/json") + public synchronized LinkedListX cleaningEvents() { + return dataCleans; + } + + @GET + @Path("/maybe") + @Produces("application/json") + public Maybe maybe() { + return Maybe.just("hello-world"); + } + + @GET + @Path("/get") + public String bucket() { + return client.get("hello") + .toString(); + } + + @GET + @Path("/put") + public String put() { + client.put("hello", "world"); + return "added"; + } +} diff --git a/micro-async-data-writer/src/test/java/app/cleaner/off/scheduled/com/oath/micro/server/CouchbaseRunnerTest.java b/micro-async-data-writer/src/test/java/app/cleaner/off/scheduled/com/oath/micro/server/CouchbaseRunnerTest.java new file mode 100644 index 000000000..b60689ded --- /dev/null +++ b/micro-async-data-writer/src/test/java/app/cleaner/off/scheduled/com/oath/micro/server/CouchbaseRunnerTest.java @@ -0,0 +1,67 @@ +package app.cleaner.off.scheduled.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +import org.couchbase.mock.CouchbaseMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { "couchbaseServers", "http://localhost:8091/pools", "couchbasePassword", "", + "couchbaseBucket", "beer-sample", "async.data.schedular.cron.loader", "* * * * * ?", + "async.data.schedular.cron.cleaner", "* * * * * ?" }) +public class CouchbaseRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + try { + // couchbase already running? + rest.get("http://localhost:8091/pools"); + } catch (Exception e) { + // start mock couchbase + CouchbaseMock.main(new String[] { "-S" }); + } + server = new MicroserverApp( + ConfigurableModule.builder() + .context("simple-app") + .build()); + + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + rest.get("http://localhost:8080/simple-app/couchbase/put"); + assertThat(rest.get("http://localhost:8080/simple-app/couchbase/get"), containsString("world")); + + Thread.sleep(2000); + + String json = rest.getJson("http://localhost:8080/simple-app/couchbase/cleaning-events"); + List list = JacksonUtil.convertFromJson(json, List.class); + System.out.println(list); + assertTrue(list.size() == 0); + + } + +} diff --git a/micro-async-data-writer/src/test/java/app/cleaner/off/scheduled/com/oath/micro/server/TurnOff.java b/micro-async-data-writer/src/test/java/app/cleaner/off/scheduled/com/oath/micro/server/TurnOff.java new file mode 100644 index 000000000..c387db307 --- /dev/null +++ b/micro-async-data-writer/src/test/java/app/cleaner/off/scheduled/com/oath/micro/server/TurnOff.java @@ -0,0 +1,16 @@ +package app.cleaner.off.scheduled.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.async.data.cleaner.ConditionallyClean; + +@Component +public class TurnOff implements ConditionallyClean { + + @Override + public boolean shouldClean() { + + return false; + } + +} diff --git a/micro-async-data-writer/src/test/java/app/cleaner/scheduled/com/oath/micro/server/CouchbaseResource.java b/micro-async-data-writer/src/test/java/app/cleaner/scheduled/com/oath/micro/server/CouchbaseResource.java new file mode 100644 index 000000000..fb91c7246 --- /dev/null +++ b/micro-async-data-writer/src/test/java/app/cleaner/scheduled/com/oath/micro/server/CouchbaseResource.java @@ -0,0 +1,64 @@ +package app.cleaner.scheduled.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import cyclops.reactive.collections.immutable.LinkedListX; +import cyclops.control.Maybe; +import org.springframework.beans.factory.annotation.Autowired; + + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.distributed.DistributedMap; +import com.oath.micro.server.events.SystemData; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +@Path("/couchbase") +@Rest +public class CouchbaseResource { + + private final DistributedMap client; + + private volatile LinkedListX dataCleans = LinkedListX.empty(); + + @Autowired + public CouchbaseResource(DistributedMap client, EventBus bus) { + this.client = client; + bus.register(this); + } + + @Subscribe + public synchronized void events(SystemData event) { + dataCleans = dataCleans.plus(event); + } + + @GET + @Path("/cleaning-events") + @Produces("application/json") + public synchronized LinkedListX cleaningEvents() { + return dataCleans; + } + + @GET + @Path("/maybe") + @Produces("application/json") + public Maybe maybe() { + return Maybe.just("hello-world"); + } + + @GET + @Path("/get") + public String bucket() { + return client.get("hello") + .toString(); + } + + @GET + @Path("/put") + public String put() { + client.put("hello", "world"); + return "added"; + } +} diff --git a/micro-async-data-writer/src/test/java/app/cleaner/scheduled/com/oath/micro/server/CouchbaseRunnerTest.java b/micro-async-data-writer/src/test/java/app/cleaner/scheduled/com/oath/micro/server/CouchbaseRunnerTest.java new file mode 100644 index 000000000..7a898fd53 --- /dev/null +++ b/micro-async-data-writer/src/test/java/app/cleaner/scheduled/com/oath/micro/server/CouchbaseRunnerTest.java @@ -0,0 +1,67 @@ +package app.cleaner.scheduled.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +import org.couchbase.mock.CouchbaseMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { "couchbaseServers", "http://localhost:8091/pools", "couchbasePassword", "", + "couchbaseBucket", "beer-sample", "async.data.schedular.cron.loader", "* * * * * ?", + "async.data.schedular.cron.cleaner", "* * * * * ?" }) +public class CouchbaseRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + try { + // couchbase already running? + rest.get("http://localhost:8091/pools"); + } catch (Exception e) { + // start mock couchbase + CouchbaseMock.main(new String[] { "-S" }); + } + server = new MicroserverApp( + ConfigurableModule.builder() + .context("simple-app") + .build()); + + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + rest.get("http://localhost:8080/simple-app/couchbase/put"); + assertThat(rest.get("http://localhost:8080/simple-app/couchbase/get"), containsString("world")); + + Thread.sleep(2000); + + String json = rest.getJson("http://localhost:8080/simple-app/couchbase/cleaning-events"); + List list = JacksonUtil.convertFromJson(json, List.class); + System.out.println(list); + assertTrue(list.size() > 0); + + } + +} diff --git a/micro-async-data-writer/src/test/java/app/writer/configured/com/oath/micro/server/ManifestComparatorResource.java b/micro-async-data-writer/src/test/java/app/writer/configured/com/oath/micro/server/ManifestComparatorResource.java new file mode 100644 index 000000000..079f6fdd0 --- /dev/null +++ b/micro-async-data-writer/src/test/java/app/writer/configured/com/oath/micro/server/ManifestComparatorResource.java @@ -0,0 +1,48 @@ +package app.writer.configured.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.async.data.writer.AsyncDataWriter; +import com.oath.micro.server.auto.discovery.Rest; + +@Path("/comparator") +@Rest +public class ManifestComparatorResource { + + private volatile int count = 1; + private final AsyncDataWriter comparator; + + @Autowired + public ManifestComparatorResource(AsyncDataWriter comparator) { + this.comparator = comparator; + } + + @GET + @Path("/increment") + public String bucket() { + comparator.saveAndIncrement("hello" + (count++)) + .get(); + return "incremented"; + } + + @GET + @Path("/get") + public String get() { + + return comparator.loadAndGet() + .fold(s->s,e->"Error loading " + e.getMessage()); + + } + + + @GET + @Path("/check") + public String check() { + return "" + !comparator.isOutOfDate() + .getOrElse(null); + + } +} diff --git a/micro-async-data-writer/src/test/java/app/writer/configured/com/oath/micro/server/ManifestComparatorRunnerTest.java b/micro-async-data-writer/src/test/java/app/writer/configured/com/oath/micro/server/ManifestComparatorRunnerTest.java new file mode 100644 index 000000000..dd8ba45b5 --- /dev/null +++ b/micro-async-data-writer/src/test/java/app/writer/configured/com/oath/micro/server/ManifestComparatorRunnerTest.java @@ -0,0 +1,62 @@ +package app.writer.configured.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.couchbase.mock.CouchbaseMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { "couchbaseServers", "http://localhost:8091/pools", "couchbasePassword", "", + "couchbaseBucket", "beer-sample", "couchbase.manifest.comparison.key", "test-key" }) +public class ManifestComparatorRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + try { + // couchbase already running? + rest.get("http://localhost:8091/pools"); + } catch (Exception e) { + // start mock couchbase + CouchbaseMock.main(new String[] { "-S" }); + } + server = new MicroserverApp( + () -> "simple-app"); + + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + rest.get("http://localhost:8080/simple-app/comparator/increment"); + + assertThat(rest.get("http://localhost:8080/simple-app/comparator/check"), equalTo("true")); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"), equalTo("hello1")); + rest.get("http://localhost:8080/simple-app/comparator/increment"); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"), equalTo("hello2")); + + rest.get("http://localhost:8080/simple-app/comparator2/increment"); + + assertThat(rest.get("http://localhost:8080/simple-app/comparator/check"), equalTo("false")); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"), equalTo("hellob")); + + } + +} diff --git a/micro-async-data-writer/src/test/java/app/writer/configured/com/oath/micro/server/SecondComparatorResource.java b/micro-async-data-writer/src/test/java/app/writer/configured/com/oath/micro/server/SecondComparatorResource.java new file mode 100644 index 000000000..dcc9c9179 --- /dev/null +++ b/micro-async-data-writer/src/test/java/app/writer/configured/com/oath/micro/server/SecondComparatorResource.java @@ -0,0 +1,44 @@ +package app.writer.configured.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.manifest.ManifestComparator; + +@Path("/comparator2") +@Rest +public class SecondComparatorResource { + + private final ManifestComparator comparator; + + @Autowired + public SecondComparatorResource(ManifestComparator comparator) { + this.comparator = comparator.withKey("test-key"); + } + + @GET + @Path("/increment") + public String bucket() { + comparator.saveAndIncrement("hellob"); + return "increment"; + } + + @GET + @Path("/get") + public String get() { + comparator.load(); + return comparator.getData() + .toString(); + + } + + @GET + @Path("/check") + public String check() { + return "" + !comparator.isOutOfDate(); + + } +} \ No newline at end of file diff --git a/micro-async-data-writer/src/test/java/com/oath/micro/server/async/data/writer/AsyncDataWriterTest.java b/micro-async-data-writer/src/test/java/com/oath/micro/server/async/data/writer/AsyncDataWriterTest.java new file mode 100644 index 000000000..f0827127d --- /dev/null +++ b/micro-async-data-writer/src/test/java/com/oath/micro/server/async/data/writer/AsyncDataWriterTest.java @@ -0,0 +1,71 @@ +package com.oath.micro.server.async.data.writer; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; + +import cyclops.control.Future; +import cyclops.control.Try; +import org.junit.Before; +import org.junit.Test; + + +import com.oath.micro.server.events.SystemData; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +public class AsyncDataWriterTest { + + AsyncDataWriter writer; + Executor ex = Executors.newFixedThreadPool(5); + EventBus bus; + private DummyManifestComparator dummyMc; + AtomicInteger eventRecieved; + + @Before + public void setup() { + eventRecieved = new AtomicInteger( + 0); + bus = new EventBus(); + bus.register(this); + dummyMc = new DummyManifestComparator<>(); + writer = new AsyncDataWriter<>( + ex, dummyMc, bus); + } + + @Subscribe + public void event(SystemData data) { + eventRecieved.incrementAndGet(); + } + + @Test + public void testLoadAndGet() { + assertThat(eventRecieved.get(), equalTo(0)); + dummyMc.setData("hello world"); + Future res = writer.loadAndGet(); + + assertThat(res.get(), equalTo(Try.success("hello world"))); + assertThat(dummyMc.loadCalled.get(), equalTo(1)); + assertThat(eventRecieved.get(), equalTo(1)); + } + + @Test + public void testSaveAndIncrement() { + assertThat(eventRecieved.get(), equalTo(0)); + writer.saveAndIncrement("boo!"); + Future res = writer.loadAndGet(); + assertThat(res.get(), equalTo(Try.success("boo!"))); + assertThat(eventRecieved.get(), equalTo(2)); + } + + @Test + public void testIsOutOfDate() { + writer.isOutOfDate() + .get(); + assertThat(dummyMc.outofDateCalled.get(), equalTo(1)); + } + +} diff --git a/micro-async-data-writer/src/test/java/com/oath/micro/server/async/data/writer/DummyDataWriter.java b/micro-async-data-writer/src/test/java/com/oath/micro/server/async/data/writer/DummyDataWriter.java new file mode 100644 index 000000000..d0fdd21b9 --- /dev/null +++ b/micro-async-data-writer/src/test/java/com/oath/micro/server/async/data/writer/DummyDataWriter.java @@ -0,0 +1,38 @@ +package com.oath.micro.server.async.data.writer; + + + +import cyclops.control.Future; +import lombok.Getter; +import lombok.Setter; + +public class DummyDataWriter implements DataWriter { + + @Getter + @Setter + String data; + @Getter + @Setter + int version = 0; + @Getter + @Setter + boolean outofdate = false; + + @Override + public Future loadAndGet() { + return Future.ofResult(data); + } + + @Override + public Future saveAndIncrement(String data) { + this.data = data; + version++; + return Future.ofResult(null); + } + + @Override + public Future isOutOfDate() { + return Future.ofResult(outofdate); + } + +} diff --git a/micro-async-data-writer/src/test/java/com/oath/micro/server/async/data/writer/DummyManifestComparator.java b/micro-async-data-writer/src/test/java/com/oath/micro/server/async/data/writer/DummyManifestComparator.java new file mode 100644 index 000000000..8c06e168f --- /dev/null +++ b/micro-async-data-writer/src/test/java/com/oath/micro/server/async/data/writer/DummyManifestComparator.java @@ -0,0 +1,71 @@ +package com.oath.micro.server.async.data.writer; + +import java.util.concurrent.atomic.AtomicInteger; + +import com.oath.micro.server.manifest.ManifestComparator; + +import lombok.Getter; +import lombok.Setter; + +public class DummyManifestComparator implements ManifestComparator { + + AtomicInteger loadCalled = new AtomicInteger( + 0); + AtomicInteger outofDateCalled = new AtomicInteger( + 0); + AtomicInteger cleanCalled = new AtomicInteger( + 0); + AtomicInteger cleanAllCalled = new AtomicInteger( + 0); + + private boolean outOfDate; + @Getter + @Setter + private volatile T data; + + @Override + public ManifestComparator withKey(java.lang.String key) { + return (DummyManifestComparator) this; + } + + @Override + public boolean load() { + loadCalled.incrementAndGet(); + return true; + + } + + @Override + public void cleanAll() { + cleanAllCalled.incrementAndGet(); + + } + + @Override + public void clean(int numberToClean) { + cleanCalled.incrementAndGet(); + + } + + @Override + public void saveAndIncrement(T data) { + this.data = data; + } + + @Override + public T getData() { + return data; + } + + @Override + public boolean isOutOfDate() { + outofDateCalled.incrementAndGet(); + return true; + } + + @Override + public T getCurrentData() { + return getData(); + } + +} diff --git a/micro-async-data-writer/src/test/java/com/oath/micro/server/async/data/writer/MultiDataWriterTest.java b/micro-async-data-writer/src/test/java/com/oath/micro/server/async/data/writer/MultiDataWriterTest.java new file mode 100644 index 000000000..a250ab71b --- /dev/null +++ b/micro-async-data-writer/src/test/java/com/oath/micro/server/async/data/writer/MultiDataWriterTest.java @@ -0,0 +1,111 @@ +package com.oath.micro.server.async.data.writer; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import cyclops.reactive.collections.mutable.ListX; +import cyclops.control.Try; +import org.junit.Before; +import org.junit.Test; + + + +public class MultiDataWriterTest { + + MultiDataWriter writer; + MultiDataWriter empty; + private DummyDataWriter dataWriter1; + private DummyDataWriter dataWriter2; + + @Before + public void setup() { + dataWriter1 = new DummyDataWriter(); + dataWriter2 = new DummyDataWriter(); + writer = new MultiDataWriter<>( + ListX.of(dataWriter1, dataWriter2)); + empty = new MultiDataWriter<>( + ListX.empty()); + } + + @Test + public void bothDataWritersUpdated() { + writer.saveAndIncrement("hello world"); + assertThat(dataWriter1.loadAndGet() + .get(), + equalTo(Try.success("hello world"))); + assertThat(dataWriter2.loadAndGet() + .get(), + equalTo(Try.success("hello world"))); + } + + @Test + public void emptySaveAndIncrement() { + + assertThat(empty.saveAndIncrement("hello world") + .get(), + equalTo(Try.success(null))); + } + + @Test + public void loadAndGetReturnsDataFromFirst() { + dataWriter1.setData("one"); + dataWriter2.setData("two"); + String data = writer.loadAndGet() + .orElse(null); + assertThat(data, equalTo("one")); + } + + @Test + public void loadAndGetReturnsNullForEmpty() { + String data = empty.loadAndGet() + .orElse("null!!"); + assertThat(data, equalTo(null)); + } + + @Test + public void isOutOfDateReturnsFalseIfSecondOnlyIsFalse() { + dataWriter1.setOutofdate(true); + dataWriter2.setOutofdate(false); + boolean outofdate = writer.isOutOfDate() + .orElse(null); + assertThat(outofdate, equalTo(true)); + } + + @Test + public void isOutOfDateReturnsFalseIfFirstOnlyIsFalse() { + dataWriter1.setOutofdate(false); + dataWriter2.setOutofdate(true); + boolean outofdate = writer.isOutOfDate() + .orElse(null); + assertThat(outofdate, equalTo(true)); + } + + @Test + public void isOutOfDateReturnsFalseIfBothAreFalse() { + dataWriter1.setOutofdate(false); + dataWriter2.setOutofdate(false); + boolean outofdate = writer.isOutOfDate() + .orElse(null); + assertThat(outofdate, equalTo(false)); + } + + @Test + public void isOutOfDateReturnsTrueIfBothAreTrue() { + dataWriter1.setOutofdate(true); + dataWriter2.setOutofdate(true); + + boolean outofdate = writer.isOutOfDate() + .orElse(null); + + + assertThat(outofdate, equalTo(true)); + } + + @Test + public void isOutofDateWorksEmpty() { + + boolean outofdate = empty.isOutOfDate() + .orElse(null); + assertThat(outofdate, equalTo(false)); + } +} diff --git a/micro-async-data-writer/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-async-data-writer/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-async-data-writer/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-boot/README.md b/micro-boot/README.md new file mode 100644 index 000000000..796d575d2 --- /dev/null +++ b/micro-boot/README.md @@ -0,0 +1,113 @@ +# Spring Boot entry point for Microserver + +[micro-boot example apps](https://github.com/aol/micro-server/tree/master/micro-boot/src/test/java/app) + +**micro-boot** allows Microserver front ends to use Microserver plugins with Spring Boot without configuring support for the micro-jersey plugin. Rest and Web end points in Microserver +plugins may not be available (but the Spring beans will be and can be used to expose the same data in a different manner). +To use full-stack Spring Boot with Microserver (and. Jersey) see the [micro-spring-boot plugin](https://github.com/aol/micro-server/tree/master/micro-spring-boot). +## A simple example with one resource + +* Annotate your classes with @Microboot to let Spring Boot know the base package for auto-scanning Spring beans. + +* Create a MicroserverApp and run. + +* You can now use the @Microserver annotation for configuration (except for base auto-scan packages) + +[Spring Boot Hello World example](https://spring.io/guides/gs/spring-boot/) converted to a micro-boot test + +```java +@Microserver +@MicroBoot +public class Application { + + + AsyncRestClient rest = new AsyncRestClient(1000,1000).withAccept("text/plain"); + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + new MicroserverApp( ()-> "spring-mvc"); + Thread.sleep(2000); + + assertThat(rest.get("http://localhost:8080/spring-mvc").get(),is("Greetings from Spring Boot with Microserver!")); + + } + + +} + + +@RestController +public class HelloController { + + @RequestMapping("/") + public String index() { + return "Greetings from Spring Boot with Microserver!"; + } + +} + +``` + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-boot/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-boot) + +Add micro-boot to the classpath + +Maven + + + com.oath.microservices + micro-boot + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-boot:x.yz' + +And also add Grizzly and Jersey (micro-grizzly-with-jersey will add both) + +Maven + + + com.oath.microservices + micro-grizzly-with-jersey + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-grizzly-with-jersey:x.yz' + + +## Create a simple server +```java +@Microboot +@Path("/simple") +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()->"test-app").run(); + } + + @GET + public String ping() { + return "ok"; + } +} +``` +# Relationship to Microserver and Spring Boot + +micro-boot allows you to use Microserver plugins & jax-rs support with Spring Boot back ends. + + +@Microboot is simply syntax sugar for + + ```java +@Component +@SpringBootApplication(exclude = SpringDataWebAutoConfiguration.class) + ``` + +You can also define your own SpringBoot configuration if required. diff --git a/micro-boot/build.gradle b/micro-boot/build.gradle index c78c0009e..9f0d479e3 100644 --- a/micro-boot/build.gradle +++ b/micro-boot/build.gradle @@ -1,67 +1,85 @@ description = 'micro-boot' + dependencies { - + compile 'org.springframework.boot:spring-boot:' + springBootVersion + compile 'org.springframework.boot:spring-boot-autoconfigure:' + springBootVersion + compile project(':micro-core') + + compile group: 'org.glassfish.jersey.core', name: 'jersey-server', version: "$jerseyVersion" + compile(group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: "$jerseyVersion") { + exclude(module: 'jackson-xc') + exclude(module: 'jackson-core-asl') + exclude(module: 'jackson-jaxrs') + exclude(module: 'jackson-mapper-asl') + } + compile group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version: "$jerseyVersion" - compile 'org.springframework.boot:spring-boot:'+springBootVersion - compile 'org.springframework.boot:spring-boot-autoconfigure:'+springBootVersion - compile project(':micro-core') - testCompile group: 'com.google.guava', name: 'guava', version:guavaVersion - testCompile group: 'org.hamcrest', name: 'hamcrest-all', version:hamcrestVersion - testCompile project(':micro-jackson-configuration') - testCompile project(':micro-grizzly') - testCompile project(':micro-swagger') - testCompile project(':micro-client') - testCompile project(':micro-events') - testCompile project(':micro-jersey') - testCompile project(':micro-metrics') + compile "org.glassfish.jersey.media:jersey-media-multipart:$jerseyVersion" + compile "org.glassfish.jersey.ext:jersey-spring4:$jerseyVersion" + compile "org.glassfish.jersey.ext:jersey-bean-validation:$jerseyVersion" + compile project(':micro-jackson-configuration') + testCompile("org.springframework.boot:spring-boot-starter-web:"+ springBootVersion) + testCompile 'org.springframework.boot:spring-boot-starter-test:' + springBootVersion + testCompile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: "$jerseyVersion" + testCompile 'org.apache.tomcat.embed:tomcat-embed-core:' + tomcatVersion + + testCompile project(':micro-application-register') + testCompile project(':micro-cors') + testCompile project(':micro-swagger') + testCompile project(':micro-client') + testCompile project(':micro-events') + testCompile project(':micro-metrics') + testCompile project(':micro-guava') + + testCompile "com.oath.cyclops:cyclops-futurestream:$cyclopsVersion" } modifyPom { - project { - name 'Microserver-boot' - description 'Opinionated rest microservices with Spring Boot' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver-boot' + description 'Opinionated rest microservices with Spring Boot' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-boot' + version "$version" - groupId 'com.aol.microservices' - artifactId 'micro-boot' - version "$version" - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - } - } + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-boot/readme.md b/micro-boot/readme.md deleted file mode 100644 index bb583eafc..000000000 --- a/micro-boot/readme.md +++ /dev/null @@ -1,114 +0,0 @@ -# Spring Boot entry point for Microserver - -[micro-boot example apps](https://github.com/aol/micro-server/tree/master/micro-boot/src/test/java/app) - -**micro-boot** allows Microserver front ends to use Spring Boot backends (in other words it adds Spring Boot as a plugin to Microserver). To use full-stack Spring Boot with Microserver (and Jersey) see the [micro-spring-boot plugin](https://github.com/aol/micro-server/tree/master/micro-spring-boot) (in other words to use Microserver as a plugin to Spring Boot use micro-sprint-boot rather than this plugin). - -## A simple example with one resource - -* Annotate your classes with @Microboot to let Spring Boot know the base package for auto-scanning Spring beans. - -* Create a MicroserverApp and run. - -* You can now use the @Microserver annotation for configuration (except for base auto-scan packages) - - -```java -@Microboot //configure this package as the base for autoscan -//optionally use @Microserver here for more configuration options -public class SimpleExample { - - RestClient rest = new RestClient(10_000,1_000); - - - public static void main (String[] args){ - - new MicroserverApp(()-> "simple-app").start(); - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),equalTo("ok")); - - } - - - -} -@Rest -@Path("/status") -public class SimpleResource{ - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return "ok"; - } - - -} -``` - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-boot/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-boot) - -Add micro-boot to the classpath - -Maven - - - com.aol.microservices - micro-boot - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-boot:x.yz' - -And also add Grizzly and Jersey (micro-grizzly-with-jersey will add both) - -Maven - - - com.aol.microservices - micro-grizzly-with-jersey - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-grizzly-with-jersey:x.yz' - - -## Create a simple server -```java -@Microboot -@Path("/simple") -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()->"test-app").run(); - } - - @GET - public String ping() { - return "ok"; - } -} -``` -# Relationship to Microserver and Spring Boot - -micro-boot allows you to use Microserver plugins & jax-rs support with Spring Boot back ends. - - -@Microboot is simply syntax sugar for - - ```java -@Component -@SpringBootApplication(exclude = SpringDataWebAutoConfiguration.class) - ``` - -You can also define your own SpringBoot configuration if required. diff --git a/micro-boot/src/main/java/com/aol/micro/server/boot/config/Microboot.java b/micro-boot/src/main/java/com/aol/micro/server/boot/config/Microboot.java deleted file mode 100644 index 4957fe1d5..000000000 --- a/micro-boot/src/main/java/com/aol/micro/server/boot/config/Microboot.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.aol.micro.server.boot.config; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration; -import org.springframework.stereotype.Component; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Component -@SpringBootApplication(exclude = SpringDataWebAutoConfiguration.class) -public @interface Microboot{ - -} \ No newline at end of file diff --git a/micro-boot/src/main/java/com/aol/micro/server/spring/boot/BootApplicationConfigurator.java b/micro-boot/src/main/java/com/aol/micro/server/spring/boot/BootApplicationConfigurator.java deleted file mode 100644 index 24beb3017..000000000 --- a/micro-boot/src/main/java/com/aol/micro/server/spring/boot/BootApplicationConfigurator.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.aol.micro.server.spring.boot; - - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.context.ConfigurableApplicationContext; - -import com.aol.micro.server.config.Config; -import com.aol.micro.server.spring.SpringBuilder; - -public class BootApplicationConfigurator implements SpringBuilder { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public ConfigurableApplicationContext createSpringApp(Config config, Class...classes) { - - - List classList = new ArrayList(); - classList.addAll(Arrays.asList(classes)); - classList.add(JerseyApplication.class); - SpringApplicationBuilder builder = new SpringApplicationBuilder(classList.toArray(new Class[0])); - new JerseyApplication(classList).config(builder); - - return builder.application().run(); - } - - -} diff --git a/micro-boot/src/main/java/com/aol/micro/server/spring/boot/BootPlugin.java b/micro-boot/src/main/java/com/aol/micro/server/spring/boot/BootPlugin.java deleted file mode 100644 index fc2ab302b..000000000 --- a/micro-boot/src/main/java/com/aol/micro/server/spring/boot/BootPlugin.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aol.micro.server.spring.boot; - -import com.aol.micro.server.Plugin; -import com.aol.micro.server.spring.SpringBuilder; - -/** - * - * @author johnmcclean - * - */ -public class BootPlugin implements Plugin{ - - - /** - * @return Engine for building Spring Context - */ - public SpringBuilder springBuilder(){ - return new BootApplicationConfigurator(); - } - - -} diff --git a/micro-boot/src/main/java/com/aol/micro/server/spring/boot/JerseyApplication.java b/micro-boot/src/main/java/com/aol/micro/server/spring/boot/JerseyApplication.java deleted file mode 100644 index f0048927c..000000000 --- a/micro-boot/src/main/java/com/aol/micro/server/spring/boot/JerseyApplication.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.aol.micro.server.spring.boot; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.Properties; - -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.embedded.EmbeddedServletContainer; -import org.springframework.boot.context.embedded.EmbeddedServletContainerException; -import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; -import org.springframework.boot.context.web.SpringBootServletInitializer; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; - -import com.aol.micro.server.module.Environment; -import com.aol.micro.server.servers.AccessLogLocationBean; -import com.aol.micro.server.spring.properties.PropertyFileConfig; - - -@Configuration -@PropertySource("classpath:spring-boot-microserver.properties") -public class JerseyApplication extends SpringBootServletInitializer { - - List classes; - - public JerseyApplication(){ - classes = new ArrayList<>(); - } - - public JerseyApplication(List classes2) { - classes = new ArrayList<>(); - classes.addAll(classes2); - classes.add(JerseyApplication.class); - classes.add(PropertyFileConfig.class); - classes.add(Environment.class); - classes.add(AccessLogLocationBean.class); - } - - - @Override - protected SpringApplicationBuilder configure( - SpringApplicationBuilder application) { - - return application.sources(classes.toArray(new Class[0])); - } - - public SpringApplicationBuilder config(SpringApplicationBuilder builder) { - return configure(builder); - - } - - @Bean - public AccessLogLocationBean createAccessLogLocationBean( - ApplicationContext rootContext) { - Properties props = (Properties) rootContext.getBean("propertyFactory"); - String location = Optional.ofNullable( - (String) props.get("access.log.output")).orElse("./logs/"); - return new AccessLogLocationBean(location); - } - - - - - - - @Bean - public EmbeddedServletContainerFactory servletContainer() { - - return (initializers) -> { - return new Container(); - }; - - - } - - static class Container implements EmbeddedServletContainer { - - @Override - public void start() throws EmbeddedServletContainerException { - - - } - - @Override - public void stop() throws EmbeddedServletContainerException { - - } - - @Override - public int getPort() { - - return 0; - } - - } - -} diff --git a/micro-boot/src/main/java/com/aol/micro/server/spring/boot/JerseySpringBootFrontEndApplication.java b/micro-boot/src/main/java/com/aol/micro/server/spring/boot/JerseySpringBootFrontEndApplication.java deleted file mode 100644 index 06f750e98..000000000 --- a/micro-boot/src/main/java/com/aol/micro/server/spring/boot/JerseySpringBootFrontEndApplication.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.aol.micro.server.spring.boot; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.Properties; - -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.embedded.EmbeddedServletContainer; -import org.springframework.boot.context.embedded.EmbeddedServletContainerException; -import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; -import org.springframework.boot.context.web.SpringBootServletInitializer; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; - -import com.aol.micro.server.module.Environment; -import com.aol.micro.server.servers.AccessLogLocationBean; -import com.aol.micro.server.spring.properties.PropertyFileConfig; - - -@Configuration -@PropertySource("classpath:spring-boot-microserver.properties") -public class JerseySpringBootFrontEndApplication extends SpringBootServletInitializer { - - List classes; - - public JerseySpringBootFrontEndApplication(){ - classes = new ArrayList<>(); - } - - public JerseySpringBootFrontEndApplication(List classes2) { - classes = new ArrayList<>(); - classes.addAll(classes2); - classes.add(JerseySpringBootFrontEndApplication.class); - classes.add(PropertyFileConfig.class); - classes.add(Environment.class); - classes.add(AccessLogLocationBean.class); - } - - - @Override - protected SpringApplicationBuilder configure( - SpringApplicationBuilder application) { - - return application.sources(classes.toArray(new Class[0])); - } - - public SpringApplicationBuilder config(SpringApplicationBuilder builder) { - return configure(builder); - - } - - @Bean - public AccessLogLocationBean createAccessLogLocationBean( - ApplicationContext rootContext) { - Properties props = (Properties) rootContext.getBean("propertyFactory"); - String location = Optional.ofNullable( - (String) props.get("access.log.output")).orElse("./logs/"); - return new AccessLogLocationBean(location); - } - - - - - - - -} diff --git a/micro-boot/src/main/java/com/oath/micro/server/boot/BootFrontEndApplicationConfigurator.java b/micro-boot/src/main/java/com/oath/micro/server/boot/BootFrontEndApplicationConfigurator.java new file mode 100644 index 000000000..0c683bea2 --- /dev/null +++ b/micro-boot/src/main/java/com/oath/micro/server/boot/BootFrontEndApplicationConfigurator.java @@ -0,0 +1,113 @@ +package com.oath.micro.server.boot; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletException; +import javax.servlet.ServletRequestListener; + +import com.oath.cyclops.types.persistent.PersistentList; +import com.oath.micro.server.GlobalState; +import com.oath.micro.server.module.MicroserverEnvironment; +import cyclops.reactive.ReactiveSeq; +import cyclops.reactive.collections.immutable.LinkedListX; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.builder.SpringApplicationBuilder; + +import org.springframework.boot.web.servlet.ServletContextInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.stereotype.Component; +import org.springframework.web.context.ContextLoader; + + +import com.oath.micro.server.config.Config; +import com.oath.micro.server.module.Module; +import com.oath.micro.server.module.ModuleDataExtractor; +import com.oath.micro.server.servers.FilterConfigurer; +import com.oath.micro.server.servers.ServletConfigurer; +import com.oath.micro.server.servers.ServletContextListenerConfigurer; +import com.oath.micro.server.servers.model.FilterData; +import com.oath.micro.server.servers.model.ServerData; +import com.oath.micro.server.servers.model.ServletData; +import com.oath.micro.server.spring.SpringBuilder; + +public class BootFrontEndApplicationConfigurator extends SpringBootServletInitializer implements SpringBuilder { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public ConfigurableApplicationContext createSpringApp(Config config, Class...classes) { + + + List classList = new ArrayList(); + classList.addAll(Arrays.asList(classes)); + + + SpringApplicationBuilder builder = new SpringApplicationBuilder(classList.toArray(new Class[0])); + + + + + return builder.application().run(); + } + + @Override + public Class[] classes(Config config, Class... classes) { + List classList = new ArrayList(); + classList.addAll(Arrays.asList(classes)); + + return ReactiveSeq.fromIterable(classList) + .toArray(i->new Class[i]); + + } + + @Component + static class MyWebAppInitializer implements ServletContextInitializer { + + private final MicroserverEnvironment microserverEnvironment; + private final Module module; + private final ApplicationContext rootContext; + @Autowired(required=false) + public MyWebAppInitializer(MicroserverEnvironment env, ApplicationContext rootContext, Module m){ + this.microserverEnvironment = env; + this.rootContext = rootContext; + this.module = m; + } + @Autowired(required=false) + public MyWebAppInitializer(MicroserverEnvironment env, ApplicationContext rootContext){ + this(env,rootContext, GlobalState.state.getModules().firstValue(null)); + } + + @Override + public void onStartup(ServletContext webappContext) throws ServletException { + + ModuleDataExtractor extractor = new ModuleDataExtractor(module); + microserverEnvironment.assureModule(module); + String fullRestResource = "/" + module.getContext() + "/*"; + + ServerData serverData = new ServerData(microserverEnvironment.getModuleBean(module).getPort(), + Arrays.asList(), + rootContext, fullRestResource, module); + List filterDataList = extractor.createFilteredDataList(serverData); + List servletDataList = extractor.createServletDataList(serverData); + new ServletConfigurer(serverData, LinkedListX.fromIterable(servletDataList)).addServlets(webappContext); + + new FilterConfigurer(serverData, LinkedListX.fromIterable(filterDataList)).addFilters(webappContext); + PersistentList servletContextListenerData = LinkedListX.fromIterable(module.getListeners(serverData)).filter(i->!(i instanceof ContextLoader)); + PersistentList servletRequestListenerData = LinkedListX.fromIterable(module.getRequestListeners(serverData)); + + new ServletContextListenerConfigurer(serverData, servletContextListenerData, servletRequestListenerData).addListeners(webappContext); + + } + + } + + +} diff --git a/micro-boot/src/main/java/com/oath/micro/server/boot/BootPlugin.java b/micro-boot/src/main/java/com/oath/micro/server/boot/BootPlugin.java new file mode 100644 index 000000000..fa93c7333 --- /dev/null +++ b/micro-boot/src/main/java/com/oath/micro/server/boot/BootPlugin.java @@ -0,0 +1,44 @@ +package com.oath.micro.server.boot; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + +import javax.ws.rs.core.FeatureContext; + +import cyclops.reactive.collections.mutable.MapX; +import cyclops.reactive.collections.mutable.SetX; +import cyclops.reactive.companion.MapXs; +import org.glassfish.jersey.CommonProperties; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.spring.SpringBuilder; + +/** + * + * @author johnmcclean + * + */ +public class BootPlugin implements Plugin{ + + + /** + * @return Engine for building Spring Context + */ + public SpringBuilder springBuilder(){ + return new BootFrontEndApplicationConfigurator(); + } + + @Override + public Set springClasses() { + return SetX.empty(); + } + + @Override + public Function> jacksonFeatureProperties(){ + return context-> new HashMap<>(); + } + +} diff --git a/micro-boot/src/main/java/com/oath/micro/server/boot/MicroBoot.java b/micro-boot/src/main/java/com/oath/micro/server/boot/MicroBoot.java new file mode 100644 index 000000000..46916cfcc --- /dev/null +++ b/micro-boot/src/main/java/com/oath/micro/server/boot/MicroBoot.java @@ -0,0 +1,18 @@ +package com.oath.micro.server.boot; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration; +import org.springframework.stereotype.Component; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Component +@SpringBootApplication(exclude = SpringDataWebAutoConfiguration.class) +public @interface MicroBoot { + +} diff --git a/micro-boot/src/main/java/com/oath/micro/server/rest/jersey/SpringBootJerseyRestApplication.java b/micro-boot/src/main/java/com/oath/micro/server/rest/jersey/SpringBootJerseyRestApplication.java new file mode 100644 index 000000000..dd1894c1a --- /dev/null +++ b/micro-boot/src/main/java/com/oath/micro/server/rest/jersey/SpringBootJerseyRestApplication.java @@ -0,0 +1,87 @@ +package com.oath.micro.server.rest.jersey; + +import java.util.Map; + +import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import cyclops.reactive.collections.immutable.LinkedListX; +import org.glassfish.hk2.utilities.binding.AbstractBinder; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.ServerProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; + +import com.oath.micro.server.GlobalState; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.module.JaxRsProvider; +import com.oath.micro.server.module.Module; +import com.oath.micro.server.module.ModuleDataExtractor; + +import javax.ws.rs.ext.Provider; + +public class SpringBootJerseyRestApplication extends ResourceConfig { + + @Autowired(required=false) + public SpringBootJerseyRestApplication(ApplicationContext context){ + this(context, GlobalState.state.getModules().firstValue(null)); + } + + @Autowired(required=false) + public SpringBootJerseyRestApplication(ApplicationContext context,Module module){ + ModuleDataExtractor extractor = new ModuleDataExtractor(module); + + LinkedListX allResources = extractor.getRestResources(context); + + System.out.println("Resources " + allResources); + Map serverProperties = module.getServerProperties(); + if (allResources != null) { + for (Object next : allResources) { + if(isSingleton(next)) + register(next); + else + register(next.getClass()); + } + } + + if (serverProperties.isEmpty()) { + property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true); + //http://stackoverflow.com/questions/25755773/bean-validation-400-errors-are-returning-default-error-page-html-instead-of-re + property(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, "true"); + } else { + for (Map.Entry entry : serverProperties.entrySet()) { + property(entry.getKey(), entry.getValue()); + } + } + + + context.getBeansOfType(AbstractBinder.class).forEach((n,e)->register(e)); + + JacksonJaxbJsonProvider p = new JacksonJaxbJsonProvider(); + p.setMapper(JacksonUtil.getMapper()); + register(p); + module.getDefaultJaxRsPackages() + .stream() + .forEach(e -> packages(e)); + module.getDefaultResources() + .stream() + .forEach(e -> register(e)); + + + module.getResourceConfigManager().accept(new JaxRsProvider<>(this)); + } + + + private boolean isSingleton(Object next) { + if(next instanceof RestResource) + return ((RestResource)next).isSingleton(); + Rest rest = next.getClass().getAnnotation(Rest.class); + if(rest == null) + return !(next instanceof Class); + return rest.isSingleton(); + } + + + + +} diff --git a/micro-boot/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-boot/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 3e9503978..000000000 --- a/micro-boot/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.spring.boot.BootPlugin \ No newline at end of file diff --git a/micro-boot/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-boot/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..cdb0f8ada --- /dev/null +++ b/micro-boot/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.boot.BootPlugin diff --git a/micro-boot/src/test/java/app/boot/com/aol/micro/server/AsyncAppRunner.java b/micro-boot/src/test/java/app/boot/com/aol/micro/server/AsyncAppRunner.java deleted file mode 100644 index 447bcece4..000000000 --- a/micro-boot/src/test/java/app/boot/com/aol/micro/server/AsyncAppRunner.java +++ /dev/null @@ -1,49 +0,0 @@ -package app.boot.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.boot.config.Microboot; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; - -@Microserver @Microboot -public class AsyncAppRunner { - - - AsyncRestClient rest = new AsyncRestClient(1000,1000).withAccept("text/plain"); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( ()-> "async-app"); - server.start(); - - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - Thread.sleep(2000); - - assertThat(rest.get("http://localhost:8080/async-app/async/expensive").get(),is(";test!;test!;test!")); - - } - - - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/app/boot/com/aol/micro/server/AsyncResource.java b/micro-boot/src/test/java/app/boot/com/aol/micro/server/AsyncResource.java deleted file mode 100644 index 56d3c4af5..000000000 --- a/micro-boot/src/test/java/app/boot/com/aol/micro/server/AsyncResource.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.boot.com.aol.micro.server; - -import java.util.List; -import java.util.concurrent.CompletableFuture; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.container.Suspended; - -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.google.common.collect.ImmutableList; - -@Path("/async") -@Component -public class AsyncResource implements RestResource{ - - private final SimpleReact simpleReact =new SimpleReact(); - private final ImmutableList urls = ImmutableList.of("http://localhost:8080/async-app/async/ping2", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping"); - - private final AsyncRestClient client = new AsyncRestClient(1000,1000).withAccept("text/plain"); - - @GET - @Path("/expensive") - @Produces("text/plain") - public void expensive(@Suspended AsyncResponse asyncResponse){ - - simpleReact.fromStream(urls.stream() - .>map(it -> client.get(it))) - .onFail(it -> "") - .peek(it -> - System.out.println(it)) - .allOf(data -> { - System.out.println(data); - return asyncResponse.resume(String.join(";", (List)data)); }); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - -} diff --git a/micro-boot/src/test/java/app/boot/com/aol/micro/server/SimpleApp.java b/micro-boot/src/test/java/app/boot/com/aol/micro/server/SimpleApp.java deleted file mode 100644 index 41cdbc63e..000000000 --- a/micro-boot/src/test/java/app/boot/com/aol/micro/server/SimpleApp.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.boot.com.aol.micro.server; - -import com.aol.micro.server.MicroserverApp; - - -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()->"test-app").run(); - } - -} diff --git a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/AltAppResource.java b/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/AltAppResource.java deleted file mode 100644 index facee2f8a..000000000 --- a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/AltAppResource.java +++ /dev/null @@ -1,21 +0,0 @@ -package app.boot.embedded.com.aol.micro.server; - -import java.util.List; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - - -@AltAppRestResource -@Path("/alt-status") -public class AltAppResource { - - @POST - @Produces("application/json") - @Path("/ping") - public List ping(ImmutableEntity entity) { - return entity.getList(); - } - -} diff --git a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/AltAppRestResource.java b/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/AltAppRestResource.java deleted file mode 100644 index fc7803727..000000000 --- a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/AltAppRestResource.java +++ /dev/null @@ -1,15 +0,0 @@ -package app.boot.embedded.com.aol.micro.server; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface AltAppRestResource { - -} diff --git a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java b/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java deleted file mode 100644 index adfe9570d..000000000 --- a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java +++ /dev/null @@ -1,25 +0,0 @@ -package app.boot.embedded.com.aol.micro.server; - -import java.util.Arrays; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.boot.config.Microboot; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.EmbeddedModule; - -@Microserver @Microboot//(basePackages = { "app.boot.embedded.com.aol.micro.server" }) -public class EmbeddedAppLocalMain { - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( - EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")).start(); - - - - } - - -} diff --git a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/EmbeddedAppTest.java b/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/EmbeddedAppTest.java deleted file mode 100644 index 3a878873c..000000000 --- a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/EmbeddedAppTest.java +++ /dev/null @@ -1,103 +0,0 @@ -package app.boot.embedded.com.aol.micro.server; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.NotFoundException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.EmbeddedModule; -import com.aol.micro.server.testing.RestAgent; -import com.google.common.collect.ImmutableList; - -public class EmbeddedAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer(){ - server = new MicroserverApp(EmbeddedAppLocalMain.class, - EmbeddedModule.annotationModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.annotationModule(Arrays.asList(AltAppRestResource.class),"alternative-app")); - server.start(); - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); - - - assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value",ImmutableList.of("hello","world")),List.class), - hasItem("hello")); - - } - - - @Test - public void nonBlockingRestClientTest(){ - assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"),is("-*test!-*test!")); - } - - CompletableFuture toCompletableFuture( - final ListenableFuture listenableFuture - ) { - //create an instance of CompletableFuture - CompletableFuture completable = new CompletableFuture() { - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - // propagate cancel to the listenable future - boolean result = listenableFuture.cancel(mayInterruptIfRunning); - super.cancel(mayInterruptIfRunning); - return result; - } - }; - - // add callback - listenableFuture.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(T result) { - completable.complete(result); - } - - @Override - public void onFailure(Throwable t) { - completable.completeExceptionally(t); - } - }); - return completable; - } - - @Test(expected=NotFoundException.class) - public void confirmAltAppCantUseTestAppResources(){ - - assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); - - } - @Test(expected=NotFoundException.class) - public void confirmTestAppCantUseAltAppResources(){ - - assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",ImmutableList.of("hello","world")),List.class), - hasItem("hello")); - - } -} diff --git a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/ImmutableEntity.java b/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/ImmutableEntity.java deleted file mode 100644 index 98733725d..000000000 --- a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/ImmutableEntity.java +++ /dev/null @@ -1,29 +0,0 @@ -package app.boot.embedded.com.aol.micro.server; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -import com.google.common.collect.ImmutableList; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableEntity { - - private final String value; - private final ImmutableList list; - - public ImmutableEntity() { - this(null,null); - } - -} diff --git a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/TestAppResource.java b/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/TestAppResource.java deleted file mode 100644 index c359e6a82..000000000 --- a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/TestAppResource.java +++ /dev/null @@ -1,52 +0,0 @@ -package app.boot.embedded.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.micro.server.rest.client.nio.NIORestClient; -import com.google.common.collect.ImmutableList; -//@Component -@TestAppRestResource -@Path("/test-status") -public class TestAppResource { - - private final SimpleReact simpleReact = new SimpleReact(); - private final NIORestClient template; - private final ImmutableList urls = ImmutableList.of("http://localhost:8081/alternative-app/alt-status/ping", - "http://localhost:8080/test-app/test-status/ping", - "http://localhost:8082/simple-app/status/ping", - "http://localhost:8080/test-app/test-status/ping"); - - @Autowired - public TestAppResource(NIORestClient template) { - - this.template = template; - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - @GET - @Produces("text/plain") - @Path("/rest-calls") - public String restCallResult(){ - - return simpleReact - .fromStream(urls.stream() - .map(it -> template.getForEntity(it,String.class))) - .then(it -> it.getBody()) - .then(it -> "*"+it) - .peek(loadedAndModified -> System.out.println(loadedAndModified)) - .block().stream().reduce("", (acc,next) -> acc+"-"+next); - - } - -} diff --git a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/TestAppRestResource.java b/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/TestAppRestResource.java deleted file mode 100644 index 3c0e7861b..000000000 --- a/micro-boot/src/test/java/app/boot/embedded/com/aol/micro/server/TestAppRestResource.java +++ /dev/null @@ -1,15 +0,0 @@ -package app.boot.embedded.com.aol.micro.server; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface TestAppRestResource{ - -} diff --git a/micro-boot/src/test/java/app/boot/events/com/aol/micro/server/EventRunnerTest.java b/micro-boot/src/test/java/app/boot/events/com/aol/micro/server/EventRunnerTest.java deleted file mode 100644 index cdeed1b3d..000000000 --- a/micro-boot/src/test/java/app/boot/events/com/aol/micro/server/EventRunnerTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package app.boot.events.com.aol.micro.server; - - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.boot.config.Microboot; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.testing.RestAgent; - -@Microserver @Microboot -public class EventRunnerTest { - - RestAgent rest = new RestAgent(); - private final AsyncRestClient client = new AsyncRestClient(1000,1000).withAccept("application/json"); - MicroserverApp server; - - - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "event-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/event-app/status/ping"),is("ok")); - - assertThat(client.get("http://localhost:8080/event-app/active/jobs").get(), - containsString("startedAt")); - assertThat(client.get("http://localhost:8080/event-app/active/requests").get(), - containsString("startedAt")); - assertThat(client.get("http://localhost:8080/event-app/manifest").get(), - containsString("Manifest")); - - } - - - -} diff --git a/micro-boot/src/test/java/app/boot/events/com/aol/micro/server/EventStatusResource.java b/micro-boot/src/test/java/app/boot/events/com/aol/micro/server/EventStatusResource.java deleted file mode 100644 index 4a17b5de9..000000000 --- a/micro-boot/src/test/java/app/boot/events/com/aol/micro/server/EventStatusResource.java +++ /dev/null @@ -1,40 +0,0 @@ -package app.boot.events.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.events.RequestEvents; -import com.google.common.eventbus.EventBus; - -@Component -@Path("/status") -public class EventStatusResource implements RestResource { - - - - - private final EventBus bus; - - @Autowired - public EventStatusResource(EventBus bus ){ - this.bus = bus; - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - bus.post(RequestEvents.start("get", 1l)); - try{ - return "ok"; - }finally{ - bus.post(RequestEvents.finish("get",1l)); - } - } - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/app/boot/events/com/aol/micro/server/Job.java b/micro-boot/src/test/java/app/boot/events/com/aol/micro/server/Job.java deleted file mode 100644 index 8978963fd..000000000 --- a/micro-boot/src/test/java/app/boot/events/com/aol/micro/server/Job.java +++ /dev/null @@ -1,16 +0,0 @@ -package app.boot.events.com.aol.micro.server; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.events.ScheduledJob; -import com.aol.micro.server.events.SystemData; - -@Component -public class Job implements ScheduledJob{ - - @Override - public SystemData scheduleAndLog() { - return SystemData.builder().errors(0).processed(2).build(); - } - -} diff --git a/micro-boot/src/test/java/app/boot/events/com/aol/micro/server/Schedular.java b/micro-boot/src/test/java/app/boot/events/com/aol/micro/server/Schedular.java deleted file mode 100644 index d68afd75c..000000000 --- a/micro-boot/src/test/java/app/boot/events/com/aol/micro/server/Schedular.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.boot.events.com.aol.micro.server; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - - -@Component -public class Schedular { - - private final Job job; - - @Autowired - public Schedular(final Job job){ - this.job=job; - } - - @Scheduled(fixedDelay=1) - public synchronized void scheduleTask(){ - job.scheduleAndLog(); - } -} diff --git a/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/AutodiscoveredFilter.java b/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/AutodiscoveredFilter.java deleted file mode 100644 index 57467985d..000000000 --- a/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/AutodiscoveredFilter.java +++ /dev/null @@ -1,50 +0,0 @@ -package app.boot.filter.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import lombok.Getter; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.FilterConfiguration; - -@Component -public class AutodiscoveredFilter implements Filter, FilterConfiguration { - - @Getter - private static volatile int called= 0; - - @Override - public String[] getMapping() { - return new String[] { "/*" }; - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - - called++; - chain.doFilter(request, response); - } - - @Override - public void destroy() { - - - } - - - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/ConfiguredFilter.java b/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/ConfiguredFilter.java deleted file mode 100644 index 4d64ba4ae..000000000 --- a/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/ConfiguredFilter.java +++ /dev/null @@ -1,38 +0,0 @@ -package app.boot.filter.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import lombok.Getter; - -public class ConfiguredFilter implements Filter { - - @Getter - private static volatile int called= 0; - @Override - public void init(FilterConfig filterConfig) throws ServletException { - // TODO Auto-generated method stub - - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - called++; - chain.doFilter(request, response); - - } - - @Override - public void destroy() { - // TODO Auto-generated method stub - - } - -} diff --git a/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/FilterAppLocalMain.java b/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/FilterAppLocalMain.java deleted file mode 100644 index 42ff0cfaf..000000000 --- a/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/FilterAppLocalMain.java +++ /dev/null @@ -1,20 +0,0 @@ -package app.boot.filter.com.aol.micro.server; - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import com.aol.micro.server.MicroserverApp; -@Configuration -@ComponentScan(basePackages = { "app.filter.com.aol.micro.server" }) -public class FilterAppLocalMain { - - - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( FilterAppLocalMain.class, () -> "filter-app") - .run(); - } - - } \ No newline at end of file diff --git a/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/FilterRunnerTest.java b/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/FilterRunnerTest.java deleted file mode 100644 index 74497f9e3..000000000 --- a/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/FilterRunnerTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package app.boot.filter.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Map; -import java.util.concurrent.ExecutionException; - -import javax.servlet.Filter; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; -import com.google.common.collect.ImmutableMap; - -@Ignore -public class FilterRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - Map filters = ImmutableMap.of("/filter-app/status/ping2",new ConfiguredFilter()); - server = new MicroserverApp( FilterAppLocalMain.class, ConfigurableModule.builder().context("filter-app").filters(filters ).build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testAutoDiscoveredFilter() throws InterruptedException, ExecutionException{ - Thread.sleep(100); - assertThat(AutodiscoveredFilter.getCalled(),is(0)); - assertThat(rest.get("http://localhost:8080/filter-app/status/ping"),is("ok")); - assertThat(AutodiscoveredFilter.getCalled(),is(0)); - } - @Test - public void testConfiguredFilter() throws InterruptedException, ExecutionException{ - Thread.sleep(100); - assertThat(ConfiguredFilter.getCalled(),is(0)); - assertThat(rest.get("http://localhost:8080/filter-app/status/ping2"),is("ok")); - assertThat(ConfiguredFilter.getCalled(),is(1)); - } - - - - -} diff --git a/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/FilterStatusResource.java b/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/FilterStatusResource.java deleted file mode 100644 index fccca1ec2..000000000 --- a/micro-boot/src/test/java/app/boot/filter/com/aol/micro/server/FilterStatusResource.java +++ /dev/null @@ -1,30 +0,0 @@ -package app.boot.filter.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/status") -public class FilterStatusResource implements RestResource { - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - @GET - @Produces("text/plain") - @Path("/ping2") - public String ping2() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/app/guava/com/aol/micro/server/GuavaAppResource.java b/micro-boot/src/test/java/app/guava/com/aol/micro/server/GuavaAppResource.java deleted file mode 100644 index baeb5aed2..000000000 --- a/micro-boot/src/test/java/app/guava/com/aol/micro/server/GuavaAppResource.java +++ /dev/null @@ -1,30 +0,0 @@ -package app.guava.com.aol.micro.server; - -import java.util.List; -import java.util.Optional; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -@Component -@Path("/status") -public class GuavaAppResource implements RestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public List ping(ImmutableGuavaEntity entity) { - return entity.getList(); - } - @POST - @Produces("application/json") - @Path("/optional") - public Optional optional(Jdk8Entity entity) { - return entity.getName(); - } - -} diff --git a/micro-boot/src/test/java/app/guava/com/aol/micro/server/GuavaAppTest.java b/micro-boot/src/test/java/app/guava/com/aol/micro/server/GuavaAppTest.java deleted file mode 100644 index 0941ef957..000000000 --- a/micro-boot/src/test/java/app/guava/com/aol/micro/server/GuavaAppTest.java +++ /dev/null @@ -1,93 +0,0 @@ -package app.guava.com.aol.micro.server; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.List; -import java.util.Optional; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.SimpleReactStream; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.boot.config.Microboot; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.jackson.JacksonUtil; -import com.aol.micro.server.testing.RestAgent; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableSet; - -@Microserver @Microboot -public class GuavaAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - ImmutableGuavaEntity entity; - Jdk8Entity present; - Jdk8Entity absent; - - SimpleReact simpleReact = new SimpleReact(); - SimpleReactStream stream; - - @Before - public void startServer() { - stream = simpleReact.ofAsync( - () -> server = new MicroserverApp(GuavaAppTest.class, - () -> "guava-app")).then(server -> server.start()); - - entity = ImmutableGuavaEntity.builder().value("value") - .list(ImmutableList.of("hello", "world")) - .mapOfSets(ImmutableMap.of("key1", ImmutableSet.of(1, 2, 3))) - .multiMap(ImmutableMultimap.of("1", 2, "1", 2, "2", 4)).build(); - - JacksonUtil.convertFromJson(JacksonUtil.serializeToJson(entity), - ImmutableGuavaEntity.class); - - present = Jdk8Entity.builder().name(Optional.of("test")).build(); - - JacksonUtil.convertFromJson(JacksonUtil.serializeToJson(present), - Optional.class); - absent = Jdk8Entity.builder().name(Optional.empty()).build(); - } - - @After - public void stopServer() { - server.stop(); - } - - @Test - public void confirmExpectedUrlsPresentTest() throws InterruptedException, - ExecutionException { - - stream.block(); - - assertThat((List) rest.post( - "http://localhost:8080/guava-app/status/ping", entity, - List.class), hasItem("hello")); - - } - - @Test - public void confirmOptionalConversionWorking() throws InterruptedException, - ExecutionException { - - stream.block(); - - assertThat(rest.post("http://localhost:8080/guava-app/status/optional", - present, String.class), is("\"test\"")); - - assertThat(rest.post("http://localhost:8080/guava-app/status/optional", - absent, String.class), is("null")); - - } - -} diff --git a/micro-boot/src/test/java/app/guava/com/aol/micro/server/ImmutableGuavaEntity.java b/micro-boot/src/test/java/app/guava/com/aol/micro/server/ImmutableGuavaEntity.java deleted file mode 100644 index 8ee2bb325..000000000 --- a/micro-boot/src/test/java/app/guava/com/aol/micro/server/ImmutableGuavaEntity.java +++ /dev/null @@ -1,34 +0,0 @@ -package app.guava.com.aol.micro.server; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableSet; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableGuavaEntity { - - private final String value; - private final ImmutableList list; - private final ImmutableMap mapOfSets; - private final ImmutableMultimap multiMap; - - public ImmutableGuavaEntity() { - this(null,null,null,null); - } - -} diff --git a/micro-boot/src/test/java/app/guava/com/aol/micro/server/Jdk8Entity.java b/micro-boot/src/test/java/app/guava/com/aol/micro/server/Jdk8Entity.java deleted file mode 100644 index 039cb2645..000000000 --- a/micro-boot/src/test/java/app/guava/com/aol/micro/server/Jdk8Entity.java +++ /dev/null @@ -1,27 +0,0 @@ -package app.guava.com.aol.micro.server; - -import java.util.Optional; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "optional") -@Getter -@AllArgsConstructor -@Builder -public class Jdk8Entity { - - private final Optional name; - - public Jdk8Entity(){ - name = Optional.empty(); - } -} diff --git a/micro-boot/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java b/micro-boot/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java deleted file mode 100644 index c2d92407e..000000000 --- a/micro-boot/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java +++ /dev/null @@ -1,45 +0,0 @@ -package app.listeners.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import lombok.Getter; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.FilterConfiguration; - -@Component -public class AutodiscoveredListener implements ServletContextListener { - - @Getter - private static volatile int called= 0; - - @Override - public void contextInitialized(ServletContextEvent sce) { - called ++; - - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - - - } - - - - - - - - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java b/micro-boot/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java deleted file mode 100644 index ba6591048..000000000 --- a/micro-boot/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package app.listeners.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.List; -import java.util.concurrent.ExecutionException; - -import javax.servlet.ServletContextListener; - -import nonautoscan.com.aol.micro.server.ConfiguredListener; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.boot.config.Microboot; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; -import com.google.common.collect.ImmutableList; - - -@Microserver @Microboot -public class ListenerRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - List listeners = ImmutableList.of(new ConfiguredListener()); - server = new MicroserverApp( ListenerRunnerTest.class, ConfigurableModule.builder().context("listener-app").listeners(listeners ).build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testListeners() throws InterruptedException, ExecutionException{ - - assertThat(AutodiscoveredListener.getCalled(),is(1)); - assertThat(ConfiguredListener.getCalled(),is(1)); - } - - - - - -} diff --git a/micro-boot/src/test/java/app/metrics/boot/com/aol/micro/server/MetricsRunnerTest.java b/micro-boot/src/test/java/app/metrics/boot/com/aol/micro/server/MetricsRunnerTest.java deleted file mode 100644 index ec2cca159..000000000 --- a/micro-boot/src/test/java/app/metrics/boot/com/aol/micro/server/MetricsRunnerTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package app.metrics.boot.com.aol.micro.server; - - -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.io.IOException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.boot.config.Microboot; -import com.aol.micro.server.spring.metrics.CodahaleMetricsConfigurer; -import com.aol.micro.server.testing.RestAgent; - -@Microboot -public class MetricsRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - CodahaleMetricsConfigurer.setInit( metricRegistry -> TestReporter - .forRegistry(metricRegistry) - .build() - .start(10, TimeUnit.MILLISECONDS)); - - server = new MicroserverApp( ()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException, IOException{ - - - - - - assertThat(rest.get("http://localhost:8080/simple-app/metrics/ping"),is("ok")); - - - assertThat(TestReporter.getTimer().size(),greaterThan(0)); - } - - - -} diff --git a/micro-boot/src/test/java/app/metrics/boot/com/aol/micro/server/MetricsStatusResource.java b/micro-boot/src/test/java/app/metrics/boot/com/aol/micro/server/MetricsStatusResource.java deleted file mode 100644 index 48bd138ee..000000000 --- a/micro-boot/src/test/java/app/metrics/boot/com/aol/micro/server/MetricsStatusResource.java +++ /dev/null @@ -1,28 +0,0 @@ -package app.metrics.boot.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - - - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/metrics") -public class MetricsStatusResource implements RestResource { - - @Autowired - TimedResource timed; - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - timed.times(); - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/app/metrics/boot/com/aol/micro/server/TestReporter.java b/micro-boot/src/test/java/app/metrics/boot/com/aol/micro/server/TestReporter.java deleted file mode 100644 index a75b93ca4..000000000 --- a/micro-boot/src/test/java/app/metrics/boot/com/aol/micro/server/TestReporter.java +++ /dev/null @@ -1,169 +0,0 @@ -package app.metrics.boot.com.aol.micro.server; - -import java.io.PrintStream; -import java.util.Locale; -import java.util.SortedMap; -import java.util.TimeZone; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - -import lombok.Getter; - -import com.codahale.metrics.Clock; -import com.codahale.metrics.ConsoleReporter; -import com.codahale.metrics.Counter; -import com.codahale.metrics.Gauge; -import com.codahale.metrics.Histogram; -import com.codahale.metrics.Meter; -import com.codahale.metrics.MetricFilter; -import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.ScheduledReporter; -import com.codahale.metrics.Timer; - - -public class TestReporter extends ScheduledReporter { - - @Getter - private static volatile SortedMap timer = new TreeMap<>(); - - protected TestReporter(MetricRegistry registry, String name, - MetricFilter filter, TimeUnit rateUnit, TimeUnit durationUnit) { - super(registry, name, filter, rateUnit, durationUnit); - - } - - - public static Builder forRegistry(MetricRegistry registry) { - return new Builder(registry); - } - - @Override - public void report(SortedMap gauges, - SortedMap counters, - SortedMap histograms, - SortedMap meters, SortedMap timers) { - this.timer = timers; - - - } - - public static class Builder { - private final MetricRegistry registry; - private PrintStream output; - private Locale locale; - private Clock clock; - private TimeZone timeZone; - private TimeUnit rateUnit; - private TimeUnit durationUnit; - private MetricFilter filter; - - private Builder(MetricRegistry registry) { - this.registry = registry; - this.output = System.out; - this.locale = Locale.getDefault(); - this.clock = Clock.defaultClock(); - this.timeZone = TimeZone.getDefault(); - this.rateUnit = TimeUnit.SECONDS; - this.durationUnit = TimeUnit.MILLISECONDS; - this.filter = MetricFilter.ALL; - } - - /** - * Write to the given {@link PrintStream}. - * - * @param output a {@link PrintStream} instance. - * @return {@code this} - */ - public Builder outputTo(PrintStream output) { - this.output = output; - return this; - } - - /** - * Format numbers for the given {@link Locale}. - * - * @param locale a {@link Locale} - * @return {@code this} - */ - public Builder formattedFor(Locale locale) { - this.locale = locale; - return this; - } - - /** - * Use the given {@link Clock} instance for the time. - * - * @param clock a {@link Clock} instance - * @return {@code this} - */ - public Builder withClock(Clock clock) { - this.clock = clock; - return this; - } - - /** - * Use the given {@link TimeZone} for the time. - * - * @param timeZone a {@link TimeZone} - * @return {@code this} - */ - public Builder formattedFor(TimeZone timeZone) { - this.timeZone = timeZone; - return this; - } - - /** - * Convert rates to the given time unit. - * - * @param rateUnit a unit of time - * @return {@code this} - */ - public Builder convertRatesTo(TimeUnit rateUnit) { - this.rateUnit = rateUnit; - return this; - } - - /** - * Convert durations to the given time unit. - * - * @param durationUnit a unit of time - * @return {@code this} - */ - public Builder convertDurationsTo(TimeUnit durationUnit) { - this.durationUnit = durationUnit; - return this; - } - - /** - * Only report metrics which match the given filter. - * - * @param filter a {@link MetricFilter} - * @return {@code this} - */ - public Builder filter(MetricFilter filter) { - this.filter = filter; - return this; - } - - /** - * Builds a {@link ConsoleReporter} with the given properties. - * - * @return a {@link ConsoleReporter} - */ - public TestReporter build() { - return new TestReporter(registry, - // output, - "name", - // locale, - // clock, - // timeZone, - this.filter, - rateUnit, - durationUnit - ); - } - } - - -} - diff --git a/micro-boot/src/test/java/app/metrics/boot/com/aol/micro/server/TimedResource.java b/micro-boot/src/test/java/app/metrics/boot/com/aol/micro/server/TimedResource.java deleted file mode 100644 index af197479b..000000000 --- a/micro-boot/src/test/java/app/metrics/boot/com/aol/micro/server/TimedResource.java +++ /dev/null @@ -1,17 +0,0 @@ -package app.metrics.boot.com.aol.micro.server; - -import org.springframework.stereotype.Component; - -import com.codahale.metrics.annotation.Timed; -import com.ryantenney.metrics.annotation.Counted; - -@Component -public class TimedResource { - - - @Timed - public String times(){ - - return "ok!"; - } -} diff --git a/micro-boot/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java b/micro-boot/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java deleted file mode 100644 index 2ddc53508..000000000 --- a/micro-boot/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package app.minimal.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.testing.RestAgent; - -@Rest -@Path("/single") -public class MinimalClassTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "minimal-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok1")); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok1"; - } - - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/app/rest/client/com/aol/micro/server/GenericRestClientResource.java b/micro-boot/src/test/java/app/rest/client/com/aol/micro/server/GenericRestClientResource.java deleted file mode 100644 index 8aa6fdec9..000000000 --- a/micro-boot/src/test/java/app/rest/client/com/aol/micro/server/GenericRestClientResource.java +++ /dev/null @@ -1,56 +0,0 @@ -package app.rest.client.com.aol.micro.server; - -import java.util.List; - -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -@Component -@Path("/rest") -public class GenericRestClientResource implements RestResource { - - - @GET - @Produces("application/json") - @Path("/get") - public List get() { - - return ImmutableList.of("ok"); - } - - @POST - @Produces("application/json") - @Path("/post") - public ImmutableSet post(ImmutableMap map) { - - return ImmutableSet.copyOf(map.values()); - } - - @PUT - @Produces("application/json") - @Path("/put") - public ImmutableSet put(ImmutableMap map) { - - return ImmutableSet.copyOf(map.values()); - } - @DELETE - @Produces("application/json") - @Path("/delete") - public List delete(ImmutableMap map) { - - return ImmutableList.of("ok"); - } - - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/app/rest/client/com/aol/micro/server/MyEntity.java b/micro-boot/src/test/java/app/rest/client/com/aol/micro/server/MyEntity.java deleted file mode 100644 index 1d2fa9b71..000000000 --- a/micro-boot/src/test/java/app/rest/client/com/aol/micro/server/MyEntity.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.rest.client.com.aol.micro.server; - -import lombok.EqualsAndHashCode; -import lombok.Getter; - -@EqualsAndHashCode -@Getter -public class MyEntity { - - private final String name ="myEntity"; - -} diff --git a/micro-boot/src/test/java/app/rest/client/com/aol/micro/server/RestClientResource.java b/micro-boot/src/test/java/app/rest/client/com/aol/micro/server/RestClientResource.java deleted file mode 100644 index c784b47d7..000000000 --- a/micro-boot/src/test/java/app/rest/client/com/aol/micro/server/RestClientResource.java +++ /dev/null @@ -1,54 +0,0 @@ -package app.rest.client.com.aol.micro.server; - -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -@Component -@Path("/generics") -public class RestClientResource implements RestResource { - - private final ImmutableList result = ImmutableList.of(new MyEntity()); - @GET - @Produces("application/json") - @Path("/get") - public ImmutableList get() { - - return result; - } - - @POST - @Produces("application/json") - @Path("/post") - public ImmutableList post(ImmutableMap map) { - - return result; - } - - @PUT - @Produces("application/json") - @Path("/put") - public ImmutableList put(ImmutableMap map) { - - return result; - } - @DELETE - @Produces("application/json") - @Path("/delete") - public ImmutableList delete(ImmutableMap map) { - - return result; - } - - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/app/rest/client/com/aol/micro/server/RestClientTest.java b/micro-boot/src/test/java/app/rest/client/com/aol/micro/server/RestClientTest.java deleted file mode 100644 index 52d925a6e..000000000 --- a/micro-boot/src/test/java/app/rest/client/com/aol/micro/server/RestClientTest.java +++ /dev/null @@ -1,115 +0,0 @@ - -package app.rest.client.com.aol.micro.server; - - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.List; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.web.client.RestClientException; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.boot.config.Microboot; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.rest.client.nio.NIORestClient; -import com.aol.micro.server.rest.client.nio.SpringConfig; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -@Microserver @Microboot -public class RestClientTest { - - private final AsyncRestClient> listClient = new AsyncRestClient(1000,1000).withResponse(List.class); - private final AsyncRestClient> setClient = new AsyncRestClient(1000,1000).withResponse(ImmutableSet.class);; - private final AsyncRestClient> genericsClient = new AsyncRestClient(1000,1000).withGenericResponse(ImmutableList.class, MyEntity.class); - - private final NIORestClient rest = new SpringConfig().restClient(); - - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( RestClientTest.class, ()-> "rest-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - /* - * Simpler with JaxRsNIOClient - */ - @Test - public void testCRUD() throws InterruptedException, ExecutionException{ - - - assertThat(listClient.get("http://localhost:8080/rest-app/rest/get").get().get(0),is("ok")); - assertThat(setClient.post("http://localhost:8080/rest-app/rest/post",ImmutableMap.of(1,"hello")).get(),is(ImmutableSet.of("hello"))); - assertThat(setClient.put("http://localhost:8080/rest-app/rest/put",ImmutableMap.of(1,"hello")).get(),is(ImmutableSet.of("hello"))); - assertThat(listClient.delete("http://localhost:8080/rest-app/rest/delete").get().get(0),is("ok")); - } - - @Test - public void testCRUDGenerics() throws InterruptedException, ExecutionException{ - - - assertThat(genericsClient.get("http://localhost:8080/rest-app/generics/get").get().get(0),is(new MyEntity())); - assertThat(genericsClient.post("http://localhost:8080/rest-app/generics/post",ImmutableMap.of(1,"hello")).get(),is(ImmutableList.of(new MyEntity()))); - assertThat(genericsClient.put("http://localhost:8080/rest-app/generics/put",ImmutableMap.of(1,"hello")).get(),is(ImmutableList.of(new MyEntity()))); - assertThat(genericsClient.delete("http://localhost:8080/rest-app/generics/delete").get().get(0),is(new MyEntity())); - } - - /** - * More complex with Spring REST Template Based NIORestTemplate - * - */ - - @Test - public void testCRUDSpring() throws InterruptedException, ExecutionException, RestClientException, URISyntaxException{ - - - assertThat(rest.getForEntity(new URI("http://localhost:8080/rest-app/rest/get"),List.class).get().getBody().get(0),is("ok")); - - assertThat(rest.postForEntity("http://localhost:8080/rest-app/rest/post", new HttpEntity(ImmutableMap.of(1,"hello")), ImmutableSet.class).get().getBody(),is(ImmutableSet.of("hello"))); - assertThat( rest.put("http://localhost:8080/rest-app/rest/put",new HttpEntity(ImmutableMap.of(1,"hello")),ImmutableSet.class).get() - ,is(nullValue())); - assertThat(rest.delete("http://localhost:8080/rest-app/rest/delete").get(),is(nullValue())); - } - - @Test - public void testCRUDGenericsSpring() throws InterruptedException, ExecutionException{ - - - assertThat(rest.exchange("http://localhost:8080/rest-app/generics/get",HttpMethod.GET,null,new ParameterizedTypeReference>(){}) - .get().getBody().get(0),is(new MyEntity())); - - assertThat(rest.exchange("http://localhost:8080/rest-app/generics/post",HttpMethod.POST,new HttpEntity(ImmutableMap.of(1,"hello")),new ParameterizedTypeReference>(){}) - .get().getBody(),is(ImmutableList.of(new MyEntity()))); - - assertThat(rest.exchange("http://localhost:8080/rest-app/generics/put",HttpMethod.PUT,new HttpEntity(ImmutableMap.of(1,"hello")),new ParameterizedTypeReference>(){}) - .get().getBody(),is(ImmutableList.of(new MyEntity()))); - - assertThat(rest.exchange("http://localhost:8080/rest-app/generics/delete",HttpMethod.DELETE,null,new ParameterizedTypeReference>(){}) - .get().getBody().get(0),is(new MyEntity())); - - } - - - -} diff --git a/micro-boot/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java b/micro-boot/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java deleted file mode 100644 index b447491a1..000000000 --- a/micro-boot/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java +++ /dev/null @@ -1,20 +0,0 @@ -package app.servlet.com.aol.micro.server; - - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import com.aol.micro.server.MicroserverApp; - -@Configuration -@ComponentScan(basePackages = { "app.servlet.com.aol.micro.server" }) -public class AppRunnerLocalMain { - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( AppRunnerLocalMain.class, () -> "test-app") - .run(); - } - -} diff --git a/micro-boot/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java b/micro-boot/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java deleted file mode 100644 index d0123c905..000000000 --- a/micro-boot/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java +++ /dev/null @@ -1,30 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.ServletConfiguration; - -@Component -public class AutodiscoveredServlet extends HttpServlet implements ServletConfiguration { - - @Override - public String[] getMapping() { - return new String[] { "/servlet" }; - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - resp.setContentType("text/html"); - resp.getWriter().write("hello world"); - } - -} diff --git a/micro-boot/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java b/micro-boot/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java deleted file mode 100644 index 92577a92e..000000000 --- a/micro-boot/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class ConfiguredServlet extends HttpServlet { - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - resp.setContentType("text/html"); - resp.getWriter().write("configured servlet"); - } - - - -} diff --git a/micro-boot/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java b/micro-boot/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java deleted file mode 100644 index aa6e20b4f..000000000 --- a/micro-boot/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package app.servlet.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ExecutionException; - -import javax.servlet.Servlet; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -public class ServletRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - Map servlets = new HashMap<>(); - servlets.put("/configured", new ConfiguredServlet()); - server = new MicroserverApp( AppRunnerLocalMain.class, ConfigurableModule.builder().context("test-app").servlets(servlets ).build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/test-app/servlet/ping"),is("ok")); - - } - - @Test - public void autoDiscoveredServletTest() throws InterruptedException, ExecutionException{ - - - assertThat(rest.get("http://localhost:8080/servlet"),is("hello world")); - - } - - @Test - public void configuredServletTest() throws InterruptedException, ExecutionException{ - - - assertThat(rest.get("http://localhost:8080/configured"),is("configured servlet")); - - } - - -} diff --git a/micro-boot/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java b/micro-boot/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java deleted file mode 100644 index 890a64679..000000000 --- a/micro-boot/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/servlet") -public class ServletStatusResource implements RestResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java b/micro-boot/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java deleted file mode 100644 index 77d4f7595..000000000 --- a/micro-boot/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package app.simple.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.boot.config.Microboot; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Microserver @Microboot -public class SimpleRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( SimpleRunnerTest.class, ()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); - - - } - - - -} diff --git a/micro-boot/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java b/micro-boot/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java deleted file mode 100644 index 0093fe138..000000000 --- a/micro-boot/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java +++ /dev/null @@ -1,28 +0,0 @@ -package app.simple.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Qualifier("simpleStatusResource") -@Path("/status") -public class SimpleStatusResource implements RestResource { - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java b/micro-boot/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java deleted file mode 100644 index cd8720d48..000000000 --- a/micro-boot/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package app.single.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -@Path("/single") -@Ignore -public class SingleClassTest implements RestResource{ - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( ()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/single/ping"),is("ok")); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java b/micro-boot/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java deleted file mode 100644 index 1d544a1cf..000000000 --- a/micro-boot/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java +++ /dev/null @@ -1,30 +0,0 @@ -package app.single.main.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.Ignore; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.MicroserverApp; - -@Configuration -@ComponentScan(basePackages = { "app.simple.com.aol.micro.server" }) -@Component -@Path("/status") @Ignore -public class SingleClassApp { - - public static void main(String[] args){ - new MicroserverApp( SingleClassApp.class, ()-> "simple-app"); - } - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} diff --git a/micro-boot/src/test/java/app/spring/com/aol/micro/server/MyBean.java b/micro-boot/src/test/java/app/spring/com/aol/micro/server/MyBean.java deleted file mode 100644 index 1f7a589ff..000000000 --- a/micro-boot/src/test/java/app/spring/com/aol/micro/server/MyBean.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.spring.com.aol.micro.server; - -import javax.inject.Inject; - -import lombok.Getter; - -@Getter -public class MyBean { - - @Inject - private MyDependency injected; -} diff --git a/micro-boot/src/test/java/app/spring/com/aol/micro/server/MyDependency.java b/micro-boot/src/test/java/app/spring/com/aol/micro/server/MyDependency.java deleted file mode 100644 index 48d89e6c5..000000000 --- a/micro-boot/src/test/java/app/spring/com/aol/micro/server/MyDependency.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.spring.com.aol.micro.server; - -import lombok.Getter; - -import org.springframework.stereotype.Component; - -@Component -@Getter -public class MyDependency { - - private String data = "hello world"; -} diff --git a/micro-boot/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java b/micro-boot/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java deleted file mode 100644 index 9bedc885f..000000000 --- a/micro-boot/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.spring.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.context.annotation.Bean; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.boot.config.Microboot; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; -/**@Configuration -@ComponentScan(basePackages = { "app.spring.com.aol.micro.server" })**/ -@Microserver @Microboot -public class SpringRunnerTest { - - RestAgent rest = new RestAgent(); - - @Bean - public MyBean mybean(){ - return new MyBean(); - } - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( SpringRunnerTest.class, ()-> "spring-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testAutoWiring() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/spring-app/spring/ping"),is("hello world")); - - } - - - - - -} diff --git a/micro-boot/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java b/micro-boot/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java deleted file mode 100644 index 331ac997e..000000000 --- a/micro-boot/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java +++ /dev/null @@ -1,32 +0,0 @@ -package app.spring.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/spring") -public class SpringStatusResource implements RestResource { - - @Autowired - private MyBean mybean; - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return mybean.getInjected().getData(); - } - @GET - @Produces("text/plain") - @Path("/ping2") - public String ping2() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/app/spring/mvc/Application.java b/micro-boot/src/test/java/app/spring/mvc/Application.java new file mode 100644 index 000000000..46d261f76 --- /dev/null +++ b/micro-boot/src/test/java/app/spring/mvc/Application.java @@ -0,0 +1,32 @@ +package app.spring.mvc; +import java.util.concurrent.ExecutionException; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.boot.MicroBoot; +import org.junit.Test; +import org.springframework.context.ConfigurableApplicationContext; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +@Microserver +@MicroBoot +public class Application { + + + AsyncRestClient rest = new AsyncRestClient(1000,1000).withAccept("text/plain"); + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + MicroserverApp app = new MicroserverApp( ()-> "spring-mvc"); + Thread.sleep(2000); + + assertThat(rest.get("http://localhost:8080/spring-mvc").get(),is("Greetings from Spring Boot with Microserver!")); + ((ConfigurableApplicationContext)app.getSpringContext()).close(); + } + + +} diff --git a/micro-boot/src/test/java/app/spring/mvc/HelloController.java b/micro-boot/src/test/java/app/spring/mvc/HelloController.java new file mode 100644 index 000000000..34136b6e9 --- /dev/null +++ b/micro-boot/src/test/java/app/spring/mvc/HelloController.java @@ -0,0 +1,15 @@ +package app.spring.mvc; + + +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RequestMapping; + +@RestController +public class HelloController { + + @RequestMapping("/") + public String index() { + return "Greetings from Spring Boot with Microserver!"; + } + +} diff --git a/micro-boot/src/test/java/app/spring/plugin/RegistryController.java b/micro-boot/src/test/java/app/spring/plugin/RegistryController.java new file mode 100644 index 000000000..cafd4e139 --- /dev/null +++ b/micro-boot/src/test/java/app/spring/plugin/RegistryController.java @@ -0,0 +1,30 @@ +package app.spring.plugin; + + +import com.oath.micro.server.application.registry.Job; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class RegistryController { + + private final Job job; + + @Autowired + public RegistryController(Job job){ + this.job = job; + } + + @RequestMapping("/") + public String index() { + return "Greetings from Spring Boot with Microserver!"; + } + + @RequestMapping("/scheduled") + public String scheduled() { + return ""+job.getScheduled(); + } + +} diff --git a/micro-boot/src/test/java/app/spring/plugin/RegistryTest.java b/micro-boot/src/test/java/app/spring/plugin/RegistryTest.java new file mode 100644 index 000000000..370635b89 --- /dev/null +++ b/micro-boot/src/test/java/app/spring/plugin/RegistryTest.java @@ -0,0 +1,37 @@ +package app.spring.plugin; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.boot.MicroBoot; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import org.junit.Test; +import org.springframework.context.ConfigurableApplicationContext; + +import java.util.concurrent.ExecutionException; + + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertThat; + +@Microserver +@MicroBoot +public class RegistryTest { + + + AsyncRestClient rest = new AsyncRestClient(1000,1000).withAccept("text/plain"); + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + MicroserverApp app = new MicroserverApp( ()-> "spring-mvc"); + Thread.sleep(3000); + + assertThat(rest.get("http://localhost:8080/spring-mvc/scheduled").get(),is(not("0"))); + + ((ConfigurableApplicationContext)app.getSpringContext()).close(); + + } + + +} diff --git a/micro-boot/src/test/java/app/swagger/com/aol/micro/server/StatsResource.java b/micro-boot/src/test/java/app/swagger/com/aol/micro/server/StatsResource.java deleted file mode 100644 index 3d3516a41..000000000 --- a/micro-boot/src/test/java/app/swagger/com/aol/micro/server/StatsResource.java +++ /dev/null @@ -1,31 +0,0 @@ -package app.swagger.com.aol.micro.server; - -import java.util.List; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -import com.google.common.collect.ImmutableList; -import com.wordnik.swagger.annotations.Api; -import com.wordnik.swagger.annotations.ApiOperation; - - -@Path("/stats") -@Component -@Api(value = "/stats", description = "Resource to show stats for a box using sigar") -public class StatsResource implements RestResource { - - - - @GET - @Path("/ping") - @Produces("application/json") - @ApiOperation(value = "Make a ping call", response = List.class) - public List getMachineStats() { - return ImmutableList.of(1); - } -} diff --git a/micro-boot/src/test/java/app/swagger/com/aol/micro/server/SwaggerRunnerTest.java b/micro-boot/src/test/java/app/swagger/com/aol/micro/server/SwaggerRunnerTest.java deleted file mode 100644 index 2f05228b3..000000000 --- a/micro-boot/src/test/java/app/swagger/com/aol/micro/server/SwaggerRunnerTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package app.swagger.com.aol.micro.server; - -import static org.hamcrest.Matchers.containsString; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.testing.RestAgent; - -@Configuration -@ComponentScan(basePackages = { "app.swagger.com.aol.micro.server" }) -public class SwaggerRunnerTest { - - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( SwaggerRunnerTest.class, ()-> "swagger-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.getJson("http://localhost:8080/api-docs/stats"),containsString("Make a ping call")); - - } - - - -} diff --git a/micro-boot/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-boot/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-boot/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-boot/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-boot/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-boot/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-boot/src/test/java/nonautoscan/com/aol/micro/server/ConfiguredListener.java b/micro-boot/src/test/java/nonautoscan/com/aol/micro/server/ConfiguredListener.java deleted file mode 100644 index d15010390..000000000 --- a/micro-boot/src/test/java/nonautoscan/com/aol/micro/server/ConfiguredListener.java +++ /dev/null @@ -1,25 +0,0 @@ -package nonautoscan.com.aol.micro.server; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import lombok.Getter; - -public class ConfiguredListener implements ServletContextListener { - - @Getter - private static volatile int called= 0; - - @Override - public void contextInitialized(ServletContextEvent sce) { - called ++; - - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - - - } - -} \ No newline at end of file diff --git a/micro-boot/src/test/java/nonautoscan/com/aol/micro/server/PropertyFileConfigTest.java b/micro-boot/src/test/java/nonautoscan/com/aol/micro/server/PropertyFileConfigTest.java deleted file mode 100644 index 71f038db3..000000000 --- a/micro-boot/src/test/java/nonautoscan/com/aol/micro/server/PropertyFileConfigTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package nonautoscan.com.aol.micro.server; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; - -import java.io.IOException; - -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.config.Config; -import com.aol.micro.server.spring.properties.PropertyFileConfig; -public class PropertyFileConfigTest { - - - - - - PropertyFileConfig config; - @Before - public void setUp() { - config = new PropertyFileConfig(); - } - - @Test - public void testPropertyPlaceholderConfigurer() throws IOException { - Config.instance(); - assertThat( config.propertyPlaceholderConfigurer(),notNullValue()); - } - - - -} diff --git a/micro-boot/src/test/java/nonautoscan/com/aol/micro/server/ScheduleAndAsyncConfigTest.groovy b/micro-boot/src/test/java/nonautoscan/com/aol/micro/server/ScheduleAndAsyncConfigTest.groovy deleted file mode 100644 index 071c36e08..000000000 --- a/micro-boot/src/test/java/nonautoscan/com/aol/micro/server/ScheduleAndAsyncConfigTest.groovy +++ /dev/null @@ -1,56 +0,0 @@ -package nonautoscan.com.aol.micro.server - -import static org.junit.Assert.* -import groovy.transform.CompileStatic - -import org.junit.Before -import org.junit.Test -import org.mockito.Mockito -import org.springframework.scheduling.config.ScheduledTaskRegistrar -@CompileStatic -class ScheduleAndAsyncConfigTest { - - - ScheduleAndAsyncConfig config - @Before - public void setup(){ - config = new ScheduleAndAsyncConfig() - config.schedulerThreadPoolSize=3 - config.executorThreadPoolSize=3 - } - @Test - public void testSetExecutorThreadPoolSize() { - assert config.@executorThreadPoolSize==3 - } - - @Test - public void testSetSchedulerThreadPoolSize() { - - assert config.@schedulerThreadPoolSize==3 - } - - @Test - public void testGetAsyncExecutor() { - assert config.asyncExecutor !=null - } - - @Test - public void testConfigureTasks() { - ScheduledTaskRegistrar mock = Mockito.mock(ScheduledTaskRegistrar) - config.configureTasks(mock) - Mockito.verify(mock).setScheduler(Mockito.anyObject()) - } - - @Test - public void testTaskScheduler() { - assert config.taskScheduler()!=null - } - - @Test - public void testTaskExecutor() { - assert config.taskExecutor() != null - } - - - -} \ No newline at end of file diff --git a/micro-boot/src/test/resources/META-INF/MANIFEST.MF b/micro-boot/src/test/resources/META-INF/MANIFEST.MF new file mode 100644 index 000000000..b614b3f50 --- /dev/null +++ b/micro-boot/src/test/resources/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +Created-By: 1.7.0_06 (Oracle Corporation) \ No newline at end of file diff --git a/micro-client/README.md b/micro-client/README.md new file mode 100644 index 000000000..b222fdf65 --- /dev/null +++ b/micro-client/README.md @@ -0,0 +1,142 @@ +# REST client plugin for Microserver + +[micro-client example apps](https://github.com/aol/micro-server/tree/master/micro-client/src/test/java/app) + +This plugin provides thre REST Clients + +1. NIORestClient - which is a non-blocking REST client using NIO, wrapper over Apache Async HTTP. Modified to return Java 8 CompletableFuture objects. +2. AsyncRestClient - a wrapper over the Async Jersey Rest Client (it is asyncrhonous, but makes use of threads rather than NIO). Modified to return Java 8 CompletableFuture objects, and enhanced with withXXXX methods for configuration purposes. +3. RestClient - which syncrhonous wrapper over the Jersey Rest Client, enhanced with withXXXX methods for configuration purposes + +The NIORestClient is available as Spring bean. AsyncRestClient & RestClient can simply be instantiated via the new keyword. + +## Example AsyncRestClient + ```java +public class Example{ + + + private final int readTimeout = 10_000; + private final int connnectionTimeout = 1_000; + private final AsyncRestClient restClient = new AsyncRestClient<>(readTimeout,connectionTimeout);; + private final String url; + private final String ACCEPT_HEADERS; + private final String CONTENT_HEADERS; + + public CompletableFuture query(Payload payload){ + + return this.restClient.withAccept(ACCEPT_HEADERS) + .withContentType(CONTENT_HEADERS) + .withResponse(RESULT.class) + .post(url,payload); + + } + + +} +``` + +## Example NIORestClient + +Example using simple-react to manage the returned CompletableFuture object from the NIO Rest Client. + + ```java +@Path("/query") +@Rest +public class EndPoint { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final EventBus bus; + private final NIORestClient restClient; + private final String URL; + @Autowired + public EndPoint(NIORestClient restClient,EventBus bus, @Value("${url:}") String URL){ + + this.bus = bus; + this.URL = URL; + this.restClient=restClient; + } + + private final SimpleReact builder = new SimpleReact(); + + + + @POST + @Consumes("application/json") + @Produces("application/json") + public void async(RequestType query,@Suspended AsyncResponse asyncResponse){ + + + final String correlationId = UUID.randomUUID().toString(); + bus.post(RequestEvents.start(query, correlationId,"standard-query",HashMapBuilder.of("ip",QueryIPRetriever.getIpAddress()))); + builder.from(this.restClient.postForEntity(URL, new HttpEntity(JacksonUtil.serializeToJson(convertList(query)),headers),String.class)) + .sync() + .capture(e->logger.error(e.getMessage(), e)) + .then(re-> JacksonUtil.convertFromJson(re.getBody(), Result.class)) + .then(this::process) + .then(action->asyncResponse.resume(action)) + .onFail(error-> asyncResponse.resume(error.getCause())) + .peek( status->bus.post(RequestEvents.finish(query, correlationId))); + + + + } +} +``` +## Example RestClient +```java +public class Example{ + + + private final int readTimeout = 10_000; + private final int connnectionTimeout = 1_000; + private final RestClient restClient = new RestClient<>(readTimeout,connectionTimeout); + private final String url; + private final String ACCEPT_HEADERS; + private final String CONTENT_HEADERS; + + public Result query(Payload payload){ + + return this.restClient.withAccept(ACCEPT_HEADERS) + .withContentType(CONTENT_HEADERS) + .withResponse(RESULT.class) + .post(url,payload); + + } + + +} +``` + +## Configuring the NIORestClient + +The following properties & defaults are available to set values on the underlying Apache Async Http Client. + +Set the timeout in milliseconds used when requesting a connection from the connection manager using the underlying HttpClient. A timeout value of 0 specifies an infinite timeout. + + nio.rest.connection.request.timeout=10000 + +Set the socket read timeout for the underlying HttpClient in millis. A timeout value of 0 specifies an infinite timeout. + + nio.rest.connection.read.timeout=0 + +The connection timeout for the underlying HttpClient in millis. A timeout value of 0 specifies an infinite timeout. + + nio.rest.connection.connect.timeout:2000 + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-client/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-client) + +Simply add to the classpath + +Maven + + + com.oath.microservices + micro-client + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-client:x.yz' diff --git a/micro-client/build.gradle b/micro-client/build.gradle index c083cc2d5..1f5821be9 100644 --- a/micro-client/build.gradle +++ b/micro-client/build.gradle @@ -1,67 +1,65 @@ description = 'micro-client' + dependencies { - - - compile group: 'org.glassfish.jersey.core', name: 'jersey-client', version:"$jerseyVersion" - compile group: 'org.apache.httpcomponents', name:'httpclient', version:apacheHttpClientVersion - compile group: 'org.apache.httpcomponents', name:'httpasyncclient', version:apacheHttpClientVersionAsync - - compile project(':micro-core') - compile project(':micro-jackson-configuration') - testCompile group: 'org.hamcrest', name: 'hamcrest-all', version:hamcrestVersion - testCompile group: 'com.google.guava', name: 'guava', version:guavaVersion - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') - testCompile project(':micro-events') - + compile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: "$jerseyVersion" + compile group: 'org.apache.httpcomponents', name: 'httpclient', version: apacheHttpClientVersion + compile group: 'org.apache.httpcomponents', name: 'httpasyncclient', version: apacheHttpClientVersionAsync + compile project(':micro-core') + compile project(':micro-jackson-configuration') + testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: hamcrestVersion + testCompile group: 'com.google.guava', name: 'guava', version: guavaVersion + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') + testCompile project(':micro-events') + testCompile "com.oath.cyclops:cyclops-futurestream:$cyclopsVersion" } modifyPom { - project { - name 'Microserver client' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver client' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-client' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } - groupId 'com.aol.microservices' - artifactId 'micro-client' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - } - - } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-client/readme.md b/micro-client/readme.md deleted file mode 100644 index 32ed22744..000000000 --- a/micro-client/readme.md +++ /dev/null @@ -1,143 +0,0 @@ -# REST client plugin for Microserver - -[micro-client example apps](https://github.com/aol/micro-server/tree/master/micro-client/src/test/java/app) - -This plugin provides thre REST Clients - -1. NIORestClient - which is a non-blocking REST client using NIO, wrapper over Apache Async HTTP. Modified to return Java 8 CompletableFuture objects. -2. AsyncRestClient - a wrapper over the Async Jersey Rest Client (it is asyncrhonous, but makes use of threads rather than NIO). Modified to return Java 8 CompletableFuture objects, and enhanced with withXXXX methods for configuration purposes. -3. RestClient - which syncrhonous wrapper over the Jersey Rest Client, enhanced with withXXXX methods for configuration purposes - -The NIORestClient is available as Spring bean. AsyncRestClient & RestClient can simply be instantiated via the new keyword. - -## Example AsyncRestClient - ```java -public class Example{ - - - private final int readTimeout = 10_000; - private final int connnectionTimeout = 1_000; - private final AsyncRestClient restClient = new AsyncRestClient<>(readTimeout,connectionTimeout);; - private final String url; - private final String ACCEPT_HEADERS; - private final String CONTENT_HEADERS; - - public CompletableFuture query(Payload payload){ - - return this.restClient.withAccept(ACCEPT_HEADERS) - .withContentType(CONTENT_HEADERS) - .withResponse(RESULT.class) - .post(url,payload); - - } - - -} -``` - -## Example NIORestClient - -Example using simple-react to manage the returned CompletableFuture object from the NIO Rest Client. - - ```java -@Path("/query") -@Rest -public class EndPoint { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final EventBus bus; - private final NIORestClient restClient; - private final String URL; - private final AtomicLong correlationId = new AtomicLong(0); - @Autowired - public EndPoint(NIORestClient restClient,EventBus bus, @Value("${url:}") String URL){ - - this.bus = bus; - this.URL = URL; - this.restClient=restClient; - } - - private final SimpleReact builder = new SimpleReact(); - - - - @POST - @Consumes("application/json") - @Produces("application/json") - public void async(RequestType query,@Suspended AsyncResponse asyncResponse){ - - - final long correlationId = this.correlationId.incrementAndGet(); - bus.post(RequestEvents.start(query, correlationId,"standard-query",HashMapBuilder.of("ip",QueryIPRetriever.getIpAddress()))); - builder.from(this.restClient.postForEntity(URL, new HttpEntity(JacksonUtil.serializeToJson(convertList(query)),headers),String.class)) - .sync() - .capture(e->logger.error(e.getMessage(), e)) - .then(re-> JacksonUtil.convertFromJson(re.getBody(), Result.class)) - .then(this::process) - .then(action->asyncResponse.resume(action)) - .onFail(error-> asyncResponse.resume(error.getCause())) - .peek( status->bus.post(RequestEvents.finish(query, correlationId))); - - - - } -} -``` -## Example RestClient -```java -public class Example{ - - - private final int readTimeout = 10_000; - private final int connnectionTimeout = 1_000; - private final RestClient restClient = new RestClient<>(readTimeout,connectionTimeout); - private final String url; - private final String ACCEPT_HEADERS; - private final String CONTENT_HEADERS; - - public Result query(Payload payload){ - - return this.restClient.withAccept(ACCEPT_HEADERS) - .withContentType(CONTENT_HEADERS) - .withResponse(RESULT.class) - .post(url,payload); - - } - - -} -``` - -## Configuring the NIORestClient - -The following properties & defaults are available to set values on the underlying Apache Async Http Client. - -Set the timeout in milliseconds used when requesting a connection from the connection manager using the underlying HttpClient. A timeout value of 0 specifies an infinite timeout. - - nio.rest.connection.request.timeout=10000 - -Set the socket read timeout for the underlying HttpClient in millis. A timeout value of 0 specifies an infinite timeout. - - nio.rest.connection.read.timeout=0 - -The connection timeout for the underlying HttpClient in millis. A timeout value of 0 specifies an infinite timeout. - - nio.rest.connection.connect.timeout:2000 - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-client/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-client) - -Simply add to the classpath - -Maven - - - com.aol.microservices - micro-client - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-client:x.yz' diff --git a/micro-client/src/main/java/com/aol/micro/server/rest/client/nio/ClientPlugin.java b/micro-client/src/main/java/com/aol/micro/server/rest/client/nio/ClientPlugin.java deleted file mode 100644 index 54c70538d..000000000 --- a/micro-client/src/main/java/com/aol/micro/server/rest/client/nio/ClientPlugin.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.aol.micro.server.rest.client.nio; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; - -/** - * - * @author johnmcclean - * - */ -public class ClientPlugin implements Plugin{ - - @Override - public PSetX springClasses() { - return PSetX.of(SpringConfig.class); - } - - - -} diff --git a/micro-client/src/main/java/com/aol/micro/server/rest/client/RestClient.java b/micro-client/src/main/java/com/oath/micro/server/rest/client/RestClient.java similarity index 88% rename from micro-client/src/main/java/com/aol/micro/server/rest/client/RestClient.java rename to micro-client/src/main/java/com/oath/micro/server/rest/client/RestClient.java index 58a6af402..5299f8436 100644 --- a/micro-client/src/main/java/com/aol/micro/server/rest/client/RestClient.java +++ b/micro-client/src/main/java/com/oath/micro/server/rest/client/RestClient.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.rest.client; +package com.oath.micro.server.rest.client; import java.util.concurrent.CompletableFuture; @@ -16,25 +16,34 @@ import org.glassfish.jersey.client.ClientProperties; -import com.aol.micro.server.rest.jackson.JacksonFeature; -import com.aol.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.rest.jackson.JacksonFeature; +import com.oath.micro.server.rest.jackson.JacksonUtil; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; -@Wither + @Builder @AllArgsConstructor public class RestClient { + @Wither private final Client client; + @Wither private final String contentType; + @Wither private final String accept; private final Class response; + @Wither private final JavaType genericResponse; - public RestClient(int readTimeout, int connectTimeout) { + /** + * Create a new rest client. + * @param readTimeoutMillis Read timeout, in milliseconds + * @param connectTimeoutMillis Connect timeout, in milliseconds + */ + public RestClient(int readTimeoutMillis, int connectTimeoutMillis) { - this.client = initClient(readTimeout, connectTimeout); + this.client = initClient(readTimeoutMillis, connectTimeoutMillis); contentType = MediaType.APPLICATION_JSON; accept = MediaType.APPLICATION_JSON; response = (Class) String.class; diff --git a/micro-client/src/main/java/com/aol/micro/server/rest/client/nio/AsyncRestClient.java b/micro-client/src/main/java/com/oath/micro/server/rest/client/nio/AsyncRestClient.java similarity index 96% rename from micro-client/src/main/java/com/aol/micro/server/rest/client/nio/AsyncRestClient.java rename to micro-client/src/main/java/com/oath/micro/server/rest/client/nio/AsyncRestClient.java index 75d1f286b..3d627e58f 100644 --- a/micro-client/src/main/java/com/aol/micro/server/rest/client/nio/AsyncRestClient.java +++ b/micro-client/src/main/java/com/oath/micro/server/rest/client/nio/AsyncRestClient.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.rest.client.nio; +package com.oath.micro.server.rest.client.nio; import java.util.concurrent.CompletableFuture; @@ -16,20 +16,23 @@ import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.client.ClientProperties; -import com.aol.micro.server.rest.jackson.JacksonFeature; -import com.aol.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.rest.jackson.JacksonFeature; +import com.oath.micro.server.rest.jackson.JacksonUtil; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; -@Wither + @Builder @AllArgsConstructor public class AsyncRestClient { - + @Wither private final Client client; + @Wither private final String contentType; + @Wither private final String accept; private final Class response; + @Wither private final JavaType genericResponse; public AsyncRestClient(int readTimeout, int connectTimeout) { diff --git a/micro-client/src/main/java/com/oath/micro/server/rest/client/nio/ClientPlugin.java b/micro-client/src/main/java/com/oath/micro/server/rest/client/nio/ClientPlugin.java new file mode 100644 index 000000000..152079738 --- /dev/null +++ b/micro-client/src/main/java/com/oath/micro/server/rest/client/nio/ClientPlugin.java @@ -0,0 +1,23 @@ +package com.oath.micro.server.rest.client.nio; + + +import com.oath.micro.server.Plugin; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +/** + * + * @author johnmcclean + * + */ +public class ClientPlugin implements Plugin{ + + @Override + public Set springClasses() { + return SetX.of(SpringConfig.class); + } + + + +} diff --git a/micro-client/src/main/java/com/aol/micro/server/rest/client/nio/NIORestClient.java b/micro-client/src/main/java/com/oath/micro/server/rest/client/nio/NIORestClient.java similarity index 98% rename from micro-client/src/main/java/com/aol/micro/server/rest/client/nio/NIORestClient.java rename to micro-client/src/main/java/com/oath/micro/server/rest/client/nio/NIORestClient.java index e154152f6..ed959e16e 100644 --- a/micro-client/src/main/java/com/aol/micro/server/rest/client/nio/NIORestClient.java +++ b/micro-client/src/main/java/com/oath/micro/server/rest/client/nio/NIORestClient.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.rest.client.nio; +package com.oath.micro.server.rest.client.nio; import java.net.URI; @@ -21,7 +21,7 @@ import org.springframework.web.client.ResponseExtractor; import org.springframework.web.client.RestClientException; -import com.aol.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.rest.jackson.JacksonUtil; public class NIORestClient { diff --git a/micro-client/src/main/java/com/aol/micro/server/rest/client/nio/SpringConfig.java b/micro-client/src/main/java/com/oath/micro/server/rest/client/nio/SpringConfig.java similarity index 95% rename from micro-client/src/main/java/com/aol/micro/server/rest/client/nio/SpringConfig.java rename to micro-client/src/main/java/com/oath/micro/server/rest/client/nio/SpringConfig.java index 70d55e197..b4e00906c 100644 --- a/micro-client/src/main/java/com/aol/micro/server/rest/client/nio/SpringConfig.java +++ b/micro-client/src/main/java/com/oath/micro/server/rest/client/nio/SpringConfig.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.rest.client.nio; +package com.oath.micro.server.rest.client.nio; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; diff --git a/micro-client/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-client/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index e9ab7dfa3..000000000 --- a/micro-client/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.rest.client.nio.ClientPlugin \ No newline at end of file diff --git a/micro-client/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-client/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..354098bb6 --- /dev/null +++ b/micro-client/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.rest.client.nio.ClientPlugin \ No newline at end of file diff --git a/micro-client/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java b/micro-client/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java deleted file mode 100644 index 979b5fbf5..000000000 --- a/micro-client/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java +++ /dev/null @@ -1,57 +0,0 @@ -package app.async.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.io.IOException; -import java.util.Properties; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.spring.properties.PropertyFileConfig; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class AsyncAppRunner { - - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( ()-> "async-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - Thread.sleep(2000); - - assertThat(rest.get("http://localhost:8080/async-app/async/expensive"),is(";test!;test!;test!")); - - } - - @Test - public void loadProperties() throws IOException{ - - Properties props = new PropertyFileConfig(true).propertyFactory() ; - assertThat(props.getProperty("test"),is("hello world")); - } - - - -} \ No newline at end of file diff --git a/micro-client/src/test/java/app/async/com/aol/micro/server/AsyncResource.java b/micro-client/src/test/java/app/async/com/aol/micro/server/AsyncResource.java deleted file mode 100644 index 567cde3a4..000000000 --- a/micro-client/src/test/java/app/async/com/aol/micro/server/AsyncResource.java +++ /dev/null @@ -1,57 +0,0 @@ -package app.async.com.aol.micro.server; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.container.Suspended; - -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.LazyReact; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; - -@Path("/async") -@Component -public class AsyncResource implements RestResource{ - - - private final List urls =Arrays.asList("http://localhost:8080/async-app/async/ping2", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping"); - - private final AsyncRestClient client = new AsyncRestClient(100,100).withAccept("text/plain"); - - @GET - @Path("/expensive") - @Produces("text/plain") - public void expensive(@Suspended AsyncResponse asyncResponse){ - - new LazyReact().fromStreamFutures(urls.stream() - .>map(it -> client.get(it))) - .onFail(it -> "") - .peek(it -> - System.out.println(it)) - .convertToSimpleReact() - .allOf(data -> { - System.out.println(data); - return asyncResponse.resume(String.join(";", (List)data)); }) - .convertToLazyStream().run(); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - -} diff --git a/micro-client/src/test/java/app/async/com/aol/micro/server/Simple.java b/micro-client/src/test/java/app/async/com/aol/micro/server/Simple.java deleted file mode 100644 index edefa80ef..000000000 --- a/micro-client/src/test/java/app/async/com/aol/micro/server/Simple.java +++ /dev/null @@ -1,16 +0,0 @@ -package app.async.com.aol.micro.server; - -import java.io.IOException; -import java.util.Properties; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.spring.properties.PropertyFileConfig; - -public class Simple { - - public static void main(String[] args) throws IOException{ - - new MicroserverApp(()->"test-app").run(); - } -} diff --git a/micro-client/src/test/java/app/async/com/aol/micro/server/SimpleApp.java b/micro-client/src/test/java/app/async/com/aol/micro/server/SimpleApp.java deleted file mode 100644 index 919b7c6b0..000000000 --- a/micro-client/src/test/java/app/async/com/aol/micro/server/SimpleApp.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.async.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; - - - -@Rest -@Path("/test") -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()->"test-app").run(); - } - @GET - public String myEndPoint(){ - return "hello world!"; - } - - -} diff --git a/micro-client/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java b/micro-client/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java new file mode 100644 index 000000000..c71dd8184 --- /dev/null +++ b/micro-client/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java @@ -0,0 +1,57 @@ +package app.async.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.Properties; +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.spring.properties.PropertyFileConfig; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class AsyncAppRunner { + + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( ()-> "async-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + Thread.sleep(2000); + + assertThat(rest.get("http://localhost:8080/async-app/async/expensive"),is(";test!;test!;test!")); + + } + + @Test + public void loadProperties() throws IOException{ + + Properties props = new PropertyFileConfig(true).propertyFactory() ; + assertThat(props.getProperty("test"),is("hello world")); + } + + + +} \ No newline at end of file diff --git a/micro-client/src/test/java/app/async/com/oath/micro/server/AsyncResource.java b/micro-client/src/test/java/app/async/com/oath/micro/server/AsyncResource.java new file mode 100644 index 000000000..4a0a995fd --- /dev/null +++ b/micro-client/src/test/java/app/async/com/oath/micro/server/AsyncResource.java @@ -0,0 +1,58 @@ +package app.async.com.oath.micro.server; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; + +import cyclops.futurestream.LazyReact; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; + +@Path("/async") +@Component +public class AsyncResource implements RestResource{ + + + private final List urls =Arrays.asList("http://localhost:8080/async-app/async/ping2", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping"); + + private final AsyncRestClient client = new AsyncRestClient(100,100).withAccept("text/plain"); + + @GET + @Path("/expensive") + @Produces("text/plain") + public void expensive(@Suspended AsyncResponse asyncResponse){ + + new LazyReact().fromStreamFutures(urls.stream() + .>map(it -> client.get(it))) + .onFail(it -> "") + .peek(it -> + System.out.println(it)) + .convertToSimpleReact() + .allOf(data -> { + System.out.println(data); + return asyncResponse.resume(String.join(";", (List)data)); }) + .convertToLazyStream().run(); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "test!"; + } + + +} diff --git a/micro-client/src/test/java/app/async/com/oath/micro/server/Simple.java b/micro-client/src/test/java/app/async/com/oath/micro/server/Simple.java new file mode 100644 index 000000000..3eb3e7504 --- /dev/null +++ b/micro-client/src/test/java/app/async/com/oath/micro/server/Simple.java @@ -0,0 +1,13 @@ +package app.async.com.oath.micro.server; + +import java.io.IOException; + +import com.oath.micro.server.MicroserverApp; + +public class Simple { + + public static void main(String[] args) throws IOException{ + + new MicroserverApp(()->"test-app").run(); + } +} diff --git a/micro-client/src/test/java/app/async/com/oath/micro/server/SimpleApp.java b/micro-client/src/test/java/app/async/com/oath/micro/server/SimpleApp.java new file mode 100644 index 000000000..916d0330e --- /dev/null +++ b/micro-client/src/test/java/app/async/com/oath/micro/server/SimpleApp.java @@ -0,0 +1,24 @@ +package app.async.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; + + + +@Rest +@Path("/test") +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()->"test-app").run(); + } + @GET + public String myEndPoint(){ + return "hello world!"; + } + + +} diff --git a/micro-client/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java b/micro-client/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java deleted file mode 100644 index d4b8eff5c..000000000 --- a/micro-client/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java +++ /dev/null @@ -1,23 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.ArrayList; -import java.util.List; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -@Component -@Path("/alt-status") -public class AltAppResource implements AltAppRestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public List ping(ImmutableEntity entity) { - return entity.getList(); - } - -} diff --git a/micro-client/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java b/micro-client/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java deleted file mode 100644 index 8cb2643e3..000000000 --- a/micro-client/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface AltAppRestResource extends RestResource { - -} diff --git a/micro-client/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java b/micro-client/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java deleted file mode 100644 index 935083a15..000000000 --- a/micro-client/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java +++ /dev/null @@ -1,23 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.EmbeddedModule; - -@Microserver(basePackages = { "app.embedded.com.aol.micro.server" }) -public class EmbeddedAppLocalMain { - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( - EmbeddedModule.tagInterfaceModule(PStackX.of(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(PStackX.of(AltAppRestResource.class),"alternative-app")).start(); - - - - } - - -} diff --git a/micro-client/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java b/micro-client/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java deleted file mode 100644 index e1b70d818..000000000 --- a/micro-client/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java +++ /dev/null @@ -1,104 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.NotFoundException; - -import jersey.repackaged.com.google.common.collect.ImmutableList; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; - -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.EmbeddedModule; -import com.aol.micro.server.testing.RestAgent; - -public class EmbeddedAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer(){ - server = new MicroserverApp(EmbeddedAppLocalMain.class, - EmbeddedModule.tagInterfaceModule(PStackX.of(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(PStackX.of(AltAppRestResource.class),"alternative-app")); - server.start(); - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); - - - assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value",ImmutableList.of("hello","world")),List.class), - hasItem("hello")); - - } - - - @Test - public void nonBlockingRestClientTest(){ - assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"),is("-*test!-*test!")); - } - - CompletableFuture toCompletableFuture( - final ListenableFuture listenableFuture - ) { - //create an instance of CompletableFuture - CompletableFuture completable = new CompletableFuture() { - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - // propagate cancel to the listenable future - boolean result = listenableFuture.cancel(mayInterruptIfRunning); - super.cancel(mayInterruptIfRunning); - return result; - } - }; - - // add callback - listenableFuture.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(T result) { - completable.complete(result); - } - - @Override - public void onFailure(Throwable t) { - completable.completeExceptionally(t); - } - }); - return completable; - } - - @Test(expected=NotFoundException.class) - public void confirmAltAppCantUseTestAppResources(){ - - assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); - - } - @Test(expected=NotFoundException.class) - public void confirmTestAppCantUseAltAppResources(){ - - assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",ImmutableList.of("hello","world")),List.class), - hasItem("hello")); - - } -} diff --git a/micro-client/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java b/micro-client/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java deleted file mode 100644 index 778c55c90..000000000 --- a/micro-client/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java +++ /dev/null @@ -1,29 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableEntity { - - private final String value; - private final List list; - - public ImmutableEntity() { - this(null,null); - } - -} diff --git a/micro-client/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java b/micro-client/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java deleted file mode 100644 index 136c5e920..000000000 --- a/micro-client/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java +++ /dev/null @@ -1,54 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.Arrays; -import java.util.List; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.micro.server.rest.client.nio.NIORestClient; -@Component -@Path("/test-status") -public class TestAppResource implements TestAppRestResource { - - private final SimpleReact simpleReact = new SimpleReact(); - private final NIORestClient template; - private final List urls = Arrays.asList("http://localhost:8081/alternative-app/alt-status/ping", - "http://localhost:8080/test-app/test-status/ping", - "http://localhost:8082/simple-app/status/ping", - "http://localhost:8080/test-app/test-status/ping"); - - @Autowired - public TestAppResource(NIORestClient template) { - - this.template = template; - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - @GET - @Produces("text/plain") - @Path("/rest-calls") - public String restCallResult(){ - - return simpleReact - .fromStream(urls.stream() - .map(it -> template.getForEntity(it,String.class))) - .then(it -> it.getBody()) - .then(it -> "*"+it) - .peek(loadedAndModified -> System.out.println(loadedAndModified)) - .block().stream().reduce("", (acc,next) -> acc+"-"+next); - - } - -} diff --git a/micro-client/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java b/micro-client/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java deleted file mode 100644 index 3133fd8cc..000000000 --- a/micro-client/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface TestAppRestResource extends RestResource { - -} diff --git a/micro-client/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java b/micro-client/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java new file mode 100644 index 000000000..1835ababe --- /dev/null +++ b/micro-client/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java @@ -0,0 +1,22 @@ +package app.embedded.com.oath.micro.server; + +import java.util.List; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +@Component +@Path("/alt-status") +public class AltAppResource implements AltAppRestResource { + + @POST + @Produces("application/json") + @Path("/ping") + public List ping(ImmutableEntity entity) { + return entity.getList(); + } + +} diff --git a/micro-client/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java b/micro-client/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java new file mode 100644 index 000000000..7045a4f35 --- /dev/null +++ b/micro-client/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java @@ -0,0 +1,7 @@ +package app.embedded.com.oath.micro.server; + +import com.oath.micro.server.auto.discovery.RestResource; + +public interface AltAppRestResource extends RestResource { + +} diff --git a/micro-client/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java b/micro-client/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java new file mode 100644 index 000000000..13d30e1d4 --- /dev/null +++ b/micro-client/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java @@ -0,0 +1,24 @@ +package app.embedded.com.oath.micro.server; + + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.EmbeddedModule; +import cyclops.reactive.collections.immutable.LinkedListX; + +@Microserver(basePackages = { "app.embedded.com.oath.micro.server" }) +public class EmbeddedAppLocalMain { + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( + EmbeddedModule.tagInterfaceModule(LinkedListX.of(TestAppRestResource.class),"test-app"), + EmbeddedModule.tagInterfaceModule(LinkedListX.of(AltAppRestResource.class),"alternative-app")).start(); + + + + } + + +} diff --git a/micro-client/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java b/micro-client/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java new file mode 100644 index 000000000..ad57ef877 --- /dev/null +++ b/micro-client/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java @@ -0,0 +1,105 @@ +package app.embedded.com.oath.micro.server; + +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.NotFoundException; + +import com.google.common.collect.ImmutableList; +import cyclops.reactive.collections.immutable.LinkedListX; + + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.util.concurrent.ListenableFuture; +import org.springframework.util.concurrent.ListenableFutureCallback; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.EmbeddedModule; +import com.oath.micro.server.testing.RestAgent; + +public class EmbeddedAppTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer(){ + server = new MicroserverApp(EmbeddedAppLocalMain.class, + EmbeddedModule.tagInterfaceModule(LinkedListX.of(TestAppRestResource.class),"test-app"), + EmbeddedModule.tagInterfaceModule(LinkedListX.of(AltAppRestResource.class),"alternative-app")); + server.start(); + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); + + + assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value", ImmutableList.of("hello","world")),List.class), + hasItem("hello")); + + } + + + @Test + public void nonBlockingRestClientTest(){ + assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"),is("-*test!-*test!")); + } + + CompletableFuture toCompletableFuture( + final ListenableFuture listenableFuture + ) { + //create an instance of CompletableFuture + CompletableFuture completable = new CompletableFuture() { + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + // propagate cancel to the listenable future + boolean result = listenableFuture.cancel(mayInterruptIfRunning); + super.cancel(mayInterruptIfRunning); + return result; + } + }; + + // add callback + listenableFuture.addCallback(new ListenableFutureCallback() { + @Override + public void onSuccess(T result) { + completable.complete(result); + } + + @Override + public void onFailure(Throwable t) { + completable.completeExceptionally(t); + } + }); + return completable; + } + + @Test(expected=NotFoundException.class) + public void confirmAltAppCantUseTestAppResources(){ + + assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); + + } + @Test(expected=NotFoundException.class) + public void confirmTestAppCantUseAltAppResources(){ + + assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",ImmutableList.of("hello","world")),List.class), + hasItem("hello")); + + } +} diff --git a/micro-client/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java b/micro-client/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java new file mode 100644 index 000000000..337b63b89 --- /dev/null +++ b/micro-client/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java @@ -0,0 +1,29 @@ +package app.embedded.com.oath.micro.server; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "immutable") +@Getter +@AllArgsConstructor +@Builder +public class ImmutableEntity { + + private final String value; + private final List list; + + public ImmutableEntity() { + this(null,null); + } + +} diff --git a/micro-client/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java b/micro-client/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java new file mode 100644 index 000000000..33cb9c2b1 --- /dev/null +++ b/micro-client/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java @@ -0,0 +1,55 @@ +package app.embedded.com.oath.micro.server; + +import java.util.Arrays; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import cyclops.futurestream.SimpleReact; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.rest.client.nio.NIORestClient; +@Component +@Path("/test-status") +public class TestAppResource implements TestAppRestResource { + + private final SimpleReact simpleReact = new SimpleReact(); + private final NIORestClient template; + private final List urls = Arrays.asList("http://localhost:8081/alternative-app/alt-status/ping", + "http://localhost:8080/test-app/test-status/ping", + "http://localhost:8082/simple-app/status/ping", + "http://localhost:8080/test-app/test-status/ping"); + + @Autowired + public TestAppResource(NIORestClient template) { + + this.template = template; + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "test!"; + } + + @GET + @Produces("text/plain") + @Path("/rest-calls") + public String restCallResult(){ + + return simpleReact + .fromStream(urls.stream() + .map(it -> template.getForEntity(it,String.class))) + .then(it -> it.getBody()) + .then(it -> "*"+it) + .peek(loadedAndModified -> System.out.println(loadedAndModified)) + .block().stream().reduce("", (acc,next) -> acc+"-"+next); + + } + +} diff --git a/micro-client/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java b/micro-client/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java new file mode 100644 index 000000000..7d4df5753 --- /dev/null +++ b/micro-client/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java @@ -0,0 +1,7 @@ +package app.embedded.com.oath.micro.server; + +import com.oath.micro.server.auto.discovery.RestResource; + +public interface TestAppRestResource extends RestResource { + +} diff --git a/micro-client/src/test/java/app/events/com/aol/micro/server/EventRunnerTest.java b/micro-client/src/test/java/app/events/com/aol/micro/server/EventRunnerTest.java deleted file mode 100644 index e19257396..000000000 --- a/micro-client/src/test/java/app/events/com/aol/micro/server/EventRunnerTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package app.events.com.aol.micro.server; - - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class EventRunnerTest { - - RestAgent rest = new RestAgent(); - private final AsyncRestClient client = new AsyncRestClient(100,100).withAccept("application/json"); - MicroserverApp server; - - - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "event-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/event-app/status/ping"),is("ok")); - - assertThat(client.get("http://localhost:8080/event-app/active/jobs").get(), - containsString("startedAt")); - assertThat(client.get("http://localhost:8080/event-app/active/requests").get(), - containsString("startedAt")); - assertThat(client.get("http://localhost:8080/event-app/manifest").get(), - containsString("Manifest")); - - } - - - -} diff --git a/micro-client/src/test/java/app/events/com/aol/micro/server/EventStatusResource.java b/micro-client/src/test/java/app/events/com/aol/micro/server/EventStatusResource.java deleted file mode 100644 index 7f5bc184b..000000000 --- a/micro-client/src/test/java/app/events/com/aol/micro/server/EventStatusResource.java +++ /dev/null @@ -1,40 +0,0 @@ -package app.events.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.events.RequestEvents; -import com.google.common.eventbus.EventBus; - -@Component -@Path("/status") -public class EventStatusResource implements RestResource { - - - - - private final EventBus bus; - - @Autowired - public EventStatusResource(EventBus bus ){ - this.bus = bus; - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - bus.post(RequestEvents.start("get", 1l)); - try{ - return "ok"; - }finally{ - bus.post(RequestEvents.finish("get",1l)); - } - } - -} \ No newline at end of file diff --git a/micro-client/src/test/java/app/events/com/aol/micro/server/Job.java b/micro-client/src/test/java/app/events/com/aol/micro/server/Job.java deleted file mode 100644 index 845248592..000000000 --- a/micro-client/src/test/java/app/events/com/aol/micro/server/Job.java +++ /dev/null @@ -1,16 +0,0 @@ -package app.events.com.aol.micro.server; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.events.ScheduledJob; -import com.aol.micro.server.events.SystemData; - -@Component -public class Job implements ScheduledJob{ - - @Override - public SystemData scheduleAndLog() { - return SystemData.builder().errors(0).processed(2).build(); - } - -} diff --git a/micro-client/src/test/java/app/events/com/aol/micro/server/Schedular.java b/micro-client/src/test/java/app/events/com/aol/micro/server/Schedular.java deleted file mode 100644 index 8b99c6930..000000000 --- a/micro-client/src/test/java/app/events/com/aol/micro/server/Schedular.java +++ /dev/null @@ -1,21 +0,0 @@ -package app.events.com.aol.micro.server; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -@Component -public class Schedular { - - private final Job job; - - @Autowired - public Schedular(final Job job){ - this.job=job; - } - - @Scheduled(fixedDelay=1) - public synchronized void scheduleTask(){ - job.scheduleAndLog(); - } -} diff --git a/micro-client/src/test/java/app/events/com/oath/micro/server/EventRunnerTest.java b/micro-client/src/test/java/app/events/com/oath/micro/server/EventRunnerTest.java new file mode 100644 index 000000000..306b04ec7 --- /dev/null +++ b/micro-client/src/test/java/app/events/com/oath/micro/server/EventRunnerTest.java @@ -0,0 +1,63 @@ +package app.events.com.oath.micro.server; + + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.testing.RestAgent; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +@Microserver +public class EventRunnerTest { + + RestAgent rest = new RestAgent(); + private final AsyncRestClient client = new AsyncRestClient(30000,30000).withAccept("application/json"); + MicroserverApp server; + + + @Before + public void startServer(){ + + server = new MicroserverApp(()-> "event-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/event-app/status/ping"),is("ok")); + + + System.out.println("Res ****");// + client.get("http://localhost:8080/event-app/active/jobs").get()); + System.out.println(client.get("http://localhost:8080/event-app/active/jobs").get()); + System.out.println("****"); + + assertThat(client.get("http://localhost:8080/event-app/active/jobs").get(), + containsString("startedAt")); + assertThat(client.get("http://localhost:8080/event-app/active/requests").get(), + containsString("startedAt")); + assertThat(client.get("http://localhost:8080/event-app/manifest").get(), + containsString("Manifest")); + + + } + + + +} diff --git a/micro-client/src/test/java/app/events/com/oath/micro/server/EventStatusResource.java b/micro-client/src/test/java/app/events/com/oath/micro/server/EventStatusResource.java new file mode 100644 index 000000000..75ed47c04 --- /dev/null +++ b/micro-client/src/test/java/app/events/com/oath/micro/server/EventStatusResource.java @@ -0,0 +1,40 @@ +package app.events.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.events.RequestEvents; +import com.google.common.eventbus.EventBus; + +@Component +@Path("/status") +public class EventStatusResource implements RestResource { + + + + + private final EventBus bus; + + @Autowired + public EventStatusResource(EventBus bus ){ + this.bus = bus; + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + bus.post(RequestEvents.start("get", "1")); + try{ + return "ok"; + }finally{ + bus.post(RequestEvents.finish("get","1")); + } + } + +} diff --git a/micro-client/src/test/java/app/events/com/oath/micro/server/Job.java b/micro-client/src/test/java/app/events/com/oath/micro/server/Job.java new file mode 100644 index 000000000..f9457c509 --- /dev/null +++ b/micro-client/src/test/java/app/events/com/oath/micro/server/Job.java @@ -0,0 +1,16 @@ +package app.events.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.events.ScheduledJob; +import com.oath.micro.server.events.SystemData; + +@Component +public class Job implements ScheduledJob{ + + @Override + public SystemData scheduleAndLog() { + return SystemData.builder().errors(0).processed(2).build(); + } + +} diff --git a/micro-client/src/test/java/app/events/com/oath/micro/server/Schedular.java b/micro-client/src/test/java/app/events/com/oath/micro/server/Schedular.java new file mode 100644 index 000000000..c93a9c537 --- /dev/null +++ b/micro-client/src/test/java/app/events/com/oath/micro/server/Schedular.java @@ -0,0 +1,21 @@ +package app.events.com.oath.micro.server; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +@Component +public class Schedular { + + private final Job job; + + @Autowired + public Schedular(final Job job){ + this.job=job; + } + + @Scheduled(fixedDelay=1) + public synchronized void scheduleTask(){ + job.scheduleAndLog(); + } +} diff --git a/micro-client/src/test/java/app/rest/client/com/aol/micro/server/GenericRestClientResource.java b/micro-client/src/test/java/app/rest/client/com/aol/micro/server/GenericRestClientResource.java deleted file mode 100644 index 8aa6fdec9..000000000 --- a/micro-client/src/test/java/app/rest/client/com/aol/micro/server/GenericRestClientResource.java +++ /dev/null @@ -1,56 +0,0 @@ -package app.rest.client.com.aol.micro.server; - -import java.util.List; - -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -@Component -@Path("/rest") -public class GenericRestClientResource implements RestResource { - - - @GET - @Produces("application/json") - @Path("/get") - public List get() { - - return ImmutableList.of("ok"); - } - - @POST - @Produces("application/json") - @Path("/post") - public ImmutableSet post(ImmutableMap map) { - - return ImmutableSet.copyOf(map.values()); - } - - @PUT - @Produces("application/json") - @Path("/put") - public ImmutableSet put(ImmutableMap map) { - - return ImmutableSet.copyOf(map.values()); - } - @DELETE - @Produces("application/json") - @Path("/delete") - public List delete(ImmutableMap map) { - - return ImmutableList.of("ok"); - } - - -} \ No newline at end of file diff --git a/micro-client/src/test/java/app/rest/client/com/aol/micro/server/MyEntity.java b/micro-client/src/test/java/app/rest/client/com/aol/micro/server/MyEntity.java deleted file mode 100644 index 1d2fa9b71..000000000 --- a/micro-client/src/test/java/app/rest/client/com/aol/micro/server/MyEntity.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.rest.client.com.aol.micro.server; - -import lombok.EqualsAndHashCode; -import lombok.Getter; - -@EqualsAndHashCode -@Getter -public class MyEntity { - - private final String name ="myEntity"; - -} diff --git a/micro-client/src/test/java/app/rest/client/com/aol/micro/server/RestClientResource.java b/micro-client/src/test/java/app/rest/client/com/aol/micro/server/RestClientResource.java deleted file mode 100644 index c784b47d7..000000000 --- a/micro-client/src/test/java/app/rest/client/com/aol/micro/server/RestClientResource.java +++ /dev/null @@ -1,54 +0,0 @@ -package app.rest.client.com.aol.micro.server; - -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -@Component -@Path("/generics") -public class RestClientResource implements RestResource { - - private final ImmutableList result = ImmutableList.of(new MyEntity()); - @GET - @Produces("application/json") - @Path("/get") - public ImmutableList get() { - - return result; - } - - @POST - @Produces("application/json") - @Path("/post") - public ImmutableList post(ImmutableMap map) { - - return result; - } - - @PUT - @Produces("application/json") - @Path("/put") - public ImmutableList put(ImmutableMap map) { - - return result; - } - @DELETE - @Produces("application/json") - @Path("/delete") - public ImmutableList delete(ImmutableMap map) { - - return result; - } - - -} \ No newline at end of file diff --git a/micro-client/src/test/java/app/rest/client/com/aol/micro/server/RestClientTest.java b/micro-client/src/test/java/app/rest/client/com/aol/micro/server/RestClientTest.java deleted file mode 100644 index 9d7dbcf5e..000000000 --- a/micro-client/src/test/java/app/rest/client/com/aol/micro/server/RestClientTest.java +++ /dev/null @@ -1,141 +0,0 @@ - -package app.rest.client.com.aol.micro.server; - - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.List; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.web.client.RestClientException; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.RestClient; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.rest.client.nio.NIORestClient; -import com.aol.micro.server.rest.client.nio.SpringConfig; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -@Microserver -public class RestClientTest { - - private final AsyncRestClient> listClient = new AsyncRestClient(1000,1000).withResponse(List.class); - private final AsyncRestClient> setClient = new AsyncRestClient(1000,1000).withResponse(ImmutableSet.class);; - private final AsyncRestClient> genericsClient = new AsyncRestClient(1000,1000).withGenericResponse(ImmutableList.class, MyEntity.class); - - private final RestClient> listClientSync = new RestClient(1000,1000).withResponse(List.class); - private final RestClient> setClientSync = new RestClient(1000,1000).withResponse(ImmutableSet.class);; - private final RestClient> genericsClientSync = new RestClient(1000,1000).withGenericResponse(ImmutableList.class, MyEntity.class); - - private final NIORestClient rest = new SpringConfig().restClient(); - - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( RestClientTest.class, ()-> "rest-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - /* - * Simpler with JaxRsNIOClient - */ - @Test - public void testCRUD() throws InterruptedException, ExecutionException{ - - - assertThat(listClient.get("http://localhost:8080/rest-app/rest/get").get().get(0),is("ok")); - assertThat(setClient.post("http://localhost:8080/rest-app/rest/post",ImmutableMap.of(1,"hello")).get(),is(ImmutableSet.of("hello"))); - assertThat(setClient.put("http://localhost:8080/rest-app/rest/put",ImmutableMap.of(1,"hello")).get(),is(ImmutableSet.of("hello"))); - assertThat(listClient.delete("http://localhost:8080/rest-app/rest/delete").get().get(0),is("ok")); - } - - @Test - public void testCRUDGenerics() throws InterruptedException, ExecutionException{ - - - assertThat(genericsClient.get("http://localhost:8080/rest-app/generics/get").get().get(0),is(new MyEntity())); - assertThat(genericsClient.post("http://localhost:8080/rest-app/generics/post",ImmutableMap.of(1,"hello")).get(),is(ImmutableList.of(new MyEntity()))); - assertThat(genericsClient.put("http://localhost:8080/rest-app/generics/put",ImmutableMap.of(1,"hello")).get(),is(ImmutableList.of(new MyEntity()))); - assertThat(genericsClient.delete("http://localhost:8080/rest-app/generics/delete").get().get(0),is(new MyEntity())); - } - /* - * Simpler with JaxRsNIOClient - */ - @Test - public void testCRUDSync() throws InterruptedException, ExecutionException{ - - - assertThat(listClientSync.get("http://localhost:8080/rest-app/rest/get").get(0),is("ok")); - assertThat(setClientSync.post("http://localhost:8080/rest-app/rest/post",ImmutableMap.of(1,"hello")),is(ImmutableSet.of("hello"))); - assertThat(setClientSync.put("http://localhost:8080/rest-app/rest/put",ImmutableMap.of(1,"hello")),is(ImmutableSet.of("hello"))); - assertThat(listClientSync.delete("http://localhost:8080/rest-app/rest/delete").get(0),is("ok")); - } - - @Test - public void testCRUDGenericsSync() throws InterruptedException, ExecutionException{ - - - assertThat(genericsClientSync.get("http://localhost:8080/rest-app/generics/get").get(0),is(new MyEntity())); - assertThat(genericsClientSync.post("http://localhost:8080/rest-app/generics/post",ImmutableMap.of(1,"hello")),is(ImmutableList.of(new MyEntity()))); - assertThat(genericsClientSync.put("http://localhost:8080/rest-app/generics/put",ImmutableMap.of(1,"hello")),is(ImmutableList.of(new MyEntity()))); - assertThat(genericsClientSync.delete("http://localhost:8080/rest-app/generics/delete").get(0),is(new MyEntity())); - } - - /** - * More complex with Spring REST Template Based NIORestTemplate - * - */ - - @Test - public void testCRUDSpring() throws InterruptedException, ExecutionException, RestClientException, URISyntaxException{ - - - assertThat(rest.getForEntity(new URI("http://localhost:8080/rest-app/rest/get"),List.class).get().getBody().get(0),is("ok")); - - assertThat(rest.postForEntity("http://localhost:8080/rest-app/rest/post", new HttpEntity(ImmutableMap.of(1,"hello")), ImmutableSet.class).get().getBody(),is(ImmutableSet.of("hello"))); - assertThat( rest.put("http://localhost:8080/rest-app/rest/put",new HttpEntity(ImmutableMap.of(1,"hello")),ImmutableSet.class).get() - ,is(nullValue())); - assertThat(rest.delete("http://localhost:8080/rest-app/rest/delete").get(),is(nullValue())); - } - - @Test - public void testCRUDGenericsSpring() throws InterruptedException, ExecutionException{ - - - assertThat(rest.exchange("http://localhost:8080/rest-app/generics/get",HttpMethod.GET,null,new ParameterizedTypeReference>(){}) - .get().getBody().get(0),is(new MyEntity())); - - assertThat(rest.exchange("http://localhost:8080/rest-app/generics/post",HttpMethod.POST,new HttpEntity(ImmutableMap.of(1,"hello")),new ParameterizedTypeReference>(){}) - .get().getBody(),is(ImmutableList.of(new MyEntity()))); - - assertThat(rest.exchange("http://localhost:8080/rest-app/generics/put",HttpMethod.PUT,new HttpEntity(ImmutableMap.of(1,"hello")),new ParameterizedTypeReference>(){}) - .get().getBody(),is(ImmutableList.of(new MyEntity()))); - - assertThat(rest.exchange("http://localhost:8080/rest-app/generics/delete",HttpMethod.DELETE,null,new ParameterizedTypeReference>(){}) - .get().getBody().get(0),is(new MyEntity())); - - } - - - -} diff --git a/micro-client/src/test/java/app/rest/client/com/oath/micro/server/GenericRestClientResource.java b/micro-client/src/test/java/app/rest/client/com/oath/micro/server/GenericRestClientResource.java new file mode 100644 index 000000000..3b6b9ee90 --- /dev/null +++ b/micro-client/src/test/java/app/rest/client/com/oath/micro/server/GenericRestClientResource.java @@ -0,0 +1,56 @@ +package app.rest.client.com.oath.micro.server; + +import java.util.List; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +@Component +@Path("/rest") +public class GenericRestClientResource implements RestResource { + + + @GET + @Produces("application/json") + @Path("/get") + public List get() { + + return ImmutableList.of("ok"); + } + + @POST + @Produces("application/json") + @Path("/post") + public ImmutableSet post(ImmutableMap map) { + + return ImmutableSet.copyOf(map.values()); + } + + @PUT + @Produces("application/json") + @Path("/put") + public ImmutableSet put(ImmutableMap map) { + + return ImmutableSet.copyOf(map.values()); + } + @DELETE + @Produces("application/json") + @Path("/delete") + public List delete(ImmutableMap map) { + + return ImmutableList.of("ok"); + } + + +} \ No newline at end of file diff --git a/micro-client/src/test/java/app/rest/client/com/oath/micro/server/MyEntity.java b/micro-client/src/test/java/app/rest/client/com/oath/micro/server/MyEntity.java new file mode 100644 index 000000000..c075fa67f --- /dev/null +++ b/micro-client/src/test/java/app/rest/client/com/oath/micro/server/MyEntity.java @@ -0,0 +1,12 @@ +package app.rest.client.com.oath.micro.server; + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@EqualsAndHashCode +@Getter +public class MyEntity { + + private final String name ="myEntity"; + +} diff --git a/micro-client/src/test/java/app/rest/client/com/oath/micro/server/RestClientResource.java b/micro-client/src/test/java/app/rest/client/com/oath/micro/server/RestClientResource.java new file mode 100644 index 000000000..90c119ba5 --- /dev/null +++ b/micro-client/src/test/java/app/rest/client/com/oath/micro/server/RestClientResource.java @@ -0,0 +1,53 @@ +package app.rest.client.com.oath.micro.server; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +@Component +@Path("/generics") +public class RestClientResource implements RestResource { + + private final ImmutableList result = ImmutableList.of(new MyEntity()); + @GET + @Produces("application/json") + @Path("/get") + public ImmutableList get() { + + return result; + } + + @POST + @Produces("application/json") + @Path("/post") + public ImmutableList post(ImmutableMap map) { + + return result; + } + + @PUT + @Produces("application/json") + @Path("/put") + public ImmutableList put(ImmutableMap map) { + + return result; + } + @DELETE + @Produces("application/json") + @Path("/delete") + public ImmutableList delete(ImmutableMap map) { + + return result; + } + + +} \ No newline at end of file diff --git a/micro-client/src/test/java/app/rest/client/com/oath/micro/server/RestClientTest.java b/micro-client/src/test/java/app/rest/client/com/oath/micro/server/RestClientTest.java new file mode 100644 index 000000000..d011e0235 --- /dev/null +++ b/micro-client/src/test/java/app/rest/client/com/oath/micro/server/RestClientTest.java @@ -0,0 +1,141 @@ + +package app.rest.client.com.oath.micro.server; + + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.web.client.RestClientException; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.RestClient; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.rest.client.nio.NIORestClient; +import com.oath.micro.server.rest.client.nio.SpringConfig; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +@Microserver +public class RestClientTest { + + private final AsyncRestClient> listClient = new AsyncRestClient(1000,1000).withResponse(List.class); + private final AsyncRestClient> setClient = new AsyncRestClient(1000,1000).withResponse(ImmutableSet.class);; + private final AsyncRestClient> genericsClient = new AsyncRestClient(1000,1000).withGenericResponse(ImmutableList.class, MyEntity.class); + + private final RestClient> listClientSync = new RestClient(1000,1000).withResponse(List.class); + private final RestClient> setClientSync = new RestClient(1000,1000).withResponse(ImmutableSet.class);; + private final RestClient> genericsClientSync = new RestClient(1000,1000).withGenericResponse(ImmutableList.class, MyEntity.class); + + private final NIORestClient rest = new SpringConfig().restClient(); + + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( RestClientTest.class, ()-> "rest-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + /* + * Simpler with JaxRsNIOClient + */ + @Test + public void testCRUD() throws InterruptedException, ExecutionException{ + + + assertThat(listClient.get("http://localhost:8080/rest-app/rest/get").get().get(0),is("ok")); + assertThat(setClient.post("http://localhost:8080/rest-app/rest/post",ImmutableMap.of(1,"hello")).get(),is(ImmutableSet.of("hello"))); + assertThat(setClient.put("http://localhost:8080/rest-app/rest/put",ImmutableMap.of(1,"hello")).get(),is(ImmutableSet.of("hello"))); + assertThat(listClient.delete("http://localhost:8080/rest-app/rest/delete").get().get(0),is("ok")); + } + + @Test + public void testCRUDGenerics() throws InterruptedException, ExecutionException{ + + + assertThat(genericsClient.get("http://localhost:8080/rest-app/generics/get").get().get(0),is(new MyEntity())); + assertThat(genericsClient.post("http://localhost:8080/rest-app/generics/post",ImmutableMap.of(1,"hello")).get(),is(ImmutableList.of(new MyEntity()))); + assertThat(genericsClient.put("http://localhost:8080/rest-app/generics/put",ImmutableMap.of(1,"hello")).get(),is(ImmutableList.of(new MyEntity()))); + assertThat(genericsClient.delete("http://localhost:8080/rest-app/generics/delete").get().get(0),is(new MyEntity())); + } + /* + * Simpler with JaxRsNIOClient + */ + @Test + public void testCRUDSync() throws InterruptedException, ExecutionException{ + + + assertThat(listClientSync.get("http://localhost:8080/rest-app/rest/get").get(0),is("ok")); + assertThat(setClientSync.post("http://localhost:8080/rest-app/rest/post",ImmutableMap.of(1,"hello")),is(ImmutableSet.of("hello"))); + assertThat(setClientSync.put("http://localhost:8080/rest-app/rest/put",ImmutableMap.of(1,"hello")),is(ImmutableSet.of("hello"))); + assertThat(listClientSync.delete("http://localhost:8080/rest-app/rest/delete").get(0),is("ok")); + } + + @Test + public void testCRUDGenericsSync() throws InterruptedException, ExecutionException{ + + + assertThat(genericsClientSync.get("http://localhost:8080/rest-app/generics/get").get(0),is(new MyEntity())); + assertThat(genericsClientSync.post("http://localhost:8080/rest-app/generics/post",ImmutableMap.of(1,"hello")),is(ImmutableList.of(new MyEntity()))); + assertThat(genericsClientSync.put("http://localhost:8080/rest-app/generics/put",ImmutableMap.of(1,"hello")),is(ImmutableList.of(new MyEntity()))); + assertThat(genericsClientSync.delete("http://localhost:8080/rest-app/generics/delete").get(0),is(new MyEntity())); + } + + /** + * More complex with Spring REST Template Based NIORestTemplate + * + */ + + @Test + public void testCRUDSpring() throws InterruptedException, ExecutionException, RestClientException, URISyntaxException{ + + + assertThat(rest.getForEntity(new URI("http://localhost:8080/rest-app/rest/get"),List.class).get().getBody().get(0),is("ok")); + + assertThat(rest.postForEntity("http://localhost:8080/rest-app/rest/post", new HttpEntity(ImmutableMap.of(1,"hello")), ImmutableSet.class).get().getBody(),is(ImmutableSet.of("hello"))); + assertThat( rest.put("http://localhost:8080/rest-app/rest/put",new HttpEntity(ImmutableMap.of(1,"hello")),ImmutableSet.class).get() + ,is(nullValue())); + assertThat(rest.delete("http://localhost:8080/rest-app/rest/delete").get(),is(nullValue())); + } + + @Test + public void testCRUDGenericsSpring() throws InterruptedException, ExecutionException{ + + + assertThat(rest.exchange("http://localhost:8080/rest-app/generics/get",HttpMethod.GET,null,new ParameterizedTypeReference>(){}) + .get().getBody().get(0),is(new MyEntity())); + + assertThat(rest.exchange("http://localhost:8080/rest-app/generics/post",HttpMethod.POST,new HttpEntity(ImmutableMap.of(1,"hello")),new ParameterizedTypeReference>(){}) + .get().getBody(),is(ImmutableList.of(new MyEntity()))); + + assertThat(rest.exchange("http://localhost:8080/rest-app/generics/put",HttpMethod.PUT,new HttpEntity(ImmutableMap.of(1,"hello")),new ParameterizedTypeReference>(){}) + .get().getBody(),is(ImmutableList.of(new MyEntity()))); + + assertThat(rest.exchange("http://localhost:8080/rest-app/generics/delete",HttpMethod.DELETE,null,new ParameterizedTypeReference>(){}) + .get().getBody().get(0),is(new MyEntity())); + + } + + + +} diff --git a/micro-client/src/test/java/com/aol/micro/server/client/ClientModuleTest.java b/micro-client/src/test/java/com/aol/micro/server/client/ClientModuleTest.java deleted file mode 100644 index d51864c33..000000000 --- a/micro-client/src/test/java/com/aol/micro/server/client/ClientModuleTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.aol.micro.server.client; - -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; - -import org.junit.Test; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.module.Module; - -public class ClientModuleTest { - @Test - public void testProviders(){ - System.out.println(ConfigurableModule.builder().build().getProviders()); - //test MyPlugin working - - System.out.println(new ModuleImpl().getProviders()); - String additional = ReactiveSeq - .fromStream( - Arrays.asList(new TestPlugin()) - .stream()).filter(module -> module.providers()!=null) - .flatMapIterable(Plugin::providers) - .join(","); - - assertThat(additional, equalTo("")); - } - static class ModuleImpl implements Module{ - public String getContext(){ - return "hello world"; - } - } -} diff --git a/micro-client/src/test/java/com/aol/micro/server/client/TestPlugin.java b/micro-client/src/test/java/com/aol/micro/server/client/TestPlugin.java deleted file mode 100644 index add82a4ba..000000000 --- a/micro-client/src/test/java/com/aol/micro/server/client/TestPlugin.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.aol.micro.server.client; - -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.micro.server.Plugin; - -public class TestPlugin implements Plugin { - public PStackX providers(){ - return PStackX.empty(); - } -} diff --git a/micro-client/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-client/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-client/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-client/src/test/java/com/oath/micro/server/client/ClientModuleTest.java b/micro-client/src/test/java/com/oath/micro/server/client/ClientModuleTest.java new file mode 100644 index 000000000..cd6f5eb15 --- /dev/null +++ b/micro-client/src/test/java/com/oath/micro/server/client/ClientModuleTest.java @@ -0,0 +1,37 @@ +package com.oath.micro.server.client; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; + +import cyclops.reactive.ReactiveSeq; +import org.junit.Test; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.module.Module; + +public class ClientModuleTest { + @Test + public void testProviders(){ + System.out.println(ConfigurableModule.builder().build().getProviders()); + //test MyPlugin working + + System.out.println(new ModuleImpl().getProviders()); + String additional = ReactiveSeq + .fromStream( + Arrays.asList(new TestPlugin()) + .stream()).filter(module -> module.providers()!=null) + .concatMap(Plugin::providers) + .join(","); + + assertThat(additional, equalTo("")); + } + static class ModuleImpl implements Module{ + public String getContext(){ + return "hello world"; + } + } +} diff --git a/micro-client/src/test/java/com/oath/micro/server/client/TestPlugin.java b/micro-client/src/test/java/com/oath/micro/server/client/TestPlugin.java new file mode 100644 index 000000000..999c0173e --- /dev/null +++ b/micro-client/src/test/java/com/oath/micro/server/client/TestPlugin.java @@ -0,0 +1,13 @@ +package com.oath.micro.server.client; + + +import com.oath.micro.server.Plugin; +import cyclops.reactive.collections.mutable.ListX; + +import java.util.List; + +public class TestPlugin implements Plugin { + public List providers(){ + return ListX.empty(); + } +} diff --git a/micro-client/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-client/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-client/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-core/.DS_Store b/micro-core/.DS_Store deleted file mode 100644 index 5008ddfcf..000000000 Binary files a/micro-core/.DS_Store and /dev/null differ diff --git a/micro-core/README.md b/micro-core/README.md new file mode 100644 index 000000000..bbcf73d5f --- /dev/null +++ b/micro-core/README.md @@ -0,0 +1,22 @@ +# The core of Microserver + +This module imports your configured plugins, starts and manages your JEE webserver and jax-rs implementation. + +## To use + + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-core) + +Simply add to the classpath + +Maven + + + com.oath.microservices + micro-core + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-core:x.yz' diff --git a/micro-core/build.gradle b/micro-core/build.gradle index 9b501e418..9ec695b11 100644 --- a/micro-core/build.gradle +++ b/micro-core/build.gradle @@ -1,91 +1,91 @@ description = 'micro-core' + dependencies { - compile 'javax.servlet:javax.servlet-api:3.1.0' - - compile ("com.aol.simplereact:cyclops-react:$cyclopsReactVersion") - compile group: 'org.aspectj', name: 'aspectjrt', version:aspectJVersion - compile group: 'org.aspectj', name: 'aspectjweaver', version:aspectJVersion - - - compile group: 'org.springframework', name: 'spring-web', version:"${springVersion}" - compile group: 'org.springframework', name: 'spring-context', version:"${springVersion}" - compile group: 'org.springframework', name: 'spring-context-support', version:"${springVersion}" - compile group: 'ch.qos.logback', name: 'logback-classic', version:logbackVersion - compile group: 'ch.qos.logback', name: 'logback-core', version:logbackVersion - compile group: 'org.slf4j', name: 'jcl-over-slf4j', version:slf4jVersion - - - compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jdk8', version:"$jacksonVersion" - compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version:"$jacksonVersion" - compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version:"$jacksonVersion" - compile group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-json-provider', version:"$jacksonVersion" - compile group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-base', version:"$jacksonVersion" - - compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-jaxb-annotations', version:"$jacksonVersion" - - compile group: 'javax.ws.rs', name: 'javax.ws.rs-api', version:'2.0' - testCompile group: 'org.hamcrest', name: 'hamcrest-all', version:hamcrestVersion - + compile 'javax.servlet:javax.servlet-api:3.1.0' + + compile("com.oath.cyclops:cyclops:$cyclopsVersion") + compile("com.oath.cyclops:cyclops-reactive-collections:$cyclopsVersion") + compile group: 'org.aspectj', name: 'aspectjrt', version: aspectJVersion + compile group: 'org.aspectj', name: 'aspectjweaver', version: aspectJVersion + + + compile group: 'org.springframework', name: 'spring-web', version: "${springVersion}" + compile group: 'org.springframework', name: 'spring-context', version: "${springVersion}" + compile group: 'org.springframework', name: 'spring-context-support', version: "${springVersion}" + compile group: 'ch.qos.logback', name: 'logback-classic', version: logbackVersion + compile group: 'ch.qos.logback', name: 'logback-core', version: logbackVersion + compile group: 'org.slf4j', name: 'jcl-over-slf4j', version: slf4jVersion + + + compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jdk8', version: "$jacksonVersion" + compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: "$jacksonVersion" + compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: "$jacksonVersion" + compile group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-json-provider', version: "$jacksonVersion" + compile group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-base', version: "$jacksonVersion" + + compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-jaxb-annotations', version: "$jacksonVersion" + compile group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0' + testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: hamcrestVersion } modifyPom { - project { - name 'Microserver' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-core' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - developer { - id 'earlzero' - name 'Nikita Sapozhnikov' - email 'nikita.sapozhnikov@teamaol.com ' - } - } - - } + project { + name 'Microserver' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-core' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com ' + } + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-core/readme.md b/micro-core/readme.md deleted file mode 100644 index c61f91991..000000000 --- a/micro-core/readme.md +++ /dev/null @@ -1,22 +0,0 @@ -# The core of Microserver - -This module imports your configured plugins, starts and manages your JEE webserver and jax-rs implementation. - -## To use - - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-core) - -Simply add to the classpath - -Maven - - - com.aol.microservices - micro-core - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-core:x.yz' \ No newline at end of file diff --git a/micro-core/resources/.DS_Store b/micro-core/resources/.DS_Store deleted file mode 100644 index 5008ddfcf..000000000 Binary files a/micro-core/resources/.DS_Store and /dev/null differ diff --git a/micro-core/src/main/java/com/aol/micro/server/ErrorCode.java b/micro-core/src/main/java/com/aol/micro/server/ErrorCode.java deleted file mode 100644 index 985e58fd2..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/ErrorCode.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.aol.micro.server; - -import lombok.Getter; - - - -@Getter -public enum ErrorCode { - GRIZZLY_SERVER_EXCEPTION, SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG, STARTUP_FAILED_SPRING_INITIALISATION - - -} - diff --git a/micro-core/src/main/java/com/aol/micro/server/GlobalState.java b/micro-core/src/main/java/com/aol/micro/server/GlobalState.java deleted file mode 100644 index 355365749..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/GlobalState.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.aol.micro.server; - -import com.aol.cyclops.data.collections.extensions.standard.ListX; -import com.aol.micro.server.module.Module; - -import lombok.Getter; -import lombok.Setter; - -public class GlobalState { - - public static final GlobalState state = new GlobalState(); - - private GlobalState(){ } - - @Getter @Setter - private volatile ListX modules; -} diff --git a/micro-core/src/main/java/com/aol/micro/server/MicroserverApp.java b/micro-core/src/main/java/com/aol/micro/server/MicroserverApp.java deleted file mode 100644 index 383531a36..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/MicroserverApp.java +++ /dev/null @@ -1,169 +0,0 @@ -package com.aol.micro.server; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; - -import lombok.Getter; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.data.collections.extensions.standard.ListX; -import com.aol.cyclops.util.ExceptionSoftener; -import com.aol.cyclops.util.stream.StreamUtils; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.config.MicroserverConfigurer; -import com.aol.micro.server.module.Module; -import com.aol.micro.server.servers.ApplicationRegister; -import com.aol.micro.server.servers.ServerApplication; -import com.aol.micro.server.servers.ServerApplicationFactory; -import com.aol.micro.server.servers.ServerRunner; -import com.aol.micro.server.spring.SpringContextFactory; - -/** - * - * Startup class for Microserver instance - * - * @author johnmcclean - * - */ -public class MicroserverApp { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final ListX modules; - private final CompletableFuture end = new CompletableFuture(); - - - @Getter - private final ApplicationContext springContext; - - /** - * This will construct a Spring context for this Microserver instance. - * The calling class will be used to determine the base package to auto-scan from for Spring Beans - * It will attempt to pick up an @Microservice annotation first, if not present the package of the calling class - * will be used. - * - * @param modules Multiple Microservice end points that can be deployed within a single Spring context - */ - public MicroserverApp(Module... modules) { - this.modules = ListX.of(modules); - GlobalState.state.setModules(this.modules); - initSpringProperties(modules[0]); - Class c =extractClass(); - springContext = new SpringContextFactory(new MicroserverConfigurer().buildConfig( - c), extractClass(), - modules[0].getSpringConfigurationClasses()) - .createSpringContext(); - - } - - - /** - * This will construct a Spring context for this Microserver instance. - * The provided class will be used to determine the base package to auto-scan from for Spring Beans - * It will attempt to pick up an @Microservice annotation first, if not present the package of the provided class - * will be used. - * - * @param c Class used to configure Spring - * @param modules Multiple Microservice end points that can be deployed within a single Spring context - */ - public MicroserverApp(Class c, Module... modules) { - - this.modules = ListX.of(modules); - GlobalState.state.setModules(this.modules); - initSpringProperties(modules[0]); - springContext = new SpringContextFactory( - new MicroserverConfigurer().buildConfig(c), c, - modules[0].getSpringConfigurationClasses()) - .createSpringContext(); - - } - - private void initSpringProperties(Module m){ - - System.setProperty("server.contextPath", "/"+m.getContext()); - - } - - private Class extractClass() { - try { - return Class.forName(new Exception().getStackTrace()[2] - .getClassName()); - } catch (ClassNotFoundException e) { - throw ExceptionSoftener.throwSoftenedException(e); - } - - } - - - - public void stop() { - - end.complete(true); - Config.reset(); - - } - - public void run() { - start().forEach(thread -> join(thread)); - } - - public List start() { - - List apps = modules.map(module -> createServer(module)); - - - ServerRunner runner; - try { - - runner = new ServerRunner( - springContext.getBean(ApplicationRegister.class), apps, end); - } catch (BeansException e) { - runner = new ServerRunner(apps, end); - } - - return runner.run(); - } - - private ServerApplication createServer(Module module) { - - List applications = ReactiveSeq - .fromStream(PluginLoader.INSTANCE.plugins.get().stream()) - .filter(m -> m.serverApplicationFactory() != null) - .map(Plugin::serverApplicationFactory) - .flatMap(StreamUtils::optionalToStream) - .toList(); - if(applications.size()>1){ - logger.error("ERROR! Multiple server application factories found : The solution is remove one these plugins from your classpath ",applications); - System.err.println("ERROR! Multiple server application factories found : The solution is remove one these plugins from your classpath "+applications); - throw new IncorrectNumberOfServersConfiguredException("Multiple server application factories found : The solution is remove one these plugins from your classpath "+applications); - }else if(applications.size()==0){ - logger.error("ERROR! No server application factories found. If you using micro-spring-boot don't call MicroserverApp.start() method. A possible solution is add one of micro-grizzly or micro-tomcat to the classpath."); - System.err.println("ERROR! No server application factories found. If you using micro-spring-boot don't call MicroserverApp.start() method. A possible solution is add one of micro-grizzly or micro-tomcat to the classpath."); - throw new IncorrectNumberOfServersConfiguredException("No server application factories found. If you using micro-spring-boot don't call MicroserverApp.start() method. A possible solution is add one of micro-grizzly or micro-tomcat to the classpath. "); - - } - - ServerApplication app = applications.get(0).createApp(module, springContext); - - if(Config.instance().getSslProperties()!=null) - return app.withSSLProperties(Config.instance().getSslProperties()); - else - return app; - } - - private void join(Thread thread) { - try { - thread.join(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - ExceptionSoftener.throwSoftenedException(e); - } - } - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/PluginLoader.java b/micro-core/src/main/java/com/aol/micro/server/PluginLoader.java deleted file mode 100644 index 4c5d601f6..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/PluginLoader.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.aol.micro.server; - -import java.util.ServiceLoader; -import java.util.function.Supplier; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -import com.aol.cyclops.control.FluentFunctions; -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.data.collections.extensions.standard.ListX; - -@NoArgsConstructor(access=AccessLevel.PRIVATE) -public class PluginLoader { - - public final static PluginLoader INSTANCE = new PluginLoader(); - - public final Supplier> plugins = FluentFunctions.of(this::load) - .memoize(); - - private ListX load(){ - return ReactiveSeq.fromIterable(ServiceLoader.load(Plugin.class)).toListX(); - } -} diff --git a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/CommonRestResource.java b/micro-core/src/main/java/com/aol/micro/server/auto/discovery/CommonRestResource.java deleted file mode 100644 index d78c15e36..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/CommonRestResource.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.aol.micro.server.auto.discovery; - -public interface CommonRestResource extends RestResource { - - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/FilterConfiguration.java b/micro-core/src/main/java/com/aol/micro/server/auto/discovery/FilterConfiguration.java deleted file mode 100644 index 7435d7f01..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/FilterConfiguration.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aol.micro.server.auto.discovery; - -import java.util.Map; - -import javax.servlet.Filter; - -import org.pcollections.HashTreePMap; - -public interface FilterConfiguration { - - public String[] getMapping(); - - default Class getFilter(){ - return null; - } - default String getName(){ - return null; - } - default Map getInitParameters(){ - return HashTreePMap.empty(); - } -} diff --git a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/RestResource.java b/micro-core/src/main/java/com/aol/micro/server/auto/discovery/RestResource.java deleted file mode 100644 index de2691293..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/RestResource.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.aol.micro.server.auto.discovery; - - - -public interface RestResource { - - /** - * @return true if singleton - */ - default boolean isSingleton(){ - return false; - } - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/ServletConfiguration.java b/micro-core/src/main/java/com/aol/micro/server/auto/discovery/ServletConfiguration.java deleted file mode 100644 index 5507e7b92..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/ServletConfiguration.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aol.micro.server.auto.discovery; - -import java.util.Map; - -import javax.servlet.Servlet; - -import org.pcollections.HashTreePMap; - - -public interface ServletConfiguration { - - public String[] getMapping(); - default String getName(){ - return null; - } - default Map getInitParameters(){ - return HashTreePMap.empty(); - } - default Class getServlet(){ - return null; - } -} diff --git a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/SingletonRestResource.java b/micro-core/src/main/java/com/aol/micro/server/auto/discovery/SingletonRestResource.java deleted file mode 100644 index 5488946d2..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/SingletonRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.aol.micro.server.auto.discovery; - -public interface SingletonRestResource extends RestResource{ - default boolean isSingleton(){ - return true; - } -} diff --git a/micro-core/src/main/java/com/aol/micro/server/config/Classes.java b/micro-core/src/main/java/com/aol/micro/server/config/Classes.java deleted file mode 100644 index fce91765d..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/config/Classes.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.aol.micro.server.config; - -import java.util.ArrayList; -import java.util.List; - -import lombok.Getter; -import nonautoscan.com.aol.micro.server.AopConfig; -import nonautoscan.com.aol.micro.server.ScheduleAndAsyncConfig; - -import com.aol.micro.server.module.ConfigureEnviroment; -import com.aol.micro.server.servers.AccessLogConfig; -import com.aol.micro.server.spring.properties.PropertyFileConfig; - -/** - * - * Collections of Spring configuration classes (Classes annotated with @Configuration) - * that configure various useful pieces of functionality - such as property file loading, - * datasources, scheduling etc - * - * @author johnmcclean - * - */ -public class Classes { - - /** - * CORE CLASSES are the Core Microserver Spring Configuration classes - * Property support, Guava Event Bus, Spring AOP & Scheduling - * Codahale Metrics, Event tracking etc - */ - public static final Classes CORE_CLASSES = new Classes(PropertyFileConfig.class, AopConfig.class, - ScheduleAndAsyncConfig.class, ConfigureEnviroment.class, AccessLogConfig.class); - - - @Getter - private final Class[] classes; - - public Classes(Class... classes) { - this.classes = classes; - } - - public Classes combine(Classes c){ - List c1 = new ArrayList<>(); - for(Class next : classes) - c1.add(next); - for(Class next : c.classes) - c1.add(next); - return new Classes(c1.toArray(new Class[0])); - } -} diff --git a/micro-core/src/main/java/com/aol/micro/server/config/Config.java b/micro-core/src/main/java/com/aol/micro/server/config/Config.java deleted file mode 100644 index f2db3cd9a..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/config/Config.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.aol.micro.server.config; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Stream; - - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Wither; - -import org.pcollections.HashTreePMap; -import org.pcollections.HashTreePSet; -import org.pcollections.PMap; -import org.pcollections.PSet; - -/** - * - * Class for configuring a Spring Context for Microserver - * - * @author johnmcclean - * - */ -@AllArgsConstructor -@Getter -@Wither -public class Config { - - private final String defaultDataSourceName; - private final PSet classes; - private final PMap properties; - - private final String propertiesName; - private final String instancePropertiesName; - private final String serviceTypePropertiesName; - private final PMap> dataSources; - private final SSLProperties sslProperties; - private final boolean allowCircularReferences; - private final String[] basePackages; - - public Config() { - classes = HashTreePSet.empty(); - properties = HashTreePMap.empty(); - dataSources = HashTreePMap.empty(); - defaultDataSourceName = "db"; - propertiesName = "application.properties"; - instancePropertiesName = "instance.properties"; - serviceTypePropertiesName = "service-type.properties"; - sslProperties = null; - allowCircularReferences = false; - basePackages=new String[0]; - - } - - private static volatile Config instance = null; - - public Config set() { - instance = this; - return this; - } - - public static Config instance() { - instance = new Config(); - return instance; - } - - static Config get() { - return instance; - - } - - public static void reset() { - instance = null; - - } - - public Config withEntityScanDataSource(String dataSource, String... packages) { - Map> newMap = new HashMap<>(dataSources); - newMap.put(dataSource, Arrays.asList(packages)); - return this.withDataSources(HashTreePMap.from(newMap)); - } - - /** - * Define the packages that hibernate should scan for Hibernate entities - * Should be used in conjunction Microserver Spring Configuration classes @See Classes#HIBERNATE_CLASSES - * - * @param packages Packages to scan for hibernate entities - * @return New Config object, with configured packages - */ - public Config withEntityScan(String... packages) { - Map> newMap = new HashMap<>(dataSources); - newMap.put(defaultDataSourceName, Arrays.asList(packages)); - return this.withDataSources(HashTreePMap.from(newMap)); - } - - - - public Config withClassesArray(Class... classes){ - Set org = new HashSet(this.getClasses()); - for(Class c: classes) - org.add(c); - return this.withClasses(HashTreePSet.from(org)); - } - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/config/Configurer.java b/micro-core/src/main/java/com/aol/micro/server/config/Configurer.java deleted file mode 100644 index 09baf2038..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/config/Configurer.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.aol.micro.server.config; - -public interface Configurer { - public Config buildConfig(Class class1); -} diff --git a/micro-core/src/main/java/com/aol/micro/server/config/SSLProperties.java b/micro-core/src/main/java/com/aol/micro/server/config/SSLProperties.java deleted file mode 100644 index b1e482ae6..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/config/SSLProperties.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.aol.micro.server.config; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -import com.aol.cyclops.control.AnyM; - -@Getter -@Builder -@AllArgsConstructor -public class SSLProperties { - - private final String keyStoreFile; - private final String keyStorePass; - private final String trustStoreFile; - private final String trustStorePass; - private final String keyStoreType; - private final String keyStoreProvider; - private final String trustStoreType; - private final String trustStoreProvider; - private final String clientAuth; - private final String ciphers; - private final String protocol; - - public AnyM getKeyStoreType() { - return AnyM.ofNullable(keyStoreType); - } - public AnyM getKeyStoreProvider() { - return AnyM.ofNullable(keyStoreProvider); - } - public AnyM getTrustStoreType() { - return AnyM.ofNullable(trustStoreType); - } - public AnyM getTrustStoreProvider() { - return AnyM.ofNullable(trustStoreProvider); - } - public AnyM getClientAuth() { - return AnyM.ofNullable(clientAuth); - } - public AnyM getCiphers() { - return AnyM.ofNullable(ciphers); - } - public AnyM getProtocol() { - return AnyM.ofNullable(protocol); - } -} diff --git a/micro-core/src/main/java/com/aol/micro/server/module/ConfigurableModule.java b/micro-core/src/main/java/com/aol/micro/server/module/ConfigurableModule.java deleted file mode 100644 index f5d9117ee..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/module/ConfigurableModule.java +++ /dev/null @@ -1,204 +0,0 @@ -package com.aol.micro.server.module; - -import static com.aol.micro.server.utility.UsefulStaticMethods.concat; - -import java.lang.annotation.Annotation; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Consumer; -import java.util.function.Supplier; - -import javax.servlet.Filter; -import javax.servlet.Servlet; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletRequestListener; - -import com.aol.cyclops.data.collections.extensions.persistent.PMapX; -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.micro.server.auto.discovery.CommonRestResource; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.utility.HashMapBuilder; - -import lombok.AllArgsConstructor; -import lombok.experimental.Builder; -import lombok.experimental.Wither; - - -@Builder -@AllArgsConstructor -@Wither -public class ConfigurableModule implements Module{ - - private final Set jaxRsResourceObjects; - private final Set> restResourceClasses; - private final Set> restAnnotationClasses; - private final List> defaultResources; - private final List listeners; - private final List requestListeners; - private final Map filters; - private final Map servlets; - private final String jaxWsRsApplication; - private final String providers; - private final String context; - private final Set> springConfigurationClasses; - private final Map propertyOverrides; - private final List defaultJaxRsPackages; - private final Consumer> serverConfigManager; - private final Consumer> resourceConfigManager; - private final Map serverProperties; - final boolean resetAll; - - - public ConfigurableModule withResourceConfigManager(Consumer> resourceConfigManager){ - return new ConfigurableModule(jaxRsResourceObjects,restResourceClasses,restAnnotationClasses, defaultResources, - listeners, requestListeners,filters,servlets, jaxWsRsApplication,providers, - context, springConfigurationClasses, propertyOverrides,defaultJaxRsPackages,serverConfigManager, - (Consumer)resourceConfigManager,serverProperties, resetAll); - } - public ConfigurableModule withServerConfigManager(Consumer> serverConfigManager){ - return new ConfigurableModule(jaxRsResourceObjects,restResourceClasses,restAnnotationClasses, defaultResources, - listeners, requestListeners,filters,servlets, jaxWsRsApplication,providers, - context, springConfigurationClasses, propertyOverrides,defaultJaxRsPackages, - (Consumer)serverConfigManager,resourceConfigManager, serverProperties, resetAll); - } - @Override - public Set getJaxRsResourceObjects(){ - if(this.jaxRsResourceObjects!=null) - return PSetX.fromCollection(concat(this.jaxRsResourceObjects, extract(() -> Module.super.getJaxRsResourceObjects()))); - return Module.super.getJaxRsResourceObjects(); - } - @Override - public Consumer> getServerConfigManager(){ - if(serverConfigManager!=null) - return (Consumer)serverConfigManager; - - return Module.super.getServerConfigManager(); - } - @Override - public Consumer> getResourceConfigManager(){ - if(resourceConfigManager!=null) - return (Consumer)resourceConfigManager; - - return Module.super.getResourceConfigManager(); - } - - @Override - public List getDefaultJaxRsPackages() { - if(defaultJaxRsPackages!=null) - return PStackX.fromCollection(concat(defaultJaxRsPackages,extract(()->Module.super.getDefaultJaxRsPackages()))); - - return PStackX.fromCollection(Module.super.getDefaultJaxRsPackages()); - } - private Collection extract(Supplier> s) { - if(!resetAll) - return s.get(); - return Arrays.asList(); - } - private Map extractMap(Supplier> s) { - if(!resetAll) - return s.get(); - return HashMapBuilder.of(); - } - @Override - public Set> getRestResourceClasses() { - if(restResourceClasses!=null) - return PSetX.fromCollection(concat(restResourceClasses, extract(() -> Collections.singletonList(CommonRestResource.class)))); - - return Module.super.getRestResourceClasses(); - } - - @Override - public Set> getRestAnnotationClasses() { - if(restAnnotationClasses!=null) - return PSetX.fromCollection(concat(restAnnotationClasses, extract(() -> Module.super.getRestAnnotationClasses()))); - - return Module.super.getRestAnnotationClasses(); - } - - @Override - public List> getDefaultResources() { - if(this.defaultResources!=null){ - return PStackX.fromCollection((concat(this.defaultResources,extract(()->Module.super.getDefaultResources())))); - } - - return Module.super.getDefaultResources(); - } - - @Override - public List getListeners(ServerData data) { - if(listeners!=null) - return PStackX.fromCollection((concat(this.listeners, extract(()->Module.super.getListeners(data))))); - - return Module.super.getListeners(data); - } - - @Override - public List getRequestListeners(ServerData data) { - if(requestListeners!=null) - return PStackX.fromCollection(concat(this.requestListeners, - extract(()->Module.super.getRequestListeners(data)))); - - return Module.super.getRequestListeners(data); - } - - @Override - public Map getFilters(ServerData data) { - if(filters!=null) - return PMapX.fromMap(filters).plusAll(extractMap(()->Module.super.getFilters(data))); - - return Module.super.getFilters(data); - } - - @Override - public Map getServlets(ServerData data) { - if(servlets!=null) - return PMapX.fromMap(servlets).plusAll(extractMap(()->Module.super.getServlets(data))); - - return Module.super.getServlets(data); - } - - @Override - public String getJaxWsRsApplication() { - if(this.jaxWsRsApplication!=null) - return jaxWsRsApplication; - return Module.super.getJaxWsRsApplication(); - } - - @Override - public String getProviders() { - if(providers!=null) - return providers; - return Module.super.getProviders(); - } - - @Override - public String getContext() { - - return context; - } - - @Override - public Set> getSpringConfigurationClasses() { - if(this.springConfigurationClasses!=null) - return PSetX.fromCollection(concat(this.springConfigurationClasses, extract(()->Module.super.getSpringConfigurationClasses()))); - - return Module.super.getSpringConfigurationClasses(); - } - - @Override - public Map getServerProperties() { - if(serverProperties != null) { - return PMapX.fromMap(serverProperties).plusAll(extractMap(() -> Module.super.getServerProperties())); - } else { - return Module.super.getServerProperties(); - } - } - - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/module/ConfigureEnviroment.java b/micro-core/src/main/java/com/aol/micro/server/module/ConfigureEnviroment.java deleted file mode 100644 index 5429b1d64..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/module/ConfigureEnviroment.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.aol.micro.server.module; - -import java.util.Collection; -import java.util.Properties; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class ConfigureEnviroment { - - @Autowired(required = false) - private Collection modules; - - @Bean - public Environment environment(@Qualifier("propertyFactory") Properties props) { - if (modules == null) { - return new Environment(props); - } - return new Environment(props, modules); - } - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/module/EmbeddedModule.java b/micro-core/src/main/java/com/aol/micro/server/module/EmbeddedModule.java deleted file mode 100644 index 2c52f17f6..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/module/EmbeddedModule.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aol.micro.server.module; - -import java.lang.annotation.Annotation; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; - -import lombok.Getter; -@Getter -public class EmbeddedModule implements Module { - - private final PSetX> restAnnotationClasses; - private final PSetX> restResourceClasses; - private final String context; - - private EmbeddedModule(Iterable> restAnnotationClasses, String context){ - this.restAnnotationClasses = PSetX.fromIterable(restAnnotationClasses); - this.context = context; - this.restResourceClasses = PSetX.empty(); - } - - private EmbeddedModule(String context, Iterable> restTagClasses){ - this.context = context; - this.restResourceClasses = PSetX.fromIterable(restTagClasses); - this.restAnnotationClasses = PSetX.empty(); - } - - public static EmbeddedModule annotationModule(Iterable> restAnnotationClasses, String context){ - return new EmbeddedModule(restAnnotationClasses, context); - } - public static EmbeddedModule tagInterfaceModule(Iterable> restTagInterfaces, String context){ - return new EmbeddedModule( context,restTagInterfaces); - } -} diff --git a/micro-core/src/main/java/com/aol/micro/server/module/Environment.java b/micro-core/src/main/java/com/aol/micro/server/module/Environment.java deleted file mode 100644 index ee7ac7f8a..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/module/Environment.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.aol.micro.server.module; - -import java.net.InetAddress; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.Properties; -import java.util.stream.Collectors; - -import org.pcollections.HashTreePMap; - -import com.aol.cyclops.control.Try; - -public class Environment { - - private volatile Map modulePort; - private final Properties properties; - private volatile int nextPort = 8080; - - public Environment(Properties propertyFactory, Collection modules) { - modulePort = modules.stream().collect(Collectors.toMap(key -> key.getModule().getContext(), value -> value)); - this.properties = propertyFactory; - } - - public Environment(Properties propertyFactory) { - modulePort = HashTreePMap.empty(); - this.properties = propertyFactory; - - } - - public ModuleBean getModuleBean(Module module) { - return modulePort.get(module.getContext()); - } - - public void assureModule(Module module) { - if (!modulePort.containsKey(module.getContext())) { - Map builder = new HashMap<>(); - builder.putAll(modulePort); - builder.put(module.getContext(), ModuleBean.builder().host(getHost(module)).port(getPort(module)).build()); - modulePort = HashTreePMap.from(builder); - } - - } - - private String getHost(Module module) { - Try.CheckedSupplier s = ()->InetAddress.getLocalHost().getHostName(); - try{ - return Optional.ofNullable(properties.get(module.getContext() + ".host")).orElse(s.get()).toString(); - }catch(Throwable e){ - throw new RuntimeException(e); - } - } - - private int getPort(Module module) { - - return Integer.valueOf(Optional.ofNullable(properties.get(module.getContext() + ".port")).orElse(nextPort++).toString()); - } -} \ No newline at end of file diff --git a/micro-core/src/main/java/com/aol/micro/server/module/Module.java b/micro-core/src/main/java/com/aol/micro/server/module/Module.java deleted file mode 100644 index ab4a0eb1d..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/module/Module.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.aol.micro.server.module; - -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Consumer; - -import javax.servlet.Filter; -import javax.servlet.Servlet; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletRequestListener; - -import org.springframework.util.StringUtils; -import org.springframework.web.context.ContextLoaderListener; -import org.springframework.web.context.WebApplicationContext; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.data.collections.extensions.persistent.PMapX; -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.cyclops.data.collections.extensions.standard.ListX; -import com.aol.cyclops.data.collections.extensions.standard.SetX; -import com.aol.cyclops.util.stream.StreamUtils; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.PluginLoader; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Classes; -import com.aol.micro.server.servers.model.ServerData; - -public interface Module { - - default Set getJaxRsResourceObjects(){ - return PluginLoader.INSTANCE.plugins.get() - .flatMap(Plugin::jaxRsResourceObjects) - .toPSetX(); - } - - - default Map getServerProperties() { - return PMapX.empty(); - } - - default Consumer> getServerConfigManager(){ - return server->{}; - } - default Consumer> getResourceConfigManager(){ - return rc->{}; - } - default List getPackages(){ - return PStackX.empty(); - } - - default Map getPropertyOverrides(){ - return PMapX.empty(); - } - default Set> getSpringConfigurationClasses(){ - return PSetX.of(Classes.CORE_CLASSES.getClasses()); - } - default Set> getRestResourceClasses() { - return PSetX.of(RestResource.class); - } - default Set> getRestAnnotationClasses() { - return SetX.of(Rest.class); - } - - - default List getDefaultJaxRsPackages(){ - - return PluginLoader.INSTANCE.plugins.get().stream() - .filter(module -> module.servletContextListeners()!=null) - .flatMapIterable(Plugin::jaxRsPackages) - - .toPStackX(); - - } - - default List> getDefaultResources(){ - return PluginLoader.INSTANCE.plugins.get().stream() - .flatMapIterable(Plugin::jaxRsResources) - .toPStackX(); - - } - - default List getListeners(ServerData data){ - List list= new ArrayList<>(); - if(data.getRootContext() instanceof WebApplicationContext){ - list.add(new ContextLoaderListener((WebApplicationContext)data - .getRootContext())); - } - - ListX modules = PluginLoader.INSTANCE.plugins.get(); - - PStackX listeners = modules.stream() - .filter(module -> module.servletContextListeners()!=null) - .flatMapIterable(Plugin::servletContextListeners) - .map(fn->fn.apply(data)) - .toPStackX(); - - return listeners.plusAll(list); - } - default List getRequestListeners(ServerData data){ - - return PluginLoader.INSTANCE.plugins.get().stream() - .filter(module -> module.servletRequestListeners()!=null) - .flatMapIterable(Plugin::servletRequestListeners) - .map(fn->fn.apply(data)) - .toPStackX(); - - - } - default Map getFilters(ServerData data) { - Map map = new HashMap<>(); - - ReactiveSeq - .fromStream( - PluginLoader.INSTANCE.plugins.get() - .stream()) - .filter(module -> module.filters() != null) - .map(module -> module.filters().apply(data)) - .forEach(pluginMap -> map.putAll(pluginMap)); - return PMapX.fromMap(map); - } - - default Map getServlets(ServerData data) { - Map map = new HashMap<>(); - ReactiveSeq - .fromStream( - PluginLoader.INSTANCE.plugins.get() - .stream()) - .filter(module -> module.servlets() != null) - .map(module -> module.servlets().apply(data)) - .forEach(pluginMap -> map.putAll(pluginMap)); - return PMapX.fromMap(map); - - } - - default String getJaxWsRsApplication(){ - List jaxRsApplications = ReactiveSeq.fromStream(PluginLoader.INSTANCE.plugins.get().stream()) - .filter(module -> module.jaxWsRsApplication()!=null) - .map(Plugin::jaxWsRsApplication) - .flatMap(StreamUtils::optionalToStream) - .toList(); - if(jaxRsApplications.size()>1) { - throw new IncorrectJaxRsPluginsException("ERROR! Multiple jax-rs application plugins found, a possible solution is to remove micro-jackson or other jax-rs application provider from your classpath. " + jaxRsApplications); - - - }else if(jaxRsApplications.size()==0){ - throw new IncorrectJaxRsPluginsException("ERROR! No jax-rs application plugins found, a possible solution is to add micro-jackson to your classpath. "); - - - } - return jaxRsApplications.get(0); - } - default String getProviders(){ - String additional = ReactiveSeq - .fromStream( - PluginLoader.INSTANCE.plugins.get() - .stream()) - .peek(System.out::println) - .filter(module -> module.providers()!=null) - .flatMapIterable(Plugin::providers) - .join(","); - - if(StringUtils.isEmpty(additional)) - return "com.aol.micro.server.rest.providers"; - return "com.aol.micro.server.rest.providers,"+additional; - } - - public String getContext(); -} diff --git a/micro-core/src/main/java/com/aol/micro/server/module/ModuleBean.java b/micro-core/src/main/java/com/aol/micro/server/module/ModuleBean.java deleted file mode 100644 index 51d58a007..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/module/ModuleBean.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.aol.micro.server.module; - -import java.util.Map; - -import javax.servlet.Filter; - -import lombok.Getter; -import lombok.experimental.Builder; - - - -@Getter -public class ModuleBean { - - private final int port; - private final String host; - private final Module module; - - - - @Builder - public ModuleBean(int port, String host, Module module) { - - this.port = port; - this.host = host; - this.module = module; - - } - - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/module/RestResourceTagBuilder.java b/micro-core/src/main/java/com/aol/micro/server/module/RestResourceTagBuilder.java deleted file mode 100644 index be7457195..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/module/RestResourceTagBuilder.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.aol.micro.server.module; - -import static com.aol.micro.server.utility.UsefulStaticMethods.concat; - -import java.lang.annotation.Annotation; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.cyclops.util.ExceptionSoftener; -import com.aol.micro.server.auto.discovery.CommonRestResource; - -import lombok.Setter; - - -public class RestResourceTagBuilder { - - private final static Logger logger = LoggerFactory.getLogger(RestResourceTagBuilder.class); - - @Setter - private static PSetX> defaultTags= PSetX.of(CommonRestResource.class); - - public static PSetX> restResourceTags(String... classes){ - return (PSetX)PSetX.fromCollection(concat(Stream.of(classes).map(cl -> toClass(cl)).collect(Collectors.toList()),defaultTags)); - } - public static PSetX> restResourceTags(Class... classes){ - return (PSetX)PSetX.fromCollection(concat((List)Stream.of(classes).collect(Collectors.toList()),defaultTags)); - } - public static PSetX> restAnnotations(String... classes){ - return (PSetX)PSetX.fromCollection(concat(Stream.of(classes).map(cl -> toClass(cl)).collect(Collectors.toList()),defaultTags)); - } - public static PSetX> restAnnotations(Class... classes){ - return (PSetX)PSetX.fromCollection(concat(Stream.of(classes).collect(Collectors.toList()),defaultTags)); - } - - private static Class toClass(String cl) { - try { - - return Class.forName(cl,true,RestResourceTagBuilder.class.getClassLoader()); - } catch (ClassNotFoundException e) { - logger.error("Class not found for {}", cl); - ExceptionSoftener.throwSoftenedException(e); - } - return null; - } -} diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/ApplicationRegister.java b/micro-core/src/main/java/com/aol/micro/server/servers/ApplicationRegister.java deleted file mode 100644 index 37d2b7f5d..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/servers/ApplicationRegister.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.aol.micro.server.servers; - -import com.aol.micro.server.servers.model.ServerData; - -public interface ApplicationRegister { - - void register(ServerData[] array); - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/FilterConfigurer.java b/micro-core/src/main/java/com/aol/micro/server/servers/FilterConfigurer.java deleted file mode 100644 index 33b6e7483..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/servers/FilterConfigurer.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.aol.micro.server.servers; - -import java.util.EnumSet; - -import javax.servlet.DispatcherType; -import javax.servlet.Filter; -import javax.servlet.FilterRegistration.Dynamic; -import javax.servlet.ServletContext; - -import lombok.AllArgsConstructor; - - -import org.pcollections.PStack; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.aol.micro.server.auto.discovery.FilterConfiguration; -import com.aol.micro.server.servers.model.FilterData; -import com.aol.micro.server.servers.model.ServerData; - -@AllArgsConstructor -public class FilterConfigurer { - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final ServerData serverData; - private final PStack filterData; - - public void addFilters(ServletContext webappContext) { - - addExplicitlyDeclaredFilters(webappContext); - addAutoDiscoveredFilters(webappContext); - - } - - private void addAutoDiscoveredFilters(ServletContext webappContext) { - serverData - .getRootContext() - .getBeansOfType(FilterConfiguration.class) - .values() - .stream() - .filter(f->f.getMapping()!=null) - .filter(f->f.getMapping().length>0) - .peek(this::logFilter) - .forEach( - filter -> setInitParameters( - webappContext.addFilter(getName(filter), - getClass(filter)), filter) - .addMappingForUrlPatterns( - EnumSet.allOf(DispatcherType.class),true, - filter.getMapping())); - } - - private void addExplicitlyDeclaredFilters(ServletContext webappContext) { - for (FilterData filterData : filterData) { - Dynamic filterReg = webappContext.addFilter( - filterData.getFilterName(), filterData.getFilter()); - - filterReg.addMappingForUrlPatterns( - EnumSet.allOf(DispatcherType.class),true, - filterData.getMapping()); - logFilter(filterData); - } - } - private void logFilter(FilterData filter) { - logger.info("Registering {} filter on {}",filter.getFilter().getClass().getName(), filter.getMapping()); - - } - - private void logFilter(FilterConfiguration filter) { - - logger.info("Registering {} filter on {}",filter.getClass().getName(),filter.getMapping()[0]); - } - - private Class getClass(FilterConfiguration filter) { - if (filter.getFilter() != null) - return filter.getFilter(); - return (Class) filter.getClass(); - } - - private Dynamic setInitParameters(Dynamic addFilter, - FilterConfiguration filter) { - addFilter.setInitParameters(filter.getInitParameters()); - return addFilter; - } - - private String getName(FilterConfiguration filter) { - if (filter.getName() != null) - return filter.getName(); - return filter.getClass().getName(); - } - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/JaxRsServletConfigurer.java b/micro-core/src/main/java/com/aol/micro/server/servers/JaxRsServletConfigurer.java deleted file mode 100644 index 982e3bd0d..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/servers/JaxRsServletConfigurer.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.aol.micro.server.servers; - -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletContext; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.util.stream.StreamUtils; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.PluginLoader; -import com.aol.micro.server.module.IncorrectJaxRsPluginsException; -import com.aol.micro.server.rest.RestConfiguration; -import com.aol.micro.server.servers.model.ServerData; - -public class JaxRsServletConfigurer { - public void addServlet(ServerData serverData, ServletContext webappContext) { - - List restConfigList = ReactiveSeq.fromStream(PluginLoader.INSTANCE.plugins.get().stream()) - .filter(module -> module.restServletConfiguration()!=null) - .map(Plugin::restServletConfiguration) - .flatMap(StreamUtils::optionalToStream) - .toList(); - if(restConfigList.size()>1) { - throw new IncorrectJaxRsPluginsException("ERROR! Multiple jax-rs application plugins found " + restConfigList); - }else if(restConfigList.size()==0){ - throw new IncorrectJaxRsPluginsException("ERROR! No jax-rs application plugins found "); - } - - RestConfiguration config = restConfigList.get(0); - javax.servlet.ServletRegistration.Dynamic servletRegistration = webappContext.addServlet(config.getName() - +"-"+serverData.getModule().getContext(),config.getServlet()); - Map initParams = config.getInitParams(); - for(String key : initParams.keySet()){ - servletRegistration.setInitParameter(key,initParams.get(key)); - } - servletRegistration.setAsyncSupported(true); - servletRegistration.setInitParameter("javax.ws.rs.Application", serverData.getModule().getJaxWsRsApplication()); - servletRegistration.setInitParameter(config.getProvidersName(), serverData.getModule().getProviders()); - servletRegistration.setInitParameter("context", serverData.getModule().getContext()); - servletRegistration.setLoadOnStartup(1); - servletRegistration.addMapping(serverData.getBaseUrlPattern()); - } - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/ServerApplication.java b/micro-core/src/main/java/com/aol/micro/server/servers/ServerApplication.java deleted file mode 100644 index 03a1b840d..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/servers/ServerApplication.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.aol.micro.server.servers; - -import java.util.concurrent.CompletableFuture; - -import com.aol.micro.server.config.SSLProperties; -import com.aol.micro.server.servers.model.ServerData; - -public interface ServerApplication { - - void run(CompletableFuture start, JaxRsServletConfigurer jaxRsConfigurer, CompletableFuture end); - ServerData getServerData(); - ServerApplication withSSLProperties(SSLProperties sslProperties); -} diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/ServerApplicationFactory.java b/micro-core/src/main/java/com/aol/micro/server/servers/ServerApplicationFactory.java deleted file mode 100644 index 2950a8355..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/servers/ServerApplicationFactory.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.aol.micro.server.servers; - -import org.springframework.context.ApplicationContext; - -import com.aol.micro.server.module.Module; - -public interface ServerApplicationFactory { - - public ServerApplication createApp(Module module,ApplicationContext springContext); -} diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/ServletConfigurer.java b/micro-core/src/main/java/com/aol/micro/server/servers/ServletConfigurer.java deleted file mode 100644 index 269fb1994..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/servers/ServletConfigurer.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.aol.micro.server.servers; - -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletRegistration; - -import lombok.AllArgsConstructor; - - - - -import org.pcollections.PStack; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.aol.micro.server.auto.discovery.ServletConfiguration; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.servers.model.ServletData; - -@AllArgsConstructor -public class ServletConfigurer { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final ServerData serverData; - private final PStack servletData; - - public void addServlets(ServletContext webappContext) { - addExplicitlyDeclaredServlets(webappContext); - addAutoDiscoveredServlets(webappContext); - } - - private void addAutoDiscoveredServlets(ServletContext webappContext) { - serverData - .getRootContext() - .getBeansOfType(ServletConfiguration.class) - .values() - .forEach( - servlet -> { - setInitParameters( - webappContext.addServlet(getName(servlet), - getServlet(servlet)), servlet) - .addMapping(servlet.getMapping()); - logServlet(servlet); - }); - } - - private void addExplicitlyDeclaredServlets(ServletContext webappContext) { - for (ServletData servletData : servletData) { - ServletRegistration.Dynamic servletReg = webappContext.addServlet( - servletData.getServletName(), servletData.getServlet()); - servletReg.addMapping(servletData.getMapping()); - logServlet(servletData); - } - } - - private void logServlet(ServletData servlet) { - logger.info("Registering {} servlet on {}",servlet.getServlet().getClass().getName(), servlet.getMapping()); - - } - - private void logServlet(ServletConfiguration servlet) { - logger.info("Registering {} servlet on {}",servlet.getClass().getName(), servlet.getMapping()[0]); - } - - private Class getServlet(ServletConfiguration servlet) { - if (servlet.getServlet() != null) - return servlet.getServlet(); - return (Class) servlet.getClass(); - } - - private ServletRegistration.Dynamic setInitParameters( - ServletRegistration.Dynamic addServlet, ServletConfiguration servlet) { - addServlet.setInitParameters(servlet.getInitParameters()); - return addServlet; - } - - private String getName(ServletConfiguration servlet) { - if (servlet.getName() != null) - return servlet.getName(); - return servlet.getClass().getName(); - } - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/ServletContextListenerConfigurer.java b/micro-core/src/main/java/com/aol/micro/server/servers/ServletContextListenerConfigurer.java deleted file mode 100644 index 3ea3bf6df..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/servers/ServletContextListenerConfigurer.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.servers; - -import java.util.List; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletRequestListener; - -import lombok.AllArgsConstructor; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.aol.micro.server.servers.model.ServerData; - -@AllArgsConstructor -public class ServletContextListenerConfigurer { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final ServerData serverData; - private final List listenerData; - private final List listenerRequestData; - - public void addListeners(ServletContext webappContext) { - - serverData.getRootContext() - .getBeansOfType(ServletContextListener.class) - .values() - - .stream() - - .peek(this::logListener) - .forEach(listener -> webappContext.addListener(listener)); - listenerData.forEach(it -> webappContext.addListener(it)); - - serverData.getRootContext() - .getBeansOfType(ServletRequestListener.class) - .values() - .stream() - .peek(this::logListener) - .forEach(listener -> webappContext.addListener(listener)); - listenerRequestData.forEach(it -> webappContext.addListener(it)); - - } - private void logListener(ServletContextListener listener) { - logger.info("Registering servlet context listener {}", listener.getClass().getName()); - - } - private void logListener(ServletRequestListener listener) { - logger.info("Registering servlet request listener {}",listener.getClass().getName()); - - } - - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/model/AllData.java b/micro-core/src/main/java/com/aol/micro/server/servers/model/AllData.java deleted file mode 100644 index 103458a61..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/servers/model/AllData.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.aol.micro.server.servers.model; - -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.ServletContextListener; -import javax.servlet.ServletRequestListener; - -import lombok.Getter; -import lombok.experimental.Builder; - -import org.pcollections.ConsPStack; -import org.pcollections.PStack; - -import com.aol.micro.server.utility.UsefulStaticMethods; - -@Getter -@Builder -public class AllData { - - private final ServerData serverData; - private final PStack filterDataList; - private final PStack servletDataList; - private final PStack servletContextListeners; - private final PStack servletRequestListeners; - - public AllData(ServerData serverData, List filterDataList, - List servletDataList, - List servletContextListeners, - List servletRequestListeners ) { - - this.servletContextListeners = ConsPStack.from(UsefulStaticMethods.either(servletContextListeners, new ArrayList())); - - this.servletRequestListeners = ConsPStack.from(UsefulStaticMethods.either(servletRequestListeners, new ArrayList())); - - this.filterDataList = ConsPStack.from(UsefulStaticMethods.either(filterDataList, new ArrayList())); - this.servletDataList = ConsPStack.from(UsefulStaticMethods.either(servletDataList, new ArrayList())); - this.serverData = serverData; - } - -} - diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/model/ServerData.java b/micro-core/src/main/java/com/aol/micro/server/servers/model/ServerData.java deleted file mode 100644 index cb793b6fd..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/servers/model/ServerData.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.aol.micro.server.servers.model; - -import java.util.List; -import java.util.stream.Collectors; - -import javax.ws.rs.Path; - -import lombok.Getter; -import lombok.experimental.Builder; - -import org.jooq.lambda.tuple.Tuple; -import org.jooq.lambda.tuple.Tuple2; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.micro.server.module.Module; - -@Getter -@Builder -public class ServerData { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private final int port; - - private final PStackX resources; - private final ApplicationContext rootContext; - private final String baseUrlPattern; - private final Module module; - - public ServerData(int port, List resources, - ApplicationContext rootContext, - String baseUrlPattern, Module module) { - - this.port = port; - this.module = module; - this.resources = resources==null ? PStackX.of() : PStackX.fromCollection(resources); - this.rootContext = rootContext; - this.baseUrlPattern = baseUrlPattern; - } - - public ReactiveSeq> extractResources() { - - - return resources.stream().peek(resource -> logMissingPath(resource)) - .filter(resource-> resource.getClass().getAnnotation(Path.class)!=null) - .map(resource -> Tuple.tuple(resource.getClass().getName(), - resource.getClass().getAnnotation(Path.class).value())); - - - } - - private void logMissingPath(Object resource) { - if(resource.getClass().getAnnotation(Path.class)==null){ - logger.info("Resource with no path " + resource); - - } - } - - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/spring/SpringApplicationConfigurator.java b/micro-core/src/main/java/com/aol/micro/server/spring/SpringApplicationConfigurator.java deleted file mode 100644 index 044da84a5..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/spring/SpringApplicationConfigurator.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.aol.micro.server.spring; - -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.util.stream.StreamUtils; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.PluginLoader; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.config.ConfigAccessor; - -public class SpringApplicationConfigurator implements SpringBuilder { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public ConfigurableApplicationContext createSpringApp(Config config, Class... classes) { - - logger.debug("Configuring Spring"); - AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); - rootContext.setAllowCircularReferences(config.isAllowCircularReferences()); - rootContext.register(classes); - - rootContext.scan(config.getBasePackages()); - rootContext.refresh(); - logger.debug("Configuring Additional Spring Beans"); - ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) rootContext).getBeanFactory(); - - config.getDataSources().keySet().stream().filter(it -> !new ConfigAccessor().get().getDefaultDataSourceName().equals(it)).forEach(name -> { - - List dbConfig = getConfig(config,rootContext,beanFactory); - dbConfig.forEach( spring-> spring.createSpringApp(name) ); - - - - }); - logger.debug("Finished Configuring Spring"); - - return rootContext; - } - - - private List getConfig(Config config, AnnotationConfigWebApplicationContext rootContext, ConfigurableListableBeanFactory beanFactory) { - List result = - ReactiveSeq.fromStream(PluginLoader.INSTANCE.plugins.get().stream()) - .filter(module -> module.springDbConfigurer()!=null) - .map(Plugin::springDbConfigurer) - .flatMap(StreamUtils::optionalToStream) - .toList(); - result.forEach( next -> { - - - - next.setBeanFactory(beanFactory); - next.setRootContext(rootContext); - - next.setConfig(config); - - - - }); - return result; - - - } - - - - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/spring/SpringBuilder.java b/micro-core/src/main/java/com/aol/micro/server/spring/SpringBuilder.java deleted file mode 100644 index 284ac936e..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/spring/SpringBuilder.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.aol.micro.server.spring; - -import org.springframework.context.ConfigurableApplicationContext; - -import com.aol.micro.server.config.Config; - -public interface SpringBuilder { - public ConfigurableApplicationContext createSpringApp(Config config, Class...classes); -} diff --git a/micro-core/src/main/java/com/aol/micro/server/spring/SpringContextFactory.java b/micro-core/src/main/java/com/aol/micro/server/spring/SpringContextFactory.java deleted file mode 100644 index 31cc7eca0..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/spring/SpringContextFactory.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.aol.micro.server.spring; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import lombok.AllArgsConstructor; -import lombok.experimental.Wither; - -import org.pcollections.HashTreePSet; -import org.pcollections.PSet; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.util.ExceptionSoftener; -import com.aol.micro.server.ErrorCode; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.PluginLoader; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.config.Microserver; - - -@AllArgsConstructor -public class SpringContextFactory { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final PSet classes; - private final Config config; - @Wither - private final SpringBuilder springBuilder; - - public SpringContextFactory(Config config, Class c, Set> classes){ - Set s = new HashSet(classes); - s.addAll(config.getClasses()); - - s.add(c); - Microserver microserver = (Microserver) c.getAnnotation(Microserver.class); - final Set immutableS = s; - - s = Optional.ofNullable(microserver).flatMap(ms -> Optional.ofNullable(ms.blacklistedClasses())).map(bl -> { - Set blacklistedClasses = Arrays.stream(bl).collect(Collectors.toSet()); - return immutableS.stream().filter(clazz -> !blacklistedClasses.contains(clazz)).collect(Collectors.toSet()); - }).orElse(immutableS); - - this.classes = HashTreePSet.from(s); - this.config = config; - - springBuilder = ReactiveSeq - .fromStream(PluginLoader.INSTANCE.plugins.get().stream()) - .filter(m -> m.springBuilder() != null) - .map(Plugin::springBuilder) - .findFirst() - .orElse(new SpringApplicationConfigurator()); - } - public SpringContextFactory(SpringBuilder builder,Config config, Class c, Set> classes){ - Set s = new HashSet(classes); - s.addAll(config.getClasses()); - - s.add(c); - Microserver microserver = (Microserver) c.getAnnotation(Microserver.class); - final Set immutableS = s; - - s = Optional.ofNullable(microserver).flatMap(ms -> Optional.ofNullable(ms.blacklistedClasses())).map(bl -> { - Set blacklistedClasses = Arrays.stream(bl).collect(Collectors.toSet()); - return immutableS.stream().filter(clazz -> !blacklistedClasses.contains(clazz)).collect(Collectors.toSet()); - }).orElse(immutableS); - - this.classes = HashTreePSet.from(s); - this.config = config; - - springBuilder = builder; - - } - - public ApplicationContext createSpringContext() { - try { - ApplicationContext springContext = springBuilder.createSpringApp(config,classes.toArray(new Class[0])); - return springContext; - } catch (Exception e) { - logger.error( ErrorCode.STARTUP_FAILED_SPRING_INITIALISATION.toString(),e.getMessage()); - ExceptionSoftener.throwSoftenedException(e); - } - return null; - } - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/spring/properties/PropertyFileConfig.java b/micro-core/src/main/java/com/aol/micro/server/spring/properties/PropertyFileConfig.java deleted file mode 100644 index 6add47312..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/spring/properties/PropertyFileConfig.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.aol.micro.server.spring.properties; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.Properties; - -import lombok.Setter; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.config.PropertiesFactoryBean; -import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.FileSystemResource; -import org.springframework.core.io.Resource; -import org.springframework.core.io.UrlResource; - -import com.aol.micro.server.config.Config; -import com.aol.micro.server.config.ConfigAccessor; - -@Configuration -public class PropertyFileConfig { - - - private final static Logger logger = LoggerFactory.getLogger(PropertyFileConfig.class); - - public PropertyFileConfig(){ - - } - public PropertyFileConfig(boolean set){ - if(set) - new Config().set(); //make sure config instance is set - } - @Bean - public static PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() throws IOException { - - - - PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer(); - Properties props = propertyFactory(); - - configurer.setProperties(props); - configurer.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE); - return configurer; - } - - @Bean - public static Properties propertyFactory() throws IOException { - List resources = loadPropertyResource(); - PropertiesFactoryBean factory = new PropertiesFactoryBean(); - factory.setLocations(resources.toArray(new Resource[resources.size()])); - factory.afterPropertiesSet(); - Properties props = factory.getObject(); - props.putAll(new ConfigAccessor().get().getProperties()); - return props; - } - - private static List loadPropertyResource() { - List resources = new ArrayList<>(); - String applicationPropertyFileName = new ConfigAccessor().get().getPropertiesName(); - loadProperties(applicationPropertyFileName,"application").ifPresent(it -> resources.add(it)); - - String serviceTypePropertyFileName = new ConfigAccessor().get().getServiceTypePropertiesName(); - loadProperties(serviceTypePropertyFileName,"service-type").ifPresent(it -> resources.add(it)); - - - - String instancePropertyFileName = new ConfigAccessor().get().getInstancePropertiesName(); - loadProperties(instancePropertyFileName,"instance").ifPresent(it -> resources.add(it)); - - return resources; - } - - private static Optional loadProperties(String applicationPropertyFileName, String type) { - - - - Optional resource = Optional.empty(); - - if (new File("./" + applicationPropertyFileName).exists()) { - resource = Optional.of(new FileSystemResource(new File("./" + applicationPropertyFileName))); - logger.info("./" + applicationPropertyFileName + " added"); - } - - URL urlResource = PropertyFileConfig.class.getClassLoader().getResource(applicationPropertyFileName); - if (urlResource != null) { - resource = Optional.of(new UrlResource(urlResource)); - logger.info(applicationPropertyFileName + " added"); - } - - if (System.getProperty(type+".env") != null) { - URL envResource = PropertyFileConfig.class.getClassLoader().getResource(createEnvBasedPropertyFileName(applicationPropertyFileName)); - if (envResource != null) { - resource = Optional.of(new UrlResource(envResource)); - logger.info(createEnvBasedPropertyFileName(applicationPropertyFileName) + " added"); - } - - } - if (System.getProperty(type+".property.file") != null) { - resource = Optional.of(new FileSystemResource(new File(System.getProperty(type+".property.file")))); - logger.info(System.getProperty("application.property.file") + " added"); - - } - return resource; - } - - private static String createEnvBasedPropertyFileName(String applicationPropertyFileName) { - return applicationPropertyFileName.substring(0, applicationPropertyFileName.lastIndexOf(".")) + "-" + System.getProperty("application.env") - + ".properties"; - } - -} diff --git a/micro-core/src/main/java/com/aol/micro/server/utility/DistributedLockService.java b/micro-core/src/main/java/com/aol/micro/server/utility/DistributedLockService.java deleted file mode 100644 index b57c6be51..000000000 --- a/micro-core/src/main/java/com/aol/micro/server/utility/DistributedLockService.java +++ /dev/null @@ -1,11 +0,0 @@ - -package com.aol.micro.server.utility; - - -public interface DistributedLockService { - - boolean tryLock(String key); - - boolean tryReleaseLock(String key); - -} diff --git a/micro-core/src/main/java/com/oath/micro/server/GlobalState.java b/micro-core/src/main/java/com/oath/micro/server/GlobalState.java new file mode 100644 index 000000000..76fff3a99 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/GlobalState.java @@ -0,0 +1,18 @@ +package com.oath.micro.server; + + +import com.oath.micro.server.module.Module; + +import cyclops.reactive.collections.mutable.ListX; +import lombok.Getter; +import lombok.Setter; + +public class GlobalState { + + public static final GlobalState state = new GlobalState(); + + private GlobalState(){ } + + @Getter @Setter + private volatile ListX modules; +} diff --git a/micro-core/src/main/java/com/oath/micro/server/HealthStatusChecker.java b/micro-core/src/main/java/com/oath/micro/server/HealthStatusChecker.java new file mode 100644 index 000000000..870727fb3 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/HealthStatusChecker.java @@ -0,0 +1,7 @@ +package com.oath.micro.server; + +@FunctionalInterface +public interface HealthStatusChecker { + + boolean isOk(); +} diff --git a/micro-core/src/main/java/com/aol/micro/server/IncorrectNumberOfServersConfiguredException.java b/micro-core/src/main/java/com/oath/micro/server/IncorrectNumberOfServersConfiguredException.java similarity index 85% rename from micro-core/src/main/java/com/aol/micro/server/IncorrectNumberOfServersConfiguredException.java rename to micro-core/src/main/java/com/oath/micro/server/IncorrectNumberOfServersConfiguredException.java index c73269302..d69afcf37 100644 --- a/micro-core/src/main/java/com/aol/micro/server/IncorrectNumberOfServersConfiguredException.java +++ b/micro-core/src/main/java/com/oath/micro/server/IncorrectNumberOfServersConfiguredException.java @@ -1,4 +1,4 @@ -package com.aol.micro.server; +package com.oath.micro.server; public class IncorrectNumberOfServersConfiguredException extends RuntimeException { diff --git a/micro-core/src/main/java/com/oath/micro/server/InternalErrorCode.java b/micro-core/src/main/java/com/oath/micro/server/InternalErrorCode.java new file mode 100644 index 000000000..5480a401d --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/InternalErrorCode.java @@ -0,0 +1,13 @@ +package com.oath.micro.server; + +import lombok.Getter; + + + +@Getter +public enum InternalErrorCode { + GRIZZLY_SERVER_EXCEPTION, SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG, STARTUP_FAILED_SPRING_INITIALISATION + + +} + diff --git a/micro-core/src/main/java/com/oath/micro/server/MicroserverApp.java b/micro-core/src/main/java/com/oath/micro/server/MicroserverApp.java new file mode 100644 index 000000000..c96885923 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/MicroserverApp.java @@ -0,0 +1,178 @@ +package com.oath.micro.server; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import com.oath.cyclops.util.ExceptionSoftener; +import cyclops.companion.Streams; +import cyclops.reactive.collections.mutable.ListX; +import cyclops.reactive.ReactiveSeq; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; + + +import com.oath.micro.server.config.Config; +import com.oath.micro.server.config.MicroserverConfigurer; +import com.oath.micro.server.module.Module; +import com.oath.micro.server.servers.ApplicationRegister; +import com.oath.micro.server.servers.ServerApplication; +import com.oath.micro.server.servers.ServerApplicationFactory; +import com.oath.micro.server.servers.ServerRunner; +import com.oath.micro.server.spring.SpringContextFactory; + +import lombok.Getter; + +/** + * + * Startup class for Microserver instance + * + * @author johnmcclean + * + */ +public class MicroserverApp { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final ListX modules; + private final CompletableFuture end = new CompletableFuture(); + + @Getter + private final ApplicationContext springContext; + public final Class[] classes; + + /** + * This will construct a Spring context for this Microserver instance. + * The calling class will be used to determine the base package to auto-scan from for Spring Beans + * It will attempt to pick up an @Microservice annotation first, if not present the package of the calling class + * will be used. + * + * @param modules Multiple Microservice end points that can be deployed within a single Spring context + */ + public MicroserverApp(Module... modules) { + this.modules = ListX.of(modules); + GlobalState.state.setModules(this.modules); + initSpringProperties(modules[0]); + Class c = extractClass(); + springContext = new SpringContextFactory( + new MicroserverConfigurer().buildConfig(c), extractClass(), + modules[0].getSpringConfigurationClasses()).createSpringContext(); + classes=null; + + } + + /** + * This will construct a Spring context for this Microserver instance. + * The provided class will be used to determine the base package to auto-scan from for Spring Beans + * It will attempt to pick up an @Microservice annotation first, if not present the package of the provided class + * will be used. + * + * @param c Class used to configure Spring + * @param modules Multiple Microservice end points that can be deployed within a single Spring context + */ + public MicroserverApp(Class c, Module... modules) { + + this.modules = ListX.of(modules); + GlobalState.state.setModules(this.modules); + initSpringProperties(modules[0]); + springContext = new SpringContextFactory( + new MicroserverConfigurer().buildConfig(c), c, + modules[0].getSpringConfigurationClasses()).createSpringContext(); + classes=null; + + } + MicroserverApp(boolean sb,Class c, Module... modules) { + + this.modules = ListX.of(modules); + GlobalState.state.setModules(this.modules); + initSpringProperties(modules[0]); + springContext = null; + classes = new SpringContextFactory( + new MicroserverConfigurer().buildConfig(c), c, + modules[0].getSpringConfigurationClasses()).classes(); + + } + + private void initSpringProperties(Module m) { + + System.setProperty("server.servlet.context-path", "/" + m.getContext()); + + } + + private Class extractClass() { + try { + return Class.forName(new Exception().getStackTrace()[2].getClassName()); + } catch (ClassNotFoundException e) { + throw ExceptionSoftener.throwSoftenedException(e); + } + + } + + public void stop() { + + end.complete(true); + Config.reset(); + + } + + public void run() { + start().forEach(thread -> join(thread)); + } + + public List start() { + + List apps = modules.map(module -> createServer(module)); + + ServerRunner runner; + try { + + runner = new ServerRunner( + springContext.getBean(ApplicationRegister.class), apps, end); + } catch (BeansException e) { + runner = new ServerRunner( + apps, end); + } + + return runner.run(); + } + + private ServerApplication createServer(Module module) { + + List applications = ReactiveSeq.fromStream(PluginLoader.INSTANCE.plugins.get() + .stream()) + .filter(m -> m.serverApplicationFactory() != null) + .map(Plugin::serverApplicationFactory) + .flatMap(Streams::optionalToStream) + .toList(); + if (applications.size() > 1) { + logger.error("ERROR! Multiple server application factories found : The solution is remove one these plugins from your classpath ", + applications); + System.err.println("ERROR! Multiple server application factories found : The solution is remove one these plugins from your classpath " + + applications); + throw new IncorrectNumberOfServersConfiguredException( + "Multiple server application factories found : The solution is remove one these plugins from your classpath " + + applications); + } else if (applications.size() == 0) { + logger.error("ERROR! No server application factories found. If you using micro-spring-boot don't call MicroserverApp.start() method. A possible solution is add one of micro-grizzly or micro-tomcat to the classpath."); + System.err.println("ERROR! No server application factories found. If you using micro-spring-boot don't call MicroserverApp.start() method. A possible solution is add one of micro-grizzly or micro-tomcat to the classpath."); + throw new IncorrectNumberOfServersConfiguredException( + "No server application factories found. If you using micro-spring-boot don't call MicroserverApp.start() method. A possible solution is add one of micro-grizzly or micro-tomcat to the classpath. "); + + } + + ServerApplication app = applications.get(0) + .createApp(module, springContext); + return app; + } + + private void join(Thread thread) { + try { + thread.join(); + } catch (InterruptedException e) { + Thread.currentThread() + .interrupt(); + ExceptionSoftener.throwSoftenedException(e); + } + } + +} diff --git a/micro-core/src/main/java/com/oath/micro/server/MicroserverPlugins.java b/micro-core/src/main/java/com/oath/micro/server/MicroserverPlugins.java new file mode 100644 index 000000000..1f9128f16 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/MicroserverPlugins.java @@ -0,0 +1,33 @@ +package com.oath.micro.server; + +import com.oath.cyclops.util.ExceptionSoftener; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.Module; +import cyclops.reactive.ReactiveSeq; + +public class MicroserverPlugins { + + private final Class[] classes; + public MicroserverPlugins(Class... classes){ + ReactiveSeq rs= classes!=null ? ReactiveSeq.of(classes) : ReactiveSeq.empty(); + this.classes = rs + .appendStream(ReactiveSeq.of(new MicroserverApp(true,extractClass(),()->"").classes)) + .toArray(i->new Class[i]); + } + public MicroserverPlugins(Module mod, Class... classes){ + this.classes = ReactiveSeq.of(classes) + .appendStream(ReactiveSeq.of(new MicroserverApp(extractClass(),mod).classes)) + .toArray(i->new Class[i]); + } + public Class[] classes(){ + return this.classes; + } + private Class extractClass() { + try { + return Class.forName(new Exception().getStackTrace()[2].getClassName()); + } catch (ClassNotFoundException e) { + throw ExceptionSoftener.throwSoftenedException(e); + } + + } +} diff --git a/micro-core/src/main/java/com/aol/micro/server/Plugin.java b/micro-core/src/main/java/com/oath/micro/server/Plugin.java similarity index 75% rename from micro-core/src/main/java/com/aol/micro/server/Plugin.java rename to micro-core/src/main/java/com/oath/micro/server/Plugin.java index 2e32bcbf2..037d23215 100644 --- a/micro-core/src/main/java/com/aol/micro/server/Plugin.java +++ b/micro-core/src/main/java/com/oath/micro/server/Plugin.java @@ -1,4 +1,4 @@ -package com.aol.micro.server; +package com.oath.micro.server; import java.util.List; import java.util.Map; @@ -12,19 +12,20 @@ import javax.servlet.ServletRequestListener; import javax.ws.rs.core.FeatureContext; -import com.aol.cyclops.data.collections.extensions.persistent.PMapX; -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.micro.server.rest.RestConfiguration; -import com.aol.micro.server.servers.ServerApplicationFactory; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.spring.SpringBuilder; -import com.aol.micro.server.spring.SpringDBConfig; + +import com.oath.micro.server.rest.RestConfiguration; +import com.oath.micro.server.servers.ServerApplicationFactory; +import com.oath.micro.server.servers.model.ServerData; +import com.oath.micro.server.spring.SpringBuilder; +import com.oath.micro.server.spring.SpringDBConfig; import com.fasterxml.jackson.databind.Module; +import cyclops.reactive.collections.mutable.ListX; +import cyclops.reactive.collections.mutable.MapX; +import cyclops.reactive.collections.mutable.SetX; /** * To implement a plugin for Microserver, implement this interface in your library and add the fully resolved class name to - * META-INF/services/com.aol.micro.server.Plugin + * META-INF/services/com.oath.micro.server.Plugin * * in your library * @@ -49,7 +50,7 @@ default Optional restServletConfiguration(){ * @return Jackson feature properties */ default Function> jacksonFeatureProperties(){ - return context->PMapX.empty(); + return context-> MapX.empty(); } /** * @return jax-rs Application name @@ -68,25 +69,25 @@ default Optional serverApplicationFactory(){ * @return Jackson modules for this plugin */ default Set jacksonModules(){ - return PSetX.empty(); + return SetX.empty(); } /** * @return jax-rs Resources (Objects) for this plugin */ default Set jaxRsResourceObjects(){ - return PSetX.empty(); + return SetX.empty(); } /** * @return jax-rs Resources (Classes) for this plugin */ default Set> jaxRsResources(){ - return PSetX.empty(); + return SetX.empty(); } /** * @return jax-rs Packages for this plugin */ default Set jaxRsPackages(){ - return PSetX.empty(); + return SetX.empty(); } /** * @return Used for configuring Data Beans (or other Beans) directly into the ApplicationContext @@ -98,43 +99,43 @@ default Optional springDbConfigurer(){ * @return Spring configuration classes for this plugin */ default Set springClasses(){ - return PSetX.empty(); + return SetX.empty(); } /** * @return Servlet Context Listeners for this plugin */ default Set> servletContextListeners(){ - return PSetX.empty(); + return SetX.empty(); } /** * @return Servlet Request Listeners for this plugin */ default Set> servletRequestListeners(){ - return PSetX.empty(); + return SetX.empty(); } /** * @return Filters for this plugin */ default Function> filters(){ - return serverData -> PMapX.empty(); + return serverData -> MapX.empty(); } /** * @return Servlets for this plugin */ default Function> servlets(){ - return serverData -> PMapX.empty(); + return serverData -> MapX.empty(); } /** * @return jax-rs Providers for this plugin */ default List providers(){ - return PStackX.empty(); + return ListX.empty(); } /** * @return Jersey server properties for this plugin */ default Map getServerProperties() { - return PMapX.empty(); + return MapX.empty(); } } diff --git a/micro-core/src/main/java/com/oath/micro/server/PluginLoader.java b/micro-core/src/main/java/com/oath/micro/server/PluginLoader.java new file mode 100644 index 000000000..105165b52 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/PluginLoader.java @@ -0,0 +1,25 @@ +package com.oath.micro.server; + +import java.util.ServiceLoader; +import java.util.function.Supplier; + +import cyclops.reactive.collections.mutable.ListX; +import cyclops.function.FluentFunctions; +import cyclops.reactive.ReactiveSeq; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + + + +@NoArgsConstructor(access=AccessLevel.PRIVATE) +public class PluginLoader { + + public final static PluginLoader INSTANCE = new PluginLoader(); + + public final Supplier> plugins = FluentFunctions.of(this::load) + .memoize(); + + private ListX load(){ + return ReactiveSeq.fromIterable(ServiceLoader.load(Plugin.class)).to(ListX::fromIterable); + } +} diff --git a/micro-core/src/main/java/com/aol/micro/server/SchedulingConfiguration.java b/micro-core/src/main/java/com/oath/micro/server/SchedulingConfiguration.java similarity index 88% rename from micro-core/src/main/java/com/aol/micro/server/SchedulingConfiguration.java rename to micro-core/src/main/java/com/oath/micro/server/SchedulingConfiguration.java index ec4b5943b..017929e57 100644 --- a/micro-core/src/main/java/com/aol/micro/server/SchedulingConfiguration.java +++ b/micro-core/src/main/java/com/oath/micro/server/SchedulingConfiguration.java @@ -1,4 +1,4 @@ -package com.aol.micro.server; +package com.oath.micro.server; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.annotation.SchedulingConfigurer; diff --git a/micro-core/src/main/java/com/oath/micro/server/StatsSupplier.java b/micro-core/src/main/java/com/oath/micro/server/StatsSupplier.java new file mode 100644 index 000000000..c469af339 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/StatsSupplier.java @@ -0,0 +1,8 @@ +package com.oath.micro.server; + +import java.util.Map; +import java.util.function.Supplier; + +public interface StatsSupplier extends Supplier>> { + +} diff --git a/micro-core/src/main/java/com/aol/micro/server/WorkerThreads.java b/micro-core/src/main/java/com/oath/micro/server/WorkerThreads.java similarity index 83% rename from micro-core/src/main/java/com/aol/micro/server/WorkerThreads.java rename to micro-core/src/main/java/com/oath/micro/server/WorkerThreads.java index 8732fcf6d..97ae38fb5 100644 --- a/micro-core/src/main/java/com/aol/micro/server/WorkerThreads.java +++ b/micro-core/src/main/java/com/oath/micro/server/WorkerThreads.java @@ -1,10 +1,11 @@ -package com.aol.micro.server; +package com.oath.micro.server; + +import cyclops.function.FluentFunctions; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.function.Supplier; -import com.aol.cyclops.control.FluentFunctions; public class WorkerThreads { diff --git a/micro-core/src/main/java/com/oath/micro/server/auto/discovery/AutoFilterConfiguration.java b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/AutoFilterConfiguration.java new file mode 100644 index 000000000..344d22f15 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/AutoFilterConfiguration.java @@ -0,0 +1,15 @@ +package com.oath.micro.server.auto.discovery; + +import cyclops.control.Either; + +import javax.servlet.Filter; + + + +public interface AutoFilterConfiguration extends Filter, FilterConfiguration{ + + @Override + default Either,Filter> getFilter(){ + return Either.right(this); + } +} diff --git a/micro-core/src/main/java/com/oath/micro/server/auto/discovery/AutoServletConfiguration.java b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/AutoServletConfiguration.java new file mode 100644 index 000000000..ae94663f8 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/AutoServletConfiguration.java @@ -0,0 +1,17 @@ +package com.oath.micro.server.auto.discovery; + +import cyclops.control.Either; + +import javax.servlet.Servlet; + + +public interface AutoServletConfiguration extends Servlet,ServletConfiguration{ + + @Override + default Either,Servlet> getServlet(){ + return Either.right(this); + } + default String getName(){ + return this.getClass().getCanonicalName(); + } +} diff --git a/micro-core/src/main/java/com/oath/micro/server/auto/discovery/CommonRestResource.java b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/CommonRestResource.java new file mode 100644 index 000000000..69b502ce9 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/CommonRestResource.java @@ -0,0 +1,6 @@ +package com.oath.micro.server.auto.discovery; + +public interface CommonRestResource extends RestResource { + + +} diff --git a/micro-core/src/main/java/com/oath/micro/server/auto/discovery/FilterConfiguration.java b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/FilterConfiguration.java new file mode 100644 index 000000000..e42598fc2 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/FilterConfiguration.java @@ -0,0 +1,57 @@ +package com.oath.micro.server.auto.discovery; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.Filter; + +import cyclops.control.Either; + + + + +/** + * If creating a Plugin, create a FilterConfiguration Spring Bean rather than a Filter Spring Bean + * This is because Spring Boot may also create a Filter based of any Filter Beans (but exposed on all URLS) + * + * + * + * @author johnmcclean + * + */ +public interface FilterConfiguration { + + /** + * @return An array of URL mapping this filter should target + */ + public String[] getMapping(); + + + /** + * Either is an eXclusive Or type. It holds one of two types, and one (and only one) must + * be returned. In this case either a Filter class or a Filter Object. + * + * {@code + *
+	 *     return Either.left(MyFilter.class);
+	 *     
+	 * 
+ * } + * {@code + *
+	 *     return Either.right(new MyFilter());
+	 *     
+	 * 
+ * } + * + * @return + */ + Either,Filter> getFilter(); + + default String getName(){ + return null; + } + default Map getInitParameters(){ + return new HashMap<>(); + } +} diff --git a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/JaxRsResource.java b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/JaxRsResource.java similarity index 87% rename from micro-core/src/main/java/com/aol/micro/server/auto/discovery/JaxRsResource.java rename to micro-core/src/main/java/com/oath/micro/server/auto/discovery/JaxRsResource.java index f5bb3715c..1ce944b75 100644 --- a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/JaxRsResource.java +++ b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/JaxRsResource.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.auto.discovery; +package com.oath.micro.server.auto.discovery; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/JaxRsResourceWrapper.java b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/JaxRsResourceWrapper.java similarity index 85% rename from micro-core/src/main/java/com/aol/micro/server/auto/discovery/JaxRsResourceWrapper.java rename to micro-core/src/main/java/com/oath/micro/server/auto/discovery/JaxRsResourceWrapper.java index 31eeb7d5e..8c0ba7bd5 100644 --- a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/JaxRsResourceWrapper.java +++ b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/JaxRsResourceWrapper.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.auto.discovery; +package com.oath.micro.server.auto.discovery; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/Rest.java b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/Rest.java similarity index 88% rename from micro-core/src/main/java/com/aol/micro/server/auto/discovery/Rest.java rename to micro-core/src/main/java/com/oath/micro/server/auto/discovery/Rest.java index bf8fe1a64..b5f4edbf6 100644 --- a/micro-core/src/main/java/com/aol/micro/server/auto/discovery/Rest.java +++ b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/Rest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.auto.discovery; +package com.oath.micro.server.auto.discovery; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/micro-core/src/main/java/com/oath/micro/server/auto/discovery/RestResource.java b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/RestResource.java new file mode 100644 index 000000000..c8ea08d55 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/RestResource.java @@ -0,0 +1,14 @@ +package com.oath.micro.server.auto.discovery; + + + +public interface RestResource { + + /** + * @return true if singleton + */ + default boolean isSingleton(){ + return false; + } + +} diff --git a/micro-core/src/main/java/com/oath/micro/server/auto/discovery/ServletConfiguration.java b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/ServletConfiguration.java new file mode 100644 index 000000000..0285ff0e8 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/ServletConfiguration.java @@ -0,0 +1,48 @@ +package com.oath.micro.server.auto.discovery; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.Servlet; + +import cyclops.control.Either; + + + + +/* +* If creating a Plugin, create a ServletConfiguration Spring Bean rather than a Servlet Spring Bean +* This is because Spring Boot may also create a Servlet based of any Filter Beans (but exposed on all URLS) +*/ +public interface ServletConfiguration { + /** + * @return An array of URL mapping this servlet should target + */ + public String[] getMapping(); + default String getName(){ + return null; + } + default Map getInitParameters(){ + return new HashMap<>(); + } + /** + * Either is an eXclusive Or type. It holds one of two types, and one (and only one) must + * be returned. In this case either a Servlet class or a Servlet Object. + * + * {@code + *
+	 *     return Either.left(MyServlet.class);
+	 *     
+	 * 
+ * } + * + * {@code + *
+	 *     return Either.right(new MyServlet());
+	 *     
+	 * 
+ * } + * + */ + Either,Servlet> getServlet(); +} diff --git a/micro-core/src/main/java/com/oath/micro/server/auto/discovery/SingletonRestResource.java b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/SingletonRestResource.java new file mode 100644 index 000000000..696ffc7db --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/auto/discovery/SingletonRestResource.java @@ -0,0 +1,7 @@ +package com.oath.micro.server.auto.discovery; + +public interface SingletonRestResource extends RestResource{ + default boolean isSingleton(){ + return true; + } +} diff --git a/micro-core/src/main/java/com/oath/micro/server/config/Classes.java b/micro-core/src/main/java/com/oath/micro/server/config/Classes.java new file mode 100644 index 000000000..fcade1ea5 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/config/Classes.java @@ -0,0 +1,50 @@ +package com.oath.micro.server.config; + +import java.util.ArrayList; +import java.util.List; + +import lombok.Getter; +import nonautoscan.com.oath.micro.server.AopConfig; +import nonautoscan.com.oath.micro.server.SSLConfig; +import nonautoscan.com.oath.micro.server.ScheduleAndAsyncConfig; + +import com.oath.micro.server.module.ConfigureEnviroment; +import com.oath.micro.server.servers.AccessLogConfig; +import com.oath.micro.server.spring.properties.PropertyFileConfig; + +/** + * + * Collections of Spring configuration classes (Classes annotated with @Configuration) + * that configure various useful pieces of functionality - such as property file loading, + * datasources, scheduling etc + * + * @author johnmcclean + * + */ +public class Classes { + + /** + * CORE CLASSES are the Core Microserver Spring Configuration classes + * Property support, Guava Event Bus, Spring AOP & Scheduling + * Codahale Metrics, Event tracking etc + */ + public static final Classes CORE_CLASSES = new Classes(PropertyFileConfig.class, AopConfig.class, + ScheduleAndAsyncConfig.class, ConfigureEnviroment.class, AccessLogConfig.class, SSLConfig.class); + + + @Getter + private final Class[] classes; + + public Classes(Class... classes) { + this.classes = classes; + } + + public Classes combine(Classes c){ + List c1 = new ArrayList<>(); + for(Class next : classes) + c1.add(next); + for(Class next : c.classes) + c1.add(next); + return new Classes(c1.toArray(new Class[0])); + } +} diff --git a/micro-core/src/main/java/com/oath/micro/server/config/Config.java b/micro-core/src/main/java/com/oath/micro/server/config/Config.java new file mode 100644 index 000000000..3659b0c25 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/config/Config.java @@ -0,0 +1,97 @@ +package com.oath.micro.server.config; + +import java.util.Arrays; + + +import com.oath.cyclops.types.persistent.PersistentMap; +import com.oath.cyclops.types.persistent.PersistentSet; +import cyclops.data.*; +import java.util.List; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.experimental.Wither; + +/** + * + * Class for configuring a Spring Context for Microserver + * + * @author johnmcclean + * + */ +@AllArgsConstructor +@Getter +@Wither +public class Config { + + private final String defaultDataSourceName; + private final PersistentSet classes; + private final PersistentMap properties; + + private final String propertiesName; + private final String instancePropertiesName; + private final String serviceTypePropertiesName; + private final PersistentMap> dataSources; + private final boolean allowCircularReferences; + private final String[] basePackages; + + public Config() { + classes = HashSet.empty(); + properties = HashMap.empty(); + dataSources = HashMap.empty(); + defaultDataSourceName = "db"; + propertiesName = "application.properties"; + instancePropertiesName = "instance.properties"; + serviceTypePropertiesName = "service-type.properties"; + allowCircularReferences = false; + basePackages = new String[0]; + + } + + private static volatile Config instance = null; + + public Config set() { + instance = this; + return this; + } + + public static Config instance() { + instance = new Config(); + return instance; + } + + static Config get() { + return instance; + + } + + public static void reset() { + instance = null; + + } + + public Config withEntityScanDataSource(String dataSource, String... packages) { + PersistentMap> nm = dataSources.put(dataSource, Arrays.asList(packages)); + return this.withDataSources(nm); + } + + /** + * Define the packages that hibernate should scan for Hibernate entities + * Should be used in conjunction Microserver Spring Configuration classes @See Classes#HIBERNATE_CLASSES + * + * @param packages Packages to scan for hibernate entities + * @return New Config object, with configured packages + */ + public Config withEntityScan(String... packages) { + return this.withDataSources(dataSources.put(defaultDataSourceName, Arrays.asList(packages))); + } + + public Config withClassesArray(Class... classes) { + PersistentSet org = this.classes; + for (Class c : classes) + org = org.plus(c); + return this.withClasses(org); + } + +} diff --git a/micro-core/src/main/java/com/aol/micro/server/config/ConfigAccessor.java b/micro-core/src/main/java/com/oath/micro/server/config/ConfigAccessor.java similarity index 85% rename from micro-core/src/main/java/com/aol/micro/server/config/ConfigAccessor.java rename to micro-core/src/main/java/com/oath/micro/server/config/ConfigAccessor.java index ab40e66b3..e8fa1984f 100644 --- a/micro-core/src/main/java/com/aol/micro/server/config/ConfigAccessor.java +++ b/micro-core/src/main/java/com/oath/micro/server/config/ConfigAccessor.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.config; +package com.oath.micro.server.config; import java.util.function.Supplier; diff --git a/micro-core/src/main/java/com/oath/micro/server/config/Configurer.java b/micro-core/src/main/java/com/oath/micro/server/config/Configurer.java new file mode 100644 index 000000000..95500ae61 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/config/Configurer.java @@ -0,0 +1,5 @@ +package com.oath.micro.server.config; + +public interface Configurer { + public Config buildConfig(Class class1); +} diff --git a/micro-core/src/main/java/com/aol/micro/server/config/Microserver.java b/micro-core/src/main/java/com/oath/micro/server/config/Microserver.java similarity index 97% rename from micro-core/src/main/java/com/aol/micro/server/config/Microserver.java rename to micro-core/src/main/java/com/oath/micro/server/config/Microserver.java index 312227a6b..52bf48abd 100644 --- a/micro-core/src/main/java/com/aol/micro/server/config/Microserver.java +++ b/micro-core/src/main/java/com/oath/micro/server/config/Microserver.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.config; +package com.oath.micro.server.config; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/micro-core/src/main/java/com/aol/micro/server/config/MicroserverConfigurer.java b/micro-core/src/main/java/com/oath/micro/server/config/MicroserverConfigurer.java similarity index 78% rename from micro-core/src/main/java/com/aol/micro/server/config/MicroserverConfigurer.java rename to micro-core/src/main/java/com/oath/micro/server/config/MicroserverConfigurer.java index 601769ea4..a99aea4b0 100644 --- a/micro-core/src/main/java/com/aol/micro/server/config/MicroserverConfigurer.java +++ b/micro-core/src/main/java/com/oath/micro/server/config/MicroserverConfigurer.java @@ -1,17 +1,15 @@ -package com.aol.micro.server.config; +package com.oath.micro.server.config; + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.PluginLoader; +import cyclops.data.HashMap; +import cyclops.reactive.ReactiveSeq; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; - -import org.pcollections.HashTreePMap; -import org.pcollections.HashTreePSet; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.PluginLoader; public class MicroserverConfigurer implements Configurer { @@ -33,16 +31,16 @@ public Config buildConfig(Class class1) { Map properties = buildProperties(microserver); - return Config.instance().withBasePackages(basePackages).withEntityScan(microserver.entityScan()).withClasses(HashTreePSet.from(classes)) + return Config.instance().withBasePackages(basePackages).withEntityScan(microserver.entityScan()).withClasses(cyclops.data.HashSet.fromIterable(classes)) .withPropertiesName(microserver.propertiesName()).withInstancePropertiesName(microserver.instancePropertiesName()) .withServiceTypePropertiesName(microserver.serviceTypePropertiesName()) - .withAllowCircularReferences(microserver.allowCircularDependencies()).withProperties(HashTreePMap.from(properties)).set(); + .withAllowCircularReferences(microserver.allowCircularDependencies()).withProperties(HashMap.fromMap(properties)).set(); } private Map buildProperties(Microserver microserver) { Map properties = ReactiveSeq.of(microserver.properties()) .grouped(2) - .toMap(prop -> prop.get(0), prop -> prop.get(1)); + .toMap(prop -> prop.getOrElse(0,null), prop -> prop.getOrElse(1,null)); return properties; } diff --git a/micro-core/src/main/java/com/oath/micro/server/config/SSLProperties.java b/micro-core/src/main/java/com/oath/micro/server/config/SSLProperties.java new file mode 100644 index 000000000..8c6f0e458 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/config/SSLProperties.java @@ -0,0 +1,54 @@ +package com.oath.micro.server.config; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +import java.util.Optional; + + +@Getter +@Builder +@AllArgsConstructor +public class SSLProperties { + + private final String keyStoreFile; + private final String keyStorePass; + private final String trustStoreFile; + private final String trustStorePass; + private final String keyStoreType; + private final String keyStoreProvider; + private final String trustStoreType; + private final String trustStoreProvider; + private final String clientAuth; + private final String ciphers; + private final String protocol; + + public Optional getKeyStoreType() { + return Optional.ofNullable(keyStoreType); + } + public Optional getKeyStoreProvider() { + return Optional.ofNullable(keyStoreProvider); + } + public Optional getTrustStoreType() { + return Optional.ofNullable(trustStoreType); + } + public Optional getTrustStoreProvider() { + return Optional.ofNullable(trustStoreProvider); + } + public Optional getClientAuth() { + return Optional.ofNullable(clientAuth); + } + public Optional getCiphers() { + return Optional.ofNullable(ciphers); + } + public Optional getProtocol() { + return Optional.ofNullable(protocol); + } + public Optional getTrustStoreFile() { + return Optional.ofNullable(trustStoreFile); + } + public Optional getTrustStorePass() { + return Optional.ofNullable(trustStorePass); + } +} diff --git a/micro-core/src/main/java/com/oath/micro/server/module/ConfigurableModule.java b/micro-core/src/main/java/com/oath/micro/server/module/ConfigurableModule.java new file mode 100644 index 000000000..603460d11 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/module/ConfigurableModule.java @@ -0,0 +1,227 @@ +package com.oath.micro.server.module; + +import static com.oath.micro.server.utility.UsefulStaticMethods.concat; + +import java.lang.annotation.Annotation; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import javax.servlet.Filter; +import javax.servlet.Servlet; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletRequestListener; + +import com.oath.micro.server.auto.discovery.CommonRestResource; +import com.oath.micro.server.servers.model.ServerData; + +import com.oath.cyclops.types.persistent.PersistentMap; +import cyclops.reactive.collections.mutable.ListX; +import cyclops.reactive.collections.mutable.MapX; +import cyclops.reactive.collections.mutable.SetX; +import cyclops.data.HashMap; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.experimental.Wither; + + +@Builder +@AllArgsConstructor +public class ConfigurableModule implements Module { + @Wither + private final Set jaxRsResourceObjects; + @Wither + private final Set> restResourceClasses; + @Wither + private final Set> restAnnotationClasses; + @Wither + private final List> defaultResources; + @Wither + private final List listeners; + @Wither + private final List requestListeners; + @Wither + private final Map filters; + @Wither + private final Map servlets; + @Wither + private final String jaxWsRsApplication; + @Wither + private final String providers; + @Wither + private final String context; + @Wither + private final Set> springConfigurationClasses; + @Wither + private final Map propertyOverrides; + @Wither + private final List defaultJaxRsPackages; + + private final Consumer> serverConfigManager; + private final Consumer> resourceConfigManager; + @Wither + private final Map serverProperties; + @Wither + final boolean resetAll; + + + public ConfigurableModule withResourceConfigManager(Consumer> resourceConfigManager) { + return new ConfigurableModule(jaxRsResourceObjects, restResourceClasses, restAnnotationClasses, defaultResources, + listeners, requestListeners, filters, servlets, jaxWsRsApplication, providers, + context, springConfigurationClasses, propertyOverrides, defaultJaxRsPackages, serverConfigManager, + (Consumer) resourceConfigManager, serverProperties, resetAll); + } + + public ConfigurableModule withServerConfigManager(Consumer> serverConfigManager) { + return new ConfigurableModule(jaxRsResourceObjects, restResourceClasses, restAnnotationClasses, defaultResources, + listeners, requestListeners, filters, servlets, jaxWsRsApplication, providers, + context, springConfigurationClasses, propertyOverrides, defaultJaxRsPackages, + (Consumer) serverConfigManager, resourceConfigManager, serverProperties, resetAll); + } + + @Override + public Set getJaxRsResourceObjects() { + if (this.jaxRsResourceObjects != null) + return SetX.fromIterable(concat(this.jaxRsResourceObjects, extract(() -> Module.super.getJaxRsResourceObjects()))); + return Module.super.getJaxRsResourceObjects(); + } + + @Override + public Consumer> getServerConfigManager() { + if (serverConfigManager != null) + return (Consumer) serverConfigManager; + + return Module.super.getServerConfigManager(); + } + + @Override + public Consumer> getResourceConfigManager() { + if (resourceConfigManager != null) + return (Consumer) resourceConfigManager; + + return Module.super.getResourceConfigManager(); + } + + @Override + public List getDefaultJaxRsPackages() { + if (defaultJaxRsPackages != null) + return ListX.fromIterable(concat(defaultJaxRsPackages, extract(() -> Module.super.getDefaultJaxRsPackages()))); + + return ListX.fromIterable(Module.super.getDefaultJaxRsPackages()); + } + + private Collection extract(Supplier> s) { + if (!resetAll) + return s.get(); + return Arrays.asList(); + } + + //@TODO revert to return Map after cyclops X bug is fixed + private PersistentMap extractMap(Supplier> s) { + if (!resetAll) + return HashMap.fromMap(s.get()); + return HashMap.empty(); + } + + @Override + public Set> getRestResourceClasses() { + if (restResourceClasses != null) + return SetX.fromIterable(concat(restResourceClasses, extract(() -> Collections.singletonList(CommonRestResource.class)))); + + return Module.super.getRestResourceClasses(); + } + + @Override + public Set> getRestAnnotationClasses() { + if (restAnnotationClasses != null) + return SetX.fromIterable(concat(restAnnotationClasses, extract(() -> Module.super.getRestAnnotationClasses()))); + + return Module.super.getRestAnnotationClasses(); + } + + @Override + public List> getDefaultResources() { + if (this.defaultResources != null) { + return ListX.fromIterable((concat(this.defaultResources, extract(() -> Module.super.getDefaultResources())))); + } + + return Module.super.getDefaultResources(); + } + + @Override + public List getListeners(ServerData data) { + if (listeners != null) + return ListX.fromIterable((concat(this.listeners, extract(() -> Module.super.getListeners(data))))); + + return Module.super.getListeners(data); + } + + @Override + public List getRequestListeners(ServerData data) { + if (requestListeners != null) + return ListX.fromIterable(concat(this.requestListeners, + extract(() -> Module.super.getRequestListeners(data)))); + + return Module.super.getRequestListeners(data); + } + + @Override + public Map getFilters(ServerData data) { + if (filters != null) + return MapX.fromMap(filters).plusAll(extractMap(() -> Module.super.getFilters(data))); + + return Module.super.getFilters(data); + } + + @Override + public Map getServlets(ServerData data) { + if (servlets != null) + return MapX.fromMap(servlets).plusAll(extractMap(() -> Module.super.getServlets(data))); + + return Module.super.getServlets(data); + } + + @Override + public String getJaxWsRsApplication() { + if (this.jaxWsRsApplication != null) + return jaxWsRsApplication; + return Module.super.getJaxWsRsApplication(); + } + + @Override + public String getProviders() { + if (providers != null) + return providers; + return Module.super.getProviders(); + } + + @Override + public String getContext() { + + return context; + } + + @Override + public Set> getSpringConfigurationClasses() { + if (this.springConfigurationClasses != null) + return SetX.fromIterable(concat(this.springConfigurationClasses, extract(() -> Module.super.getSpringConfigurationClasses()))); + + return Module.super.getSpringConfigurationClasses(); + } + + @Override + public Map getServerProperties() { + if (serverProperties != null) { + return MapX.fromMap(serverProperties).plusAll(extractMap(() -> Module.super.getServerProperties())); + } else { + return Module.super.getServerProperties(); + } + } + + +} diff --git a/micro-core/src/main/java/com/oath/micro/server/module/ConfigureEnviroment.java b/micro-core/src/main/java/com/oath/micro/server/module/ConfigureEnviroment.java new file mode 100644 index 000000000..008551e17 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/module/ConfigureEnviroment.java @@ -0,0 +1,25 @@ +package com.oath.micro.server.module; + +import java.util.Collection; +import java.util.Properties; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ConfigureEnviroment { + + @Autowired(required = false) + private Collection modules; + + @Bean + public MicroserverEnvironment microserverEnvironment(@Qualifier("propertyFactory") Properties props) { + if (modules == null) { + return new MicroserverEnvironment(props); + } + return new MicroserverEnvironment(props, modules); + } + +} diff --git a/micro-core/src/main/java/com/oath/micro/server/module/EmbeddedModule.java b/micro-core/src/main/java/com/oath/micro/server/module/EmbeddedModule.java new file mode 100644 index 000000000..777ca1d7c --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/module/EmbeddedModule.java @@ -0,0 +1,33 @@ +package com.oath.micro.server.module; + +import java.lang.annotation.Annotation; + + +import cyclops.reactive.collections.mutable.SetX; +import lombok.Getter; +@Getter +public class EmbeddedModule implements Module { + + private final SetX> restAnnotationClasses; + private final SetX> restResourceClasses; + private final String context; + + private EmbeddedModule(Iterable> restAnnotationClasses, String context){ + this.restAnnotationClasses = SetX.fromIterable(restAnnotationClasses); + this.context = context; + this.restResourceClasses = SetX.empty(); + } + + private EmbeddedModule(String context, Iterable> restTagClasses){ + this.context = context; + this.restResourceClasses = SetX.fromIterable(restTagClasses); + this.restAnnotationClasses = SetX.empty(); + } + + public static EmbeddedModule annotationModule(Iterable> restAnnotationClasses, String context){ + return new EmbeddedModule(restAnnotationClasses, context); + } + public static EmbeddedModule tagInterfaceModule(Iterable> restTagInterfaces, String context){ + return new EmbeddedModule( context,restTagInterfaces); + } +} diff --git a/micro-core/src/main/java/com/aol/micro/server/module/IncorrectJaxRsPluginsException.java b/micro-core/src/main/java/com/oath/micro/server/module/IncorrectJaxRsPluginsException.java similarity index 80% rename from micro-core/src/main/java/com/aol/micro/server/module/IncorrectJaxRsPluginsException.java rename to micro-core/src/main/java/com/oath/micro/server/module/IncorrectJaxRsPluginsException.java index 45c90db30..ba1c81bee 100644 --- a/micro-core/src/main/java/com/aol/micro/server/module/IncorrectJaxRsPluginsException.java +++ b/micro-core/src/main/java/com/oath/micro/server/module/IncorrectJaxRsPluginsException.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.module; +package com.oath.micro.server.module; public class IncorrectJaxRsPluginsException extends RuntimeException { diff --git a/micro-core/src/main/java/com/aol/micro/server/module/JaxRsProvider.java b/micro-core/src/main/java/com/oath/micro/server/module/JaxRsProvider.java similarity index 83% rename from micro-core/src/main/java/com/aol/micro/server/module/JaxRsProvider.java rename to micro-core/src/main/java/com/oath/micro/server/module/JaxRsProvider.java index 1a0164728..04e7d3da4 100644 --- a/micro-core/src/main/java/com/aol/micro/server/module/JaxRsProvider.java +++ b/micro-core/src/main/java/com/oath/micro/server/module/JaxRsProvider.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.module; +package com.oath.micro.server.module; import lombok.AllArgsConstructor; diff --git a/micro-core/src/main/java/com/oath/micro/server/module/MicroserverEnvironment.java b/micro-core/src/main/java/com/oath/micro/server/module/MicroserverEnvironment.java new file mode 100644 index 000000000..e872b382c --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/module/MicroserverEnvironment.java @@ -0,0 +1,61 @@ +package com.oath.micro.server.module; + +import java.net.InetAddress; +import java.util.Collection; +import cyclops.data.HashMap; + +import java.util.Optional; +import java.util.Properties; + +import com.oath.cyclops.types.persistent.PersistentMap; +import cyclops.control.Try; + +import static cyclops.data.tuple.Tuple.tuple; + + +public class MicroserverEnvironment { + + private volatile PersistentMap modulePort; + private final Properties properties; + private volatile int nextPort = 8080; + + public MicroserverEnvironment(Properties propertyFactory, Collection modules) { + + modulePort = HashMap.fromStream(modules.stream().map(m-> tuple(m.getModule().getContext(),m))); + this.properties = propertyFactory; + } + + public MicroserverEnvironment(Properties propertyFactory) { + modulePort = HashMap.empty(); + this.properties = propertyFactory; + + } + + public ModuleBean getModuleBean(Module module) { + return modulePort.getOrElse(module.getContext(),null); + } + + public void assureModule(Module module) { + if (!modulePort.containsKey(module.getContext())) { + HashMap builder = HashMap.empty(); + builder = builder.putAll(modulePort); + builder = builder.put(module.getContext(), ModuleBean.builder().host(getHost(module)).port(getPort(module)).build()); + modulePort = builder; + } + + } + + private String getHost(Module module) { + Try.CheckedSupplier s = ()->InetAddress.getLocalHost().getHostName(); + try{ + return Optional.ofNullable(properties.get(module.getContext() + ".host")).orElse(s.get()).toString(); + }catch(Throwable e){ + throw new RuntimeException(e); + } + } + + private int getPort(Module module) { + + return Integer.valueOf(Optional.ofNullable(properties.get(module.getContext() + ".port")).orElse(nextPort++).toString()); + } +} diff --git a/micro-core/src/main/java/com/oath/micro/server/module/Module.java b/micro-core/src/main/java/com/oath/micro/server/module/Module.java new file mode 100644 index 000000000..f92a8801d --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/module/Module.java @@ -0,0 +1,173 @@ +package com.oath.micro.server.module; + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.PluginLoader; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Classes; +import com.oath.micro.server.servers.model.ServerData; +import cyclops.reactive.collections.mutable.MapX; +import cyclops.companion.Streams; +import cyclops.reactive.collections.mutable.ListX; +import cyclops.reactive.collections.mutable.SetX; +import cyclops.reactive.ReactiveSeq; +import org.springframework.util.StringUtils; +import org.springframework.web.context.ContextLoaderListener; +import org.springframework.web.context.WebApplicationContext; + +import javax.servlet.Filter; +import javax.servlet.Servlet; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletRequestListener; +import java.lang.annotation.Annotation; +import java.util.*; +import java.util.function.Consumer; + +public interface Module { + + default Set getJaxRsResourceObjects() { + return PluginLoader.INSTANCE.plugins.get() + .concatMap(Plugin::jaxRsResourceObjects) + .to().setX(); + } + + default Map getServerProperties() { + return new HashMap<>(); + } + + default Consumer> getServerConfigManager() { + return server -> { + }; + } + + default Consumer> getResourceConfigManager() { + return rc -> { + }; + } + + default List getPackages() { + return new ArrayList<>(); + } + + default Map getPropertyOverrides() { + return new HashMap<>(); + } + + default Set> getSpringConfigurationClasses() { + return SetX.of(Classes.CORE_CLASSES.getClasses()); + } + + default Set> getRestResourceClasses() { + return SetX.of(RestResource.class); + } + + default Set> getRestAnnotationClasses() { + return SetX.of(Rest.class); + } + + default List getDefaultJaxRsPackages() { + + return PluginLoader.INSTANCE.plugins.get() + .stream() + .filter(module -> module.servletContextListeners() != null) + .concatMap(Plugin::jaxRsPackages) + .to(ListX::fromIterable); + + } + + default List> getDefaultResources() { + return PluginLoader.INSTANCE.plugins.get() + .stream() + .concatMap(Plugin::jaxRsResources) + .to(ListX::fromIterable); + + } + + default List getListeners(ServerData data) { + List list = new ArrayList<>(); + if (data.getRootContext() instanceof WebApplicationContext) { + list.add(new ContextLoaderListener( + (WebApplicationContext) data.getRootContext())); + } + + ListX modules = PluginLoader.INSTANCE.plugins.get(); + + ListX listeners = modules.stream() + .filter(module -> module.servletContextListeners() != null) + .concatMap(Plugin::servletContextListeners) + .map(fn -> fn.apply(data)) + .to(ListX::fromIterable); + + return listeners.plusAll(list); + } + + default List getRequestListeners(ServerData data) { + + return PluginLoader.INSTANCE.plugins.get() + .stream() + .filter(module -> module.servletRequestListeners() != null) + .concatMap(Plugin::servletRequestListeners) + .map(fn -> fn.apply(data)) + .to(ListX::fromIterable); + + } + + default Map getFilters(ServerData data) { + Map map = new HashMap<>(); + + ReactiveSeq.fromStream(PluginLoader.INSTANCE.plugins.get() + .stream()) + .filter(module -> module.filters() != null) + .map(module -> module.filters() + .apply(data)) + .forEach(pluginMap -> map.putAll(pluginMap)); + return MapX.fromMap(map); + } + + default Map getServlets(ServerData data) { + Map map = new HashMap<>(); + ReactiveSeq.fromStream(PluginLoader.INSTANCE.plugins.get() + .stream()) + .filter(module -> module.servlets() != null) + .map(module -> module.servlets() + .apply(data)) + .forEach(pluginMap -> map.putAll(pluginMap)); + return MapX.fromMap(map); + + } + + default String getJaxWsRsApplication() { + List jaxRsApplications = ReactiveSeq.fromStream(PluginLoader.INSTANCE.plugins.get() + .stream()) + .filter(module -> module.jaxWsRsApplication() != null) + .map(Plugin::jaxWsRsApplication) + .flatMap(Streams::optionalToStream) + .toList(); + if (jaxRsApplications.size() > 1) { + throw new IncorrectJaxRsPluginsException( + "ERROR! Multiple jax-rs application plugins found, a possible solution is to remove micro-jackson or other jax-rs application provider from your classpath. " + + jaxRsApplications); + + } else if (jaxRsApplications.size() == 0) { + throw new IncorrectJaxRsPluginsException( + "ERROR! No jax-rs application plugins found, a possible solution is to add micro-jackson to your classpath. "); + + } + return jaxRsApplications.get(0); + } + + default String getProviders() { + String additional = ReactiveSeq.fromStream(PluginLoader.INSTANCE.plugins.get() + .stream()) + .peek(System.out::println) + .filter(module -> module.providers() != null) + .concatMap(Plugin::providers) + .join(","); + + if (StringUtils.isEmpty(additional)) + return "com.oath.micro.server.rest.providers"; + return "com.oath.micro.server.rest.providers," + additional; + } + + public String getContext(); +} diff --git a/micro-core/src/main/java/com/oath/micro/server/module/ModuleBean.java b/micro-core/src/main/java/com/oath/micro/server/module/ModuleBean.java new file mode 100644 index 000000000..09d5ffd0b --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/module/ModuleBean.java @@ -0,0 +1,27 @@ +package com.oath.micro.server.module; + +import lombok.Getter; +import lombok.Builder; + + + +@Getter +public class ModuleBean { + + private final int port; + private final String host; + private final Module module; + + + + @Builder + public ModuleBean(int port, String host, Module module) { + + this.port = port; + this.host = host; + this.module = module; + + } + + +} diff --git a/micro-core/src/main/java/com/aol/micro/server/module/ModuleDataExtractor.java b/micro-core/src/main/java/com/oath/micro/server/module/ModuleDataExtractor.java similarity index 76% rename from micro-core/src/main/java/com/aol/micro/server/module/ModuleDataExtractor.java rename to micro-core/src/main/java/com/oath/micro/server/module/ModuleDataExtractor.java index a13009fa0..739bb8635 100644 --- a/micro-core/src/main/java/com/aol/micro/server/module/ModuleDataExtractor.java +++ b/micro-core/src/main/java/com/oath/micro/server/module/ModuleDataExtractor.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.module; +package com.oath.micro.server.module; import java.util.ArrayList; import java.util.List; @@ -8,15 +8,16 @@ import javax.servlet.Filter; import javax.servlet.Servlet; +import cyclops.reactive.collections.immutable.LinkedListX; import org.springframework.context.ApplicationContext; import org.springframework.web.filter.DelegatingFilterProxy; -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.micro.server.auto.discovery.JaxRsResource; -import com.aol.micro.server.auto.discovery.JaxRsResourceWrapper; -import com.aol.micro.server.servers.model.FilterData; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.servers.model.ServletData; + +import com.oath.micro.server.auto.discovery.JaxRsResource; +import com.oath.micro.server.auto.discovery.JaxRsResourceWrapper; +import com.oath.micro.server.servers.model.FilterData; +import com.oath.micro.server.servers.model.ServerData; +import com.oath.micro.server.servers.model.ServletData; import lombok.AllArgsConstructor; @@ -25,7 +26,7 @@ public class ModuleDataExtractor { private final Module module; - public PStackX getRestResources( ApplicationContext rootContext){ + public LinkedListX getRestResources(ApplicationContext rootContext){ List resources = new ArrayList<>(); module.getRestResourceClasses().forEach(it -> resources.addAll(rootContext.getBeansOfType(it).values())); @@ -33,7 +34,7 @@ public PStackX getRestResources( ApplicationContext rootContext){ rootContext.getBeansWithAnnotation(JaxRsResource.class).forEach((n,it)->resources.add(it)); rootContext.getBeansOfType(JaxRsResourceWrapper.class).forEach((n,it)->resources.add(it.getResource())); resources.addAll(module.getJaxRsResourceObjects()); - return PStackX.fromCollection(resources); + return LinkedListX.fromIterable(resources); } diff --git a/micro-core/src/main/java/com/oath/micro/server/module/RestResourceTagBuilder.java b/micro-core/src/main/java/com/oath/micro/server/module/RestResourceTagBuilder.java new file mode 100644 index 000000000..e75c5b31c --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/module/RestResourceTagBuilder.java @@ -0,0 +1,51 @@ +package com.oath.micro.server.module; + +import static com.oath.micro.server.utility.UsefulStaticMethods.concat; + +import java.lang.annotation.Annotation; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.oath.cyclops.util.ExceptionSoftener; +import cyclops.reactive.collections.mutable.SetX; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +import com.oath.micro.server.auto.discovery.CommonRestResource; + +import lombok.Setter; + + +public class RestResourceTagBuilder { + + private final static Logger logger = LoggerFactory.getLogger(RestResourceTagBuilder.class); + + @Setter + private static SetX> defaultTags= SetX.of(CommonRestResource.class); + + public static SetX> restResourceTags(String... classes){ + return (SetX)SetX.fromIterable(concat(Stream.of(classes).map(cl -> toClass(cl)).collect(Collectors.toList()),defaultTags)); + } + public static SetX> restResourceTags(Class... classes){ + return (SetX)SetX.fromIterable(concat((List)Stream.of(classes).collect(Collectors.toList()),defaultTags)); + } + public static SetX> restAnnotations(String... classes){ + return (SetX)SetX.fromIterable(concat(Stream.of(classes).map(cl -> toClass(cl)).collect(Collectors.toList()),defaultTags)); + } + public static SetX> restAnnotations(Class... classes){ + return (SetX)SetX.fromIterable(concat(Stream.of(classes).collect(Collectors.toList()),defaultTags)); + } + + private static Class toClass(String cl) { + try { + + return Class.forName(cl,true,RestResourceTagBuilder.class.getClassLoader()); + } catch (ClassNotFoundException e) { + logger.error("Class not found for {}", cl); + ExceptionSoftener.throwSoftenedException(e); + } + return null; + } +} diff --git a/micro-core/src/main/java/com/aol/micro/server/module/WebServerProvider.java b/micro-core/src/main/java/com/oath/micro/server/module/WebServerProvider.java similarity index 83% rename from micro-core/src/main/java/com/aol/micro/server/module/WebServerProvider.java rename to micro-core/src/main/java/com/oath/micro/server/module/WebServerProvider.java index 08f26d08f..89ca81d69 100644 --- a/micro-core/src/main/java/com/aol/micro/server/module/WebServerProvider.java +++ b/micro-core/src/main/java/com/oath/micro/server/module/WebServerProvider.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.module; +package com.oath.micro.server.module; import lombok.AllArgsConstructor; diff --git a/micro-core/src/main/java/com/aol/micro/server/rest/RestConfiguration.java b/micro-core/src/main/java/com/oath/micro/server/rest/RestConfiguration.java similarity index 94% rename from micro-core/src/main/java/com/aol/micro/server/rest/RestConfiguration.java rename to micro-core/src/main/java/com/oath/micro/server/rest/RestConfiguration.java index 141baedf9..708f5c181 100644 --- a/micro-core/src/main/java/com/aol/micro/server/rest/RestConfiguration.java +++ b/micro-core/src/main/java/com/oath/micro/server/rest/RestConfiguration.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.rest; +package com.oath.micro.server.rest; import java.util.Map; diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/AccessLogConfig.java b/micro-core/src/main/java/com/oath/micro/server/servers/AccessLogConfig.java similarity index 91% rename from micro-core/src/main/java/com/aol/micro/server/servers/AccessLogConfig.java rename to micro-core/src/main/java/com/oath/micro/server/servers/AccessLogConfig.java index 4c7c4550d..4df9cabe1 100644 --- a/micro-core/src/main/java/com/aol/micro/server/servers/AccessLogConfig.java +++ b/micro-core/src/main/java/com/oath/micro/server/servers/AccessLogConfig.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.servers; +package com.oath.micro.server.servers; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/AccessLogLocationBean.java b/micro-core/src/main/java/com/oath/micro/server/servers/AccessLogLocationBean.java similarity index 85% rename from micro-core/src/main/java/com/aol/micro/server/servers/AccessLogLocationBean.java rename to micro-core/src/main/java/com/oath/micro/server/servers/AccessLogLocationBean.java index 1e106713a..d00697ebd 100644 --- a/micro-core/src/main/java/com/aol/micro/server/servers/AccessLogLocationBean.java +++ b/micro-core/src/main/java/com/oath/micro/server/servers/AccessLogLocationBean.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.servers; +package com.oath.micro.server.servers; import lombok.Getter; diff --git a/micro-core/src/main/java/com/oath/micro/server/servers/ApplicationRegister.java b/micro-core/src/main/java/com/oath/micro/server/servers/ApplicationRegister.java new file mode 100644 index 000000000..1da9bcc66 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/servers/ApplicationRegister.java @@ -0,0 +1,9 @@ +package com.oath.micro.server.servers; + +import com.oath.micro.server.servers.model.ServerData; + +public interface ApplicationRegister { + + void register(ServerData[] array); + +} diff --git a/micro-core/src/main/java/com/oath/micro/server/servers/FilterConfigurer.java b/micro-core/src/main/java/com/oath/micro/server/servers/FilterConfigurer.java new file mode 100644 index 000000000..51e030a63 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/servers/FilterConfigurer.java @@ -0,0 +1,100 @@ +package com.oath.micro.server.servers; + +import java.util.EnumSet; + +import javax.servlet.DispatcherType; +import javax.servlet.FilterRegistration.Dynamic; +import javax.servlet.ServletContext; + +import com.oath.cyclops.types.persistent.PersistentList; +import lombok.AllArgsConstructor; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.oath.micro.server.auto.discovery.FilterConfiguration; +import com.oath.micro.server.servers.model.FilterData; +import com.oath.micro.server.servers.model.ServerData; + +@AllArgsConstructor +public class FilterConfigurer { + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final ServerData serverData; + private final PersistentList filterData; + + public void addFilters(ServletContext webappContext) { + + addExplicitlyDeclaredFilters(webappContext); + addAutoDiscoveredFilters(webappContext); + + } + + private void handleFilter(FilterConfiguration filter,ServletContext webappContext){ + filter.getFilter().fold(clazz-> { + setInitParameters(webappContext.addFilter(getName(filter), + clazz), filter) + .addMappingForUrlPatterns( + EnumSet.allOf(DispatcherType.class),true, + filter.getMapping()); + return 1; + }, obj-> { + Dynamic filterReg = webappContext.addFilter( + getName(filter), obj); + + filterReg.addMappingForUrlPatterns( + EnumSet.allOf(DispatcherType.class),true, + filter.getMapping()); + + return 2; + }); + } + private void addAutoDiscoveredFilters(ServletContext webappContext) { + serverData + .getRootContext() + .getBeansOfType(FilterConfiguration.class) + .values() + .stream() + .filter(f->f.getMapping()!=null) + .filter(f->f.getMapping().length>0) + .peek(this::logFilter) + .forEach(config->handleFilter(config,webappContext)); + + } + + private void addExplicitlyDeclaredFilters(ServletContext webappContext) { + for (FilterData filterData : filterData) { + Dynamic filterReg = webappContext.addFilter( + filterData.getFilterName(), filterData.getFilter()); + + filterReg.addMappingForUrlPatterns( + EnumSet.allOf(DispatcherType.class),true, + filterData.getMapping()); + logFilter(filterData); + } + } + private void logFilter(FilterData filter) { + logger.info("Registering {} filter on {}",filter.getFilter().getClass().getName(), filter.getMapping()); + + } + + private void logFilter(FilterConfiguration filter) { + + logger.info("Registering {} filter on {}",filter.getClass().getName(),filter.getMapping()[0]); + } + + + + private Dynamic setInitParameters(Dynamic addFilter, + FilterConfiguration filter) { + addFilter.setInitParameters(filter.getInitParameters()); + return addFilter; + } + + private String getName(FilterConfiguration filter) { + if (filter.getName() != null) + return filter.getName(); + return filter.getClass().getName(); + } + +} diff --git a/micro-core/src/main/java/com/oath/micro/server/servers/JaxRsServletConfigurer.java b/micro-core/src/main/java/com/oath/micro/server/servers/JaxRsServletConfigurer.java new file mode 100644 index 000000000..acaffe3ce --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/servers/JaxRsServletConfigurer.java @@ -0,0 +1,54 @@ +package com.oath.micro.server.servers; + +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.PluginLoader; +import com.oath.micro.server.module.IncorrectJaxRsPluginsException; +import com.oath.micro.server.rest.RestConfiguration; +import com.oath.micro.server.servers.model.ServerData; +import cyclops.companion.Streams; +import cyclops.reactive.ReactiveSeq; + +public class JaxRsServletConfigurer { + public void addServlet(ServerData serverData, ServletContext webappContext) { + + List restConfigList = ReactiveSeq.fromStream(PluginLoader.INSTANCE.plugins.get() + .stream()) + .filter(module -> module.restServletConfiguration() != null) + .map(Plugin::restServletConfiguration) + .flatMap(Streams::optionalToStream) + .toList(); + if (restConfigList.size() > 1) { + throw new IncorrectJaxRsPluginsException( + "ERROR! Multiple jax-rs application plugins found " + + restConfigList); + } else if (restConfigList.size() == 0) { + throw new IncorrectJaxRsPluginsException( + "ERROR! No jax-rs application plugins found "); + } + + RestConfiguration config = restConfigList.get(0); + javax.servlet.ServletRegistration.Dynamic servletRegistration = webappContext.addServlet(config.getName() + "-" + + serverData.getModule() + .getContext(), config.getServlet()); + Map initParams = config.getInitParams(); + for (String key : initParams.keySet()) { + servletRegistration.setInitParameter(key, initParams.get(key)); + } + servletRegistration.setAsyncSupported(true); + servletRegistration.setInitParameter("javax.ws.rs.Application", serverData.getModule() + .getJaxWsRsApplication()); + servletRegistration.setInitParameter(config.getProvidersName(), serverData.getModule() + .getProviders()); + servletRegistration.setInitParameter("context", serverData.getModule() + .getContext()); + servletRegistration.setLoadOnStartup(1); + servletRegistration.addMapping(serverData.getBaseUrlPattern()); + } + +} diff --git a/micro-core/src/main/java/com/oath/micro/server/servers/ServerApplication.java b/micro-core/src/main/java/com/oath/micro/server/servers/ServerApplication.java new file mode 100644 index 000000000..4375c7651 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/servers/ServerApplication.java @@ -0,0 +1,10 @@ +package com.oath.micro.server.servers; + +import java.util.concurrent.CompletableFuture; + +import com.oath.micro.server.servers.model.ServerData; + +public interface ServerApplication { + void run(CompletableFuture start, JaxRsServletConfigurer jaxRsConfigurer, CompletableFuture end); + ServerData getServerData(); +} diff --git a/micro-core/src/main/java/com/oath/micro/server/servers/ServerApplicationFactory.java b/micro-core/src/main/java/com/oath/micro/server/servers/ServerApplicationFactory.java new file mode 100644 index 000000000..08dd26a4a --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/servers/ServerApplicationFactory.java @@ -0,0 +1,10 @@ +package com.oath.micro.server.servers; + +import org.springframework.context.ApplicationContext; + +import com.oath.micro.server.module.Module; + +public interface ServerApplicationFactory { + + public ServerApplication createApp(Module module,ApplicationContext springContext); +} diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/ServerRunner.java b/micro-core/src/main/java/com/oath/micro/server/servers/ServerRunner.java similarity index 84% rename from micro-core/src/main/java/com/aol/micro/server/servers/ServerRunner.java rename to micro-core/src/main/java/com/oath/micro/server/servers/ServerRunner.java index bcfb37d8b..4d0a19f83 100644 --- a/micro-core/src/main/java/com/aol/micro/server/servers/ServerRunner.java +++ b/micro-core/src/main/java/com/oath/micro/server/servers/ServerRunner.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.servers; +package com.oath.micro.server.servers; import java.util.HashMap; import java.util.List; @@ -9,29 +9,29 @@ import java.util.stream.Collectors; +import com.oath.cyclops.types.persistent.PersistentList; +import cyclops.data.Seq; -import org.pcollections.ConsPStack; -import org.pcollections.PStack; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.aol.micro.server.module.Module; -import com.aol.micro.server.servers.model.ServerData; +import com.oath.micro.server.module.Module; +import com.oath.micro.server.servers.model.ServerData; public class ServerRunner { private final Logger logger = LoggerFactory.getLogger(getClass()); - private final PStack apps; + private final PersistentList apps; private final Optional register; private final CompletableFuture end; public ServerRunner(ApplicationRegister register, List apps, CompletableFuture end) { - this.apps = ConsPStack.from(apps); + this.apps = Seq.fromIterable(apps); this.register = Optional.of(register); this.end = end; } public ServerRunner(List apps, CompletableFuture end) { - this.apps = ConsPStack.from(apps); + this.apps = Seq.fromIterable(apps); this.register = Optional.empty(); this.end = end; } diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/ServerThreadLocalVariables.java b/micro-core/src/main/java/com/oath/micro/server/servers/ServerThreadLocalVariables.java similarity index 80% rename from micro-core/src/main/java/com/aol/micro/server/servers/ServerThreadLocalVariables.java rename to micro-core/src/main/java/com/oath/micro/server/servers/ServerThreadLocalVariables.java index 8eaacd8c8..e1ed67f34 100644 --- a/micro-core/src/main/java/com/aol/micro/server/servers/ServerThreadLocalVariables.java +++ b/micro-core/src/main/java/com/oath/micro/server/servers/ServerThreadLocalVariables.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.servers; +package com.oath.micro.server.servers; import lombok.Getter; diff --git a/micro-core/src/main/java/com/oath/micro/server/servers/ServletConfigurer.java b/micro-core/src/main/java/com/oath/micro/server/servers/ServletConfigurer.java new file mode 100644 index 000000000..41a99acc3 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/servers/ServletConfigurer.java @@ -0,0 +1,79 @@ +package com.oath.micro.server.servers; + +import javax.servlet.ServletContext; +import javax.servlet.ServletRegistration; + +import com.oath.cyclops.types.persistent.PersistentList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.oath.micro.server.auto.discovery.ServletConfiguration; +import com.oath.micro.server.servers.model.ServerData; +import com.oath.micro.server.servers.model.ServletData; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class ServletConfigurer { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final ServerData serverData; + private final PersistentList servletData; + + public void addServlets(ServletContext webappContext) { + addExplicitlyDeclaredServlets(webappContext); + addAutoDiscoveredServlets(webappContext); + } + private void handleServlet(ServletConfiguration servlet,ServletContext webappContext){ + servlet.getServlet().fold(clazz-> { + setInitParameters(webappContext.addServlet(getName(servlet), + clazz), servlet) + .addMapping(servlet.getMapping()); + return 1; + }, obj-> { + ServletRegistration.Dynamic servletReg = webappContext.addServlet( + servlet.getName(), obj); + servletReg.addMapping(servlet.getMapping()); + return 2; + }); + } + private void addAutoDiscoveredServlets(ServletContext webappContext) { + serverData + .getRootContext() + .getBeansOfType(ServletConfiguration.class) + .values() + .forEach(servlet -> handleServlet(servlet,webappContext)); + } + + private void addExplicitlyDeclaredServlets(ServletContext webappContext) { + for (ServletData servletData : servletData) { + ServletRegistration.Dynamic servletReg = webappContext.addServlet( + servletData.getServletName(), servletData.getServlet()); + servletReg.addMapping(servletData.getMapping()); + logServlet(servletData); + } + } + + private void logServlet(ServletData servlet) { + logger.info("Registering {} servlet on {}",servlet.getServlet().getClass().getName(), servlet.getMapping()); + + } + + private void logServlet(ServletConfiguration servlet) { + logger.info("Registering {} servlet on {}",servlet.getClass().getName(), servlet.getMapping()[0]); + } + + + private ServletRegistration.Dynamic setInitParameters( + ServletRegistration.Dynamic addServlet, ServletConfiguration servlet) { + addServlet.setInitParameters(servlet.getInitParameters()); + return addServlet; + } + + private String getName(ServletConfiguration servlet) { + if (servlet.getName() != null) + return servlet.getName(); + return servlet.getClass().getName(); + } + +} diff --git a/micro-core/src/main/java/com/oath/micro/server/servers/ServletContextListenerConfigurer.java b/micro-core/src/main/java/com/oath/micro/server/servers/ServletContextListenerConfigurer.java new file mode 100644 index 000000000..c0a79be5c --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/servers/ServletContextListenerConfigurer.java @@ -0,0 +1,64 @@ +package com.oath.micro.server.servers; + +import java.util.List; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletRequestListener; + +import com.oath.cyclops.types.persistent.PersistentList; +import cyclops.reactive.collections.mutable.ListX; +import lombok.AllArgsConstructor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.oath.micro.server.servers.model.ServerData; + +@AllArgsConstructor +public class ServletContextListenerConfigurer { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final ServerData serverData; + private final List listenerData; + private final List listenerRequestData; + + public ServletContextListenerConfigurer(ServerData serverData, + PersistentList listenerData, PersistentList listenerRequestData) { + this.serverData = serverData; + this.listenerData = ListX.fromIterable(listenerData); + this.listenerRequestData = ListX.fromIterable(listenerRequestData); + } + + public void addListeners(ServletContext webappContext) { + + serverData.getRootContext() + .getBeansOfType(ServletContextListener.class) + .values() + + .stream() + + .peek(this::logListener) + .forEach(listener -> webappContext.addListener(listener)); + listenerData.forEach(it -> webappContext.addListener(it)); + + serverData.getRootContext() + .getBeansOfType(ServletRequestListener.class) + .values() + .stream() + .peek(this::logListener) + .forEach(listener -> webappContext.addListener(listener)); + listenerRequestData.forEach(it -> webappContext.addListener(it)); + + } + private void logListener(ServletContextListener listener) { + logger.info("Registering servlet context listener {}", listener.getClass().getName()); + + } + private void logListener(ServletRequestListener listener) { + logger.info("Registering servlet request listener {}",listener.getClass().getName()); + + } + + +} diff --git a/micro-core/src/main/java/com/oath/micro/server/servers/model/AllData.java b/micro-core/src/main/java/com/oath/micro/server/servers/model/AllData.java new file mode 100644 index 000000000..bec23c964 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/servers/model/AllData.java @@ -0,0 +1,55 @@ +package com.oath.micro.server.servers.model; + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.ServletContextListener; +import javax.servlet.ServletRequestListener; + +import com.oath.cyclops.types.persistent.PersistentList; +import cyclops.data.Seq; +import lombok.Getter; +import lombok.Builder; + + +import com.oath.micro.server.utility.UsefulStaticMethods; + +@Getter +@Builder +public class AllData { + + private final ServerData serverData; + private final PersistentList filterDataList; + private final PersistentList servletDataList; + private final PersistentList servletContextListeners; + private final PersistentList servletRequestListeners; + + public AllData(ServerData serverData, List filterDataList, + List servletDataList, + List servletContextListeners, + List servletRequestListeners ) { + + this.servletContextListeners = Seq.fromIterable(UsefulStaticMethods.either(servletContextListeners, new ArrayList())); + + this.servletRequestListeners = Seq.fromIterable(UsefulStaticMethods.either(servletRequestListeners, new ArrayList())); + + this.filterDataList = Seq.fromIterable(UsefulStaticMethods.either(filterDataList, new ArrayList())); + this.servletDataList = Seq.fromIterable(UsefulStaticMethods.either(servletDataList, new ArrayList())); + this.serverData = serverData; + } + public AllData(ServerData serverData, PersistentList filterDataList, + PersistentList servletDataList, + PersistentList servletContextListeners, + PersistentList servletRequestListeners ) { + + this.servletContextListeners = Seq.fromIterable(UsefulStaticMethods.either(servletContextListeners, new ArrayList())); + + this.servletRequestListeners = Seq.fromIterable(UsefulStaticMethods.either(servletRequestListeners, new ArrayList())); + + this.filterDataList = Seq.fromIterable(UsefulStaticMethods.either(filterDataList, new ArrayList())); + this.servletDataList = Seq.fromIterable(UsefulStaticMethods.either(servletDataList, new ArrayList())); + this.serverData = serverData; + } + +} + diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/model/FilterData.java b/micro-core/src/main/java/com/oath/micro/server/servers/model/FilterData.java similarity index 88% rename from micro-core/src/main/java/com/aol/micro/server/servers/model/FilterData.java rename to micro-core/src/main/java/com/oath/micro/server/servers/model/FilterData.java index 5d93d689f..a7c0bd48a 100644 --- a/micro-core/src/main/java/com/aol/micro/server/servers/model/FilterData.java +++ b/micro-core/src/main/java/com/oath/micro/server/servers/model/FilterData.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.servers.model; +package com.oath.micro.server.servers.model; import javax.servlet.Filter; diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/model/RestResourceMissingPathException.java b/micro-core/src/main/java/com/oath/micro/server/servers/model/RestResourceMissingPathException.java similarity index 82% rename from micro-core/src/main/java/com/aol/micro/server/servers/model/RestResourceMissingPathException.java rename to micro-core/src/main/java/com/oath/micro/server/servers/model/RestResourceMissingPathException.java index d68f2c4ec..218b13d6d 100644 --- a/micro-core/src/main/java/com/aol/micro/server/servers/model/RestResourceMissingPathException.java +++ b/micro-core/src/main/java/com/oath/micro/server/servers/model/RestResourceMissingPathException.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.servers.model; +package com.oath.micro.server.servers.model; public class RestResourceMissingPathException extends RuntimeException { diff --git a/micro-core/src/main/java/com/oath/micro/server/servers/model/ServerData.java b/micro-core/src/main/java/com/oath/micro/server/servers/model/ServerData.java new file mode 100644 index 000000000..f858e92ba --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/servers/model/ServerData.java @@ -0,0 +1,83 @@ +package com.oath.micro.server.servers.model; + +import java.util.List; + +import javax.ws.rs.Path; + +import com.oath.cyclops.types.persistent.PersistentList; +import cyclops.reactive.collections.immutable.LinkedListX; +import cyclops.data.Seq; +import cyclops.reactive.ReactiveSeq; +import lombok.Getter; +import lombok.Builder; + +import cyclops.data.tuple.Tuple; +import cyclops.data.tuple.Tuple2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; + +import com.oath.micro.server.module.Module; + +@Getter +@Builder +public class ServerData { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + private final int port; + + private final PersistentList resources; + private final ApplicationContext rootContext; + private final String baseUrlPattern; + private final Module module; + + public ServerData(int port, PersistentList resources, + ApplicationContext rootContext, + String baseUrlPattern, Module module) { + + this.port = port; + this.module = module; + this.resources = resources==null ? Seq.of() :resources; + this.rootContext = rootContext; + this.baseUrlPattern = baseUrlPattern; + } + public ServerData(int port, List resources, + ApplicationContext rootContext, + String baseUrlPattern, Module module) { + + this.port = port; + this.module = module; + this.resources = resources==null ? LinkedListX.of() : LinkedListX.fromIterable(resources); + this.rootContext = rootContext; + this.baseUrlPattern = baseUrlPattern; + } + + public ReactiveSeq> extractResources() { + + + return resources.stream().peek(resource -> logMissingPath(resource)) + .filter(resource-> resource.getClass().getAnnotation(Path.class)!=null) + .map(resource -> Tuple.tuple(resource.getClass().getName(), + resource.getClass().getAnnotation(Path.class).value())); + + + } + + private void logMissingPath(Object resource) { + if(resource.getClass().getAnnotation(Path.class)==null){ + logger.info("Resource with no path " + resource); + + } + } + + public String getNormalizedContextPath(){ + if("".equals(module.getContext())) + return ""; + else + return "/"+module.getContext(); + + } + + +} diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/model/ServletData.java b/micro-core/src/main/java/com/oath/micro/server/servers/model/ServletData.java similarity index 85% rename from micro-core/src/main/java/com/aol/micro/server/servers/model/ServletData.java rename to micro-core/src/main/java/com/oath/micro/server/servers/model/ServletData.java index e784c1730..b44a415ea 100644 --- a/micro-core/src/main/java/com/aol/micro/server/servers/model/ServletData.java +++ b/micro-core/src/main/java/com/oath/micro/server/servers/model/ServletData.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.servers.model; +package com.oath.micro.server.servers.model; import javax.servlet.Servlet; diff --git a/micro-core/src/main/java/com/oath/micro/server/spring/SpringApplicationConfigurator.java b/micro-core/src/main/java/com/oath/micro/server/spring/SpringApplicationConfigurator.java new file mode 100644 index 000000000..fcc7e68fc --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/spring/SpringApplicationConfigurator.java @@ -0,0 +1,76 @@ +package com.oath.micro.server.spring; + +import java.util.List; + +import cyclops.companion.Streams; +import cyclops.data.tuple.Tuple2; +import cyclops.reactive.ReactiveSeq; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import com.oath.micro.server.Plugin; +import com.oath.micro.server.PluginLoader; +import com.oath.micro.server.config.Config; +import com.oath.micro.server.config.ConfigAccessor; + +public class SpringApplicationConfigurator implements SpringBuilder { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public ConfigurableApplicationContext createSpringApp(Config config, Class... classes) { + + logger.debug("Configuring Spring"); + AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); + rootContext.setAllowCircularReferences(config.isAllowCircularReferences()); + rootContext.register(classes); + + rootContext.scan(config.getBasePackages()); + rootContext.refresh(); + logger.debug("Configuring Additional Spring Beans"); + ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) rootContext).getBeanFactory(); + + config.getDataSources() + .stream() + .map(Tuple2::_1) + .filter(it -> !new ConfigAccessor().get() + .getDefaultDataSourceName() + .equals(it)) + .forEach(name -> { + + List dbConfig = getConfig(config, rootContext, beanFactory); + dbConfig.forEach(spring -> spring.createSpringApp(name)); + + }); + logger.debug("Finished Configuring Spring"); + + return rootContext; + } + + @Override + public Class[] classes(Config config, Class... classes) { + return classes; + } + + private List getConfig(Config config, AnnotationConfigWebApplicationContext rootContext, + ConfigurableListableBeanFactory beanFactory) { + List result = ReactiveSeq.fromStream(PluginLoader.INSTANCE.plugins.get() + .stream()) + .filter(module -> module.springDbConfigurer() != null) + .map(Plugin::springDbConfigurer) + .flatMap(Streams::optionalToStream) + .toList(); + result.forEach(next -> { + + next.setBeanFactory(beanFactory); + next.setRootContext(rootContext); + + next.setConfig(config); + + }); + return result; + + } + +} diff --git a/micro-core/src/main/java/com/oath/micro/server/spring/SpringBuilder.java b/micro-core/src/main/java/com/oath/micro/server/spring/SpringBuilder.java new file mode 100644 index 000000000..fe01a1e22 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/spring/SpringBuilder.java @@ -0,0 +1,11 @@ +package com.oath.micro.server.spring; + +import org.springframework.context.ConfigurableApplicationContext; + +import com.oath.micro.server.config.Config; + +public interface SpringBuilder { + public ConfigurableApplicationContext createSpringApp(Config config, Class...classes); + + public Class[] classes(Config config, Class...classes); +} diff --git a/micro-core/src/main/java/com/oath/micro/server/spring/SpringContextFactory.java b/micro-core/src/main/java/com/oath/micro/server/spring/SpringContextFactory.java new file mode 100644 index 000000000..6d327e73b --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/spring/SpringContextFactory.java @@ -0,0 +1,110 @@ +package com.oath.micro.server.spring; + +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import com.oath.cyclops.types.persistent.PersistentSet; +import com.oath.cyclops.util.ExceptionSoftener; +import cyclops.reactive.ReactiveSeq; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; + + +import com.oath.micro.server.InternalErrorCode; +import com.oath.micro.server.Plugin; +import com.oath.micro.server.PluginLoader; +import com.oath.micro.server.config.Config; +import com.oath.micro.server.config.Microserver; + +import lombok.AllArgsConstructor; +import lombok.experimental.Wither; + + +@AllArgsConstructor +public class SpringContextFactory { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final PersistentSet classes; + private final Config config; + @Wither + private final SpringBuilder springBuilder; + + public SpringContextFactory(Config config, Class c, Set> classes) { + PersistentSet s = config.getClasses() + .plusAll(classes); + + + s= s.plus(c); + Microserver microserver = c.getAnnotation(Microserver.class); + final PersistentSet immutableS = s; + + s = Optional.ofNullable(microserver) + .flatMap(ms -> Optional.ofNullable(ms.blacklistedClasses())) + .map(bl -> { + Set blacklistedClasses = Arrays.stream(bl) + .collect(Collectors.toSet()); + return (PersistentSet)immutableS.stream() + .filter(clazz -> !blacklistedClasses.contains(clazz)).hashSet(); + }) + .orElse(immutableS); + + this.classes = s; + this.config = config; + + springBuilder = ReactiveSeq.fromStream(PluginLoader.INSTANCE.plugins.get() + .stream()) + .filter(m -> m.springBuilder() != null) + .map(Plugin::springBuilder) + .findFirst() + .orElse(new SpringApplicationConfigurator()); + } + + public SpringContextFactory(SpringBuilder builder, Config config, Class c, Set> classes) { + PersistentSet s = config.getClasses(); + for(Class next : classes){ + s = s.plus(next); + } + + s = s.plus(c); + Microserver microserver = c.getAnnotation(Microserver.class); + final PersistentSet immutableS = s; + + s = Optional.ofNullable(microserver) + .flatMap(ms -> Optional.ofNullable(ms.blacklistedClasses())) + .map(bl -> { + Set blacklistedClasses = Arrays.stream(bl) + .collect(Collectors.toSet()); + PersistentSet rs = immutableS.stream() + .filter(clazz -> !blacklistedClasses.contains(clazz)) + .hashSet(); + return rs; + }) + .orElse(immutableS); + + this.classes = s; + this.config = config; + + springBuilder = builder; + + } + + + public ApplicationContext createSpringContext() { + try { + ApplicationContext springContext = springBuilder.createSpringApp(config, classes.stream().toArray(i->new Class[classes.size()])); + return springContext; + } catch (Exception e) { + logger.error(InternalErrorCode.STARTUP_FAILED_SPRING_INITIALISATION.toString(), e.getMessage()); + ExceptionSoftener.throwSoftenedException(e); + } + return null; + } + public Class[] classes() { + return springBuilder.classes(config, classes.stream().toArray(i->new Class[classes.size()])); + } + +} diff --git a/micro-core/src/main/java/com/aol/micro/server/spring/SpringDBConfig.java b/micro-core/src/main/java/com/oath/micro/server/spring/SpringDBConfig.java similarity index 84% rename from micro-core/src/main/java/com/aol/micro/server/spring/SpringDBConfig.java rename to micro-core/src/main/java/com/oath/micro/server/spring/SpringDBConfig.java index 03260134a..399da4815 100644 --- a/micro-core/src/main/java/com/aol/micro/server/spring/SpringDBConfig.java +++ b/micro-core/src/main/java/com/oath/micro/server/spring/SpringDBConfig.java @@ -1,9 +1,9 @@ -package com.aol.micro.server.spring; +package com.oath.micro.server.spring; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; -import com.aol.micro.server.config.Config; +import com.oath.micro.server.config.Config; public interface SpringDBConfig { diff --git a/micro-core/src/main/java/com/oath/micro/server/spring/properties/PropertyFileConfig.java b/micro-core/src/main/java/com/oath/micro/server/spring/properties/PropertyFileConfig.java new file mode 100644 index 000000000..a261bb354 --- /dev/null +++ b/micro-core/src/main/java/com/oath/micro/server/spring/properties/PropertyFileConfig.java @@ -0,0 +1,135 @@ +package com.oath.micro.server.spring.properties; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.config.PropertiesFactoryBean; +import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; + +import com.oath.micro.server.config.Config; +import com.oath.micro.server.config.ConfigAccessor; + +@Configuration +public class PropertyFileConfig { + + private final static Logger logger = LoggerFactory.getLogger(PropertyFileConfig.class); + + public PropertyFileConfig() { + + } + + public PropertyFileConfig(boolean set) { + if (set) + new Config().set(); // make sure config instance is set + } + + @Bean + public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() throws IOException { + + PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer(); + Properties props = propertyFactory(); + + configurer.setProperties(props); + configurer.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE); + return configurer; + } + + @Bean + public Properties propertyFactory() throws IOException { + List resources = loadPropertyResource(); + PropertiesFactoryBean factory = new PropertiesFactoryBean(); + factory.setLocations(resources.toArray(new Resource[resources.size()])); + factory.afterPropertiesSet(); + Properties props = factory.getObject(); + + new ConfigAccessor().get() + .getProperties() + .stream() + .forEach(e -> { + if (props.getProperty(e._1()) == null) { + props.put(e._1(), e._2()); + } + }); + + System.getProperties() + .entrySet() + .forEach(e -> props.put(e.getKey(), e.getValue())); + + return props; + } + + private List loadPropertyResource() { + List resources = new ArrayList<>(); + String applicationPropertyFileName = new ConfigAccessor().get() + .getPropertiesName(); + loadProperties(applicationPropertyFileName, "application").ifPresent(it -> resources.add(it)); + + String serviceTypePropertyFileName = new ConfigAccessor().get() + .getServiceTypePropertiesName(); + loadProperties(serviceTypePropertyFileName, "service-type").ifPresent(it -> resources.add(it)); + + String instancePropertyFileName = new ConfigAccessor().get() + .getInstancePropertiesName(); + loadProperties(instancePropertyFileName, "instance").ifPresent(it -> resources.add(it)); + + return resources; + } + + private Optional loadProperties(String applicationPropertyFileName, String type) { + + Optional resource = Optional.empty(); + + if (new File( + "./" + applicationPropertyFileName).exists()) { + resource = Optional.of(new FileSystemResource( + new File( + "./" + applicationPropertyFileName))); + logger.info("./" + applicationPropertyFileName + " added"); + } + + URL urlResource = PropertyFileConfig.class.getClassLoader() + .getResource(applicationPropertyFileName); + if (urlResource != null) { + resource = Optional.of(new UrlResource( + urlResource)); + logger.info(applicationPropertyFileName + " added"); + } + + if (System.getProperty(type + ".env") != null) { + URL envResource = PropertyFileConfig.class.getClassLoader() + .getResource(createEnvBasedPropertyFileName(applicationPropertyFileName)); + if (envResource != null) { + resource = Optional.of(new UrlResource( + envResource)); + logger.info(createEnvBasedPropertyFileName(applicationPropertyFileName) + " added"); + } + + } + if (System.getProperty(type + ".property.file") != null) { + resource = Optional.of(new FileSystemResource( + new File( + System.getProperty(type + ".property.file")))); + logger.info(System.getProperty("application.property.file") + " added"); + + } + return resource; + } + + private String createEnvBasedPropertyFileName(String applicationPropertyFileName) { + return applicationPropertyFileName.substring(0, applicationPropertyFileName.lastIndexOf(".")) + "-" + + System.getProperty("application.env") + ".properties"; + } + +} diff --git a/micro-core/src/main/java/com/aol/micro/server/utility/HashMapBuilder.java b/micro-core/src/main/java/com/oath/micro/server/utility/HashMapBuilder.java similarity index 98% rename from micro-core/src/main/java/com/aol/micro/server/utility/HashMapBuilder.java rename to micro-core/src/main/java/com/oath/micro/server/utility/HashMapBuilder.java index 9c5314638..3b3714ec5 100644 --- a/micro-core/src/main/java/com/aol/micro/server/utility/HashMapBuilder.java +++ b/micro-core/src/main/java/com/oath/micro/server/utility/HashMapBuilder.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.utility; +package com.oath.micro.server.utility; import java.util.Collections; import java.util.HashMap; diff --git a/micro-core/src/main/java/com/aol/micro/server/utility/UsefulStaticMethods.java b/micro-core/src/main/java/com/oath/micro/server/utility/UsefulStaticMethods.java similarity index 93% rename from micro-core/src/main/java/com/aol/micro/server/utility/UsefulStaticMethods.java rename to micro-core/src/main/java/com/oath/micro/server/utility/UsefulStaticMethods.java index 2b29cdc80..f05837716 100644 --- a/micro-core/src/main/java/com/aol/micro/server/utility/UsefulStaticMethods.java +++ b/micro-core/src/main/java/com/oath/micro/server/utility/UsefulStaticMethods.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.utility; +package com.oath.micro.server.utility; import static java.util.Optional.ofNullable; diff --git a/micro-core/src/main/java/nonautoscan/com/aol/micro/server/AopConfig.java b/micro-core/src/main/java/nonautoscan/com/oath/micro/server/AopConfig.java similarity index 83% rename from micro-core/src/main/java/nonautoscan/com/aol/micro/server/AopConfig.java rename to micro-core/src/main/java/nonautoscan/com/oath/micro/server/AopConfig.java index e24028faa..f80f6d643 100644 --- a/micro-core/src/main/java/nonautoscan/com/aol/micro/server/AopConfig.java +++ b/micro-core/src/main/java/nonautoscan/com/oath/micro/server/AopConfig.java @@ -1,4 +1,4 @@ -package nonautoscan.com.aol.micro.server; +package nonautoscan.com.oath.micro.server; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; diff --git a/micro-core/src/main/java/nonautoscan/com/oath/micro/server/SSLConfig.java b/micro-core/src/main/java/nonautoscan/com/oath/micro/server/SSLConfig.java new file mode 100644 index 000000000..045cc530f --- /dev/null +++ b/micro-core/src/main/java/nonautoscan/com/oath/micro/server/SSLConfig.java @@ -0,0 +1,54 @@ +package nonautoscan.com.oath.micro.server; + +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +import org.springframework.beans.factory.config.PropertiesFactoryBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; + +import com.oath.micro.server.config.SSLProperties; + +@Configuration +public class SSLConfig { + + private static String keyStoreFile = "keyStoreFile"; + private static String keyStorePass = "keyStorePass"; + private static String trustStoreFile = "trustStoreFile"; + private static String trustStorePass = "trustStorePass"; + private static String keyStoreType = "keyStoreType"; + private static String keyStoreProvider = "keyStoreProvider"; + private static String trustStoreType = "trustStoreType"; + private static String trustStoreProvider = "trustStoreProvider"; + private static String clientAuth = "clientAuth"; + private static String ciphers = "ciphers"; + private static String protocol = "protocol"; + + @Bean + public static SSLProperties sslProperties() throws IOException { + PropertiesFactoryBean factory = new PropertiesFactoryBean(); + URL url = SSLConfig.class.getClassLoader().getResource("ssl.properties"); + if (url != null) { + Resource reource = new UrlResource(url); + factory.setLocation(reource); + factory.afterPropertiesSet(); + Properties properties = factory.getObject(); + return SSLProperties.builder() + .keyStoreFile(properties.getProperty(keyStoreFile)) + .keyStorePass(properties.getProperty(keyStorePass)) + .trustStoreFile(properties.getProperty(trustStoreFile)) + .trustStorePass(properties.getProperty(trustStorePass)) + .keyStoreType(properties.getProperty(keyStoreType)) + .keyStoreProvider(properties.getProperty(keyStoreProvider)) + .trustStoreType(properties.getProperty(trustStoreType)) + .trustStoreProvider(properties.getProperty(trustStoreProvider)) + .clientAuth(properties.getProperty(clientAuth)) + .ciphers(properties.getProperty(ciphers)) + .protocol(properties.getProperty(protocol)).build(); + } + return null; + } +} diff --git a/micro-core/src/main/java/nonautoscan/com/aol/micro/server/ScheduleAndAsyncConfig.java b/micro-core/src/main/java/nonautoscan/com/oath/micro/server/ScheduleAndAsyncConfig.java similarity index 94% rename from micro-core/src/main/java/nonautoscan/com/aol/micro/server/ScheduleAndAsyncConfig.java rename to micro-core/src/main/java/nonautoscan/com/oath/micro/server/ScheduleAndAsyncConfig.java index 28a08a2f1..08e9cdc0e 100644 --- a/micro-core/src/main/java/nonautoscan/com/aol/micro/server/ScheduleAndAsyncConfig.java +++ b/micro-core/src/main/java/nonautoscan/com/oath/micro/server/ScheduleAndAsyncConfig.java @@ -1,4 +1,4 @@ -package nonautoscan.com.aol.micro.server; +package nonautoscan.com.oath.micro.server; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -11,7 +11,7 @@ import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.config.ScheduledTaskRegistrar; -import com.aol.micro.server.SchedulingConfiguration; +import com.oath.micro.server.SchedulingConfiguration; @Configuration @EnableScheduling diff --git a/micro-core/src/main/resources/logback.xml b/micro-core/src/main/resources/logback.xml index 5fcb0dd73..545cd9196 100644 --- a/micro-core/src/main/resources/logback.xml +++ b/micro-core/src/main/resources/logback.xml @@ -1,19 +1,11 @@ - - %date{MMM dd yyyy h:mm:ss a z,EST} %-5p %c - %msg -- - [%thread] %n + %date{MMM dd yyyy h:mm:ss a z,EST} %-5p %c - %msg -- [%thread] %n - - - - - - diff --git a/micro-core/src/test/java/com/aol/micro/server/config/SimpleApp.java b/micro-core/src/test/java/com/aol/micro/server/config/SimpleApp.java deleted file mode 100644 index ea0e36ebc..000000000 --- a/micro-core/src/test/java/com/aol/micro/server/config/SimpleApp.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aol.micro.server.config; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; - -@Microserver -@Rest -@Path("/test") -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()->"hello-world").run(); - } - - @GET - public String test(){ - return "ok!"; - } -} diff --git a/micro-core/src/test/java/com/aol/micro/server/model/ServletStatusResource.java b/micro-core/src/test/java/com/aol/micro/server/model/ServletStatusResource.java deleted file mode 100644 index 7eed4bcb7..000000000 --- a/micro-core/src/test/java/com/aol/micro/server/model/ServletStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aol.micro.server.model; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/servlet") -public class ServletStatusResource implements RestResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-core/src/test/java/com/aol/micro/server/module/ConfigureEnviromentTest.java b/micro-core/src/test/java/com/aol/micro/server/module/ConfigureEnviromentTest.java deleted file mode 100644 index 4e390aade..000000000 --- a/micro-core/src/test/java/com/aol/micro/server/module/ConfigureEnviromentTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.aol.micro.server.module; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Properties; - -import org.junit.Before; -import org.junit.Test; - -public class ConfigureEnviromentTest { - - ConfigureEnviroment configureEnviroment = new ConfigureEnviroment(); - ModuleBean moduleBean; - - @Before - public void setUp() { - moduleBean = ModuleBean.builder().port(8080).host("host").module(() -> "simple").build(); - } - - @Test - public void testEnvironmentNoModules() { - Environment environment = configureEnviroment.environment(new Properties()); - assertThat(environment.getModuleBean(() -> "simple") == null, is(true)); - } - - @Test - public void testEnvironment() { - Environment environment = configureEnviroment.environment(new Properties()); - assertThat(environment.getModuleBean(() -> "simple") == null, is(true)); - } -} diff --git a/micro-core/src/test/java/com/aol/micro/server/module/EnvironmentTest.java b/micro-core/src/test/java/com/aol/micro/server/module/EnvironmentTest.java deleted file mode 100644 index f47ce9a2d..000000000 --- a/micro-core/src/test/java/com/aol/micro/server/module/EnvironmentTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.aol.micro.server.module; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.Properties; - -import org.junit.Test; - -public class EnvironmentTest { - - @Test - public void testGetModuleBean() { - - - - Environment environment = new Environment(new Properties(), - Arrays.asList(new ModuleBean(8081, "host1", () -> "test"))); - assertThat(environment.getModuleBean(()-> "test").getPort(), is(8081)); - } - @Test - public void testDefaultPort() { - Environment environment = new Environment(new Properties()); - environment.assureModule(() ->"context"); - assertThat(environment.getModuleBean(()-> "context").getPort(), is(8080)); - } - - @Test - public void testGetModuleBeanOverridePort() { - Properties props = new Properties(); - props.put("context.port", 8081); - Environment environment = new Environment(props); - environment.assureModule(() ->"context"); - assertThat(environment.getModuleBean(()-> "context").getPort(), is(8081)); - } - - @Test - public void testDefaultHost() throws UnknownHostException { - String host =InetAddress.getLocalHost().getHostName(); - Environment environment = new Environment(new Properties()); - environment.assureModule(() ->"context"); - assertThat(environment.getModuleBean(()-> "context").getHost(), is(host)); - } - @Test - public void testDefaultHostNotNull() throws UnknownHostException { - - Environment environment = new Environment(new Properties()); - environment.assureModule(() ->"context"); - assertThat(environment.getModuleBean(()-> "context").getHost(), is(not(nullValue()))); - } - @Test - public void testHostOverride() throws UnknownHostException { - - Properties props = new Properties(); - props.put("context.host", "overriden-host"); - Environment environment = new Environment(props); - environment.assureModule(() ->"context"); - assertThat(environment.getModuleBean(()-> "context").getHost(), is("overriden-host")); - } -} diff --git a/micro-core/src/test/java/com/aol/micro/server/module/HttpServer.java b/micro-core/src/test/java/com/aol/micro/server/module/HttpServer.java deleted file mode 100644 index b3eebc077..000000000 --- a/micro-core/src/test/java/com/aol/micro/server/module/HttpServer.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.aol.micro.server.module; - -public class HttpServer { - -} diff --git a/micro-core/src/test/java/com/aol/micro/server/module/ModuleTest.java b/micro-core/src/test/java/com/aol/micro/server/module/ModuleTest.java deleted file mode 100644 index 3efe74ab3..000000000 --- a/micro-core/src/test/java/com/aol/micro/server/module/ModuleTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aol.micro.server.module; - -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; - -import org.junit.Test; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.micro.server.Plugin; -public class ModuleTest { - - @Test - public void testProviders(){ - //test MyPlugin working - assertThat("com.aol.micro.server.rest.providers,com.my.new.provider,com.my.new.provider2", - equalTo(ConfigurableModule.builder().build().getProviders())); - System.out.println(new ModuleImpl().getProviders()); - String additional = ReactiveSeq - .fromStream( - Arrays.asList(new MyPlugin()) - .stream()).filter(module -> module.providers()!=null) - .flatMapIterable(Plugin::providers) - .join(","); - - assertThat(additional, equalTo("com.my.new.provider,com.my.new.provider2")); - } - - static class ModuleImpl implements Module{ - public String getContext(){ - return "hello world"; - } - } -} diff --git a/micro-core/src/test/java/com/aol/micro/server/module/MyPlugin.java b/micro-core/src/test/java/com/aol/micro/server/module/MyPlugin.java deleted file mode 100644 index a2749247b..000000000 --- a/micro-core/src/test/java/com/aol/micro/server/module/MyPlugin.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.aol.micro.server.module; - -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.micro.server.Plugin; - -public class MyPlugin implements Plugin{ - public PStackX providers(){ - return PStackX.of("com.my.new.provider","com.my.new.provider2"); - } -} \ No newline at end of file diff --git a/micro-core/src/test/java/com/aol/micro/server/module/RestResourceTagBuilderTest.java b/micro-core/src/test/java/com/aol/micro/server/module/RestResourceTagBuilderTest.java deleted file mode 100644 index db4622aa8..000000000 --- a/micro-core/src/test/java/com/aol/micro/server/module/RestResourceTagBuilderTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aol.micro.server.module; - -import static org.hamcrest.Matchers.hasItem; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; - -import org.junit.Test; - -import com.aol.micro.server.auto.discovery.CommonRestResource; -public class RestResourceTagBuilderTest { - - @Test(expected=ClassNotFoundException.class) - public void testRestResourceTagNonsense() { - RestResourceTagBuilder.restResourceTags("com.aol.micro.server.module.RestResourceTagBuilderTest","nonsense"); - fail("should not get here, ClassNotFound expected"); - } - @Test - public void testRestResourceTag() { - assertThat(RestResourceTagBuilder.restResourceTags("com.aol.micro.server.module.RestResourceTagBuilderTest"), hasItem( RestResourceTagBuilderTest.class)); - } - @Test - public void testRestResourceTagClasses() { - assertThat(RestResourceTagBuilder.restResourceTags(RestResourceTagBuilderTest.class), hasItem( RestResourceTagBuilderTest.class)); - } - @Test - public void testRestResourceTagDefaults() { - assertThat(RestResourceTagBuilder.restResourceTags("com.aol.micro.server.module.RestResourceTagBuilderTest"), hasItem( CommonRestResource.class)); - } - @Test - public void testRestResourceTagClassesDefaults() { - assertThat(RestResourceTagBuilder.restResourceTags(RestResourceTagBuilderTest.class), hasItem( CommonRestResource.class)); - } - - -} diff --git a/micro-core/src/test/java/com/aol/micro/server/simpleserver/HelloResource.java b/micro-core/src/test/java/com/aol/micro/server/simpleserver/HelloResource.java deleted file mode 100644 index cd934e10d..000000000 --- a/micro-core/src/test/java/com/aol/micro/server/simpleserver/HelloResource.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.aol.micro.server.simpleserver; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/foo") -public class HelloResource { - - @GET - @Produces("text/plain") - @Path("/hello") - public String hello() { - return "world"; - } -} \ No newline at end of file diff --git a/micro-core/src/test/java/com/aol/micro/server/simpleserver/TestMicroserverApp.java b/micro-core/src/test/java/com/aol/micro/server/simpleserver/TestMicroserverApp.java deleted file mode 100644 index 00bc032ad..000000000 --- a/micro-core/src/test/java/com/aol/micro/server/simpleserver/TestMicroserverApp.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.aol.micro.server.simpleserver; - - -import com.aol.micro.server.MicroserverApp; - -public class TestMicroserverApp { - - public static void main(String[] args) { - // SLF4JBridgeHandler.removeHandlersForRootLogger(); - // SLF4JBridgeHandler.install(); - - new MicroserverApp(()->"simple").start(); - } - -} \ No newline at end of file diff --git a/micro-core/src/test/java/com/aol/micro/server/utility/UsefulStaticMethodsTest.java b/micro-core/src/test/java/com/aol/micro/server/utility/UsefulStaticMethodsTest.java deleted file mode 100644 index 7e9b0e7a3..000000000 --- a/micro-core/src/test/java/com/aol/micro/server/utility/UsefulStaticMethodsTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.aol.micro.server.utility; - -import static com.aol.micro.server.utility.UsefulStaticMethods.either; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.*; - -import org.junit.Test; - -public class UsefulStaticMethodsTest { - - @Test - public void testEither() { - assertThat(either(null, "answer"), is("answer")); - assertThat(either("answer", "different"), is("answer")); - } - -} diff --git a/micro-core/src/test/java/com/aol/micro/server/config/MicroserverConfigurerTest.java b/micro-core/src/test/java/com/oath/micro/server/config/MicroserverConfigurerTest.java similarity index 86% rename from micro-core/src/test/java/com/aol/micro/server/config/MicroserverConfigurerTest.java rename to micro-core/src/test/java/com/oath/micro/server/config/MicroserverConfigurerTest.java index b3f1d3c25..a7d7b5919 100644 --- a/micro-core/src/test/java/com/aol/micro/server/config/MicroserverConfigurerTest.java +++ b/micro-core/src/test/java/com/oath/micro/server/config/MicroserverConfigurerTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.config; +package com.oath.micro.server.config; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.equalTo; @@ -7,8 +7,11 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import cyclops.data.tuple.Tuple2; import org.junit.Test; +import java.util.Arrays; + @Microserver(propertiesName = "test!", instancePropertiesName = "test2!",serviceTypePropertiesName = "servicetType!", properties = { "hello", "world" }, entityScan = { "packages" }, classes = { String.class, Integer.class }, blacklistedClasses = {String.class}) @@ -18,8 +21,8 @@ public class MicroserverConfigurerTest { @Test public void properties() { - assertThat(configurer.buildConfig(MicroserverConfigurerTest.class).getProperties().keySet(), hasItem("hello")); - assertThat(configurer.buildConfig(MicroserverConfigurerTest.class).getProperties().values(), hasItem("world")); + assertThat(configurer.buildConfig(MicroserverConfigurerTest.class).getProperties().stream().map(Tuple2::_1).toSet(), hasItem("hello")); + assertThat(configurer.buildConfig(MicroserverConfigurerTest.class).getProperties().stream().map(Tuple2::_2).toSet(), hasItem("world")); } @Test @@ -42,7 +45,7 @@ public void serviceTypePropertiesName() { @Test public void entityScan() { Config config = configurer.buildConfig(MicroserverConfigurerTest.class); - assertThat(config.getDataSources().get(config.getDefaultDataSourceName()), hasItem("packages")); + assertThat(config.getDataSources().getOrElse(config.getDefaultDataSourceName(), Arrays.asList()), hasItem("packages")); } diff --git a/micro-core/src/test/java/com/oath/micro/server/config/SimpleApp.java b/micro-core/src/test/java/com/oath/micro/server/config/SimpleApp.java new file mode 100644 index 000000000..eaa971e39 --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/config/SimpleApp.java @@ -0,0 +1,22 @@ +package com.oath.micro.server.config; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; + +@Microserver +@Rest +@Path("/test") +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()->"hello-world").run(); + } + + @GET + public String test(){ + return "ok!"; + } +} diff --git a/micro-core/src/test/java/com/aol/micro/server/model/FilterDataTest.java b/micro-core/src/test/java/com/oath/micro/server/model/FilterDataTest.java similarity index 84% rename from micro-core/src/test/java/com/aol/micro/server/model/FilterDataTest.java rename to micro-core/src/test/java/com/oath/micro/server/model/FilterDataTest.java index 241dc6555..6ef0b74af 100644 --- a/micro-core/src/test/java/com/aol/micro/server/model/FilterDataTest.java +++ b/micro-core/src/test/java/com/oath/micro/server/model/FilterDataTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.model; +package com.oath.micro.server.model; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -8,7 +8,7 @@ import org.junit.Test; -import com.aol.micro.server.servers.model.FilterData; +import com.oath.micro.server.servers.model.FilterData; public class FilterDataTest { diff --git a/micro-core/src/test/java/com/aol/micro/server/model/ServerDataTest.java b/micro-core/src/test/java/com/oath/micro/server/model/ServerDataTest.java similarity index 81% rename from micro-core/src/test/java/com/aol/micro/server/model/ServerDataTest.java rename to micro-core/src/test/java/com/oath/micro/server/model/ServerDataTest.java index d4ab2918d..10382572f 100644 --- a/micro-core/src/test/java/com/aol/micro/server/model/ServerDataTest.java +++ b/micro-core/src/test/java/com/oath/micro/server/model/ServerDataTest.java @@ -1,21 +1,18 @@ -package com.aol.micro.server.model; +package com.oath.micro.server.model; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import java.util.Arrays; -import java.util.stream.Collectors; - - import org.junit.Before; import org.junit.Test; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.micro.server.servers.model.ServerData; + +import com.oath.micro.server.servers.model.ServerData; public class ServerDataTest { @@ -50,14 +47,14 @@ public void testExtractNull(){ @Test public void testExtractResourceClassName(){ - assertThat(serverData.extractResources().toList().get(0).v1(),is(ServletStatusResource.class.getName())); + assertThat(serverData.extractResources().toList().get(0)._1(),is(ServletStatusResource.class.getName())); } @Test public void testExtractResourcePath(){ - assertThat(serverData.extractResources().toList().get(0).v2(),is("/servlet")); + assertThat(serverData.extractResources().toList().get(0)._2(),is("/servlet")); } diff --git a/micro-core/src/test/java/com/oath/micro/server/model/ServletStatusResource.java b/micro-core/src/test/java/com/oath/micro/server/model/ServletStatusResource.java new file mode 100644 index 000000000..17837dcfc --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/model/ServletStatusResource.java @@ -0,0 +1,22 @@ +package com.oath.micro.server.model; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/servlet") +public class ServletStatusResource implements RestResource { + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-core/src/test/java/com/aol/micro/server/module/BasicFilter.java b/micro-core/src/test/java/com/oath/micro/server/module/BasicFilter.java similarity index 94% rename from micro-core/src/test/java/com/aol/micro/server/module/BasicFilter.java rename to micro-core/src/test/java/com/oath/micro/server/module/BasicFilter.java index a75a34231..854bd316f 100644 --- a/micro-core/src/test/java/com/aol/micro/server/module/BasicFilter.java +++ b/micro-core/src/test/java/com/oath/micro/server/module/BasicFilter.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.module; +package com.oath.micro.server.module; import java.io.IOException; diff --git a/micro-core/src/test/java/com/aol/micro/server/module/ConfigurableModuleTest.java b/micro-core/src/test/java/com/oath/micro/server/module/ConfigurableModuleTest.java similarity index 78% rename from micro-core/src/test/java/com/aol/micro/server/module/ConfigurableModuleTest.java rename to micro-core/src/test/java/com/oath/micro/server/module/ConfigurableModuleTest.java index 6a0c8c4d6..f61c9ae4a 100644 --- a/micro-core/src/test/java/com/aol/micro/server/module/ConfigurableModuleTest.java +++ b/micro-core/src/test/java/com/oath/micro/server/module/ConfigurableModuleTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.module; +package com.oath.micro.server.module; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItem; @@ -21,17 +21,19 @@ import javax.servlet.ServletContextListener; import javax.servlet.ServletRequestListener; +import cyclops.reactive.collections.mutable.SetX; +import cyclops.reactive.collections.immutable.LinkedListX; +import cyclops.data.HashSet; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.pcollections.HashTreePSet; -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.cyclops.data.collections.extensions.standard.SetX; -import com.aol.micro.server.auto.discovery.CommonRestResource; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.utility.HashMapBuilder; + + +import com.oath.micro.server.auto.discovery.CommonRestResource; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.servers.model.ServerData; +import com.oath.micro.server.utility.HashMapBuilder; public class ConfigurableModuleTest { @@ -47,7 +49,7 @@ public class ConfigurableModuleTest { private Set> resourceClasses; private Set> resourceAnnotationClasses; private Map servlets; - private Set> springConfigurationClasses; + private HashSet> springConfigurationClasses; private List defaultJaxRsPackages; private Map serverProperties = HashMapBuilder.map(SERVER_PROPERTIES_KEY, 1).build(); @@ -65,14 +67,14 @@ public void setup(){ defaultResources = new ArrayList<>(); filters = HashMapBuilder.map("/*1",new DummyQueryIPRetriever()).build(); jaxWsRsApplication = "jaxRsApp2"; - listeners = m.getListeners(ServerData.builder().resources(PStackX.empty()).build()); - requestListeners = m.getRequestListeners(ServerData.builder().resources(PStackX.empty()).build()); + listeners = m.getListeners(ServerData.builder().resources(LinkedListX.empty()).build()); + requestListeners = m.getRequestListeners(ServerData.builder().resources(LinkedListX.empty()).build()); providers = "providers2"; Module m = () -> "hello"; resourceClasses = SetX.empty(); resourceAnnotationClasses = SetX.of(Rest.class); servlets = new HashMap<>(); - springConfigurationClasses = HashTreePSet.singleton(this.getClass()); + springConfigurationClasses = HashSet.of(this.getClass()); module = ConfigurableModule.builder() @@ -87,7 +89,7 @@ public void setup(){ .providers(providers) .restResourceClasses(resourceClasses) .servlets(servlets) - .springConfigurationClasses(springConfigurationClasses) + .springConfigurationClasses(springConfigurationClasses.toSet()) .serverProperties(serverProperties) .build(); @@ -177,60 +179,60 @@ public void testGetDefaultResourcesUnchanged() { @Test public void testGetListeners() { - assertThat(module.getListeners(ServerData.builder().resources(PStackX.of()).build()).size(), - is(m.getListeners(ServerData.builder().resources(PStackX.of()).build()).size()*2)); //doubled + assertThat(module.getListeners(ServerData.builder().resources(LinkedListX.of()).build()).size(), + is(m.getListeners(ServerData.builder().resources(LinkedListX.of()).build()).size()*2)); //doubled } @Test public void testGetListenersReset() { - assertThat(module.withResetAll(true).getListeners(ServerData.builder().resources(PStackX.of()).build()),is(this.listeners)); + assertThat(module.withResetAll(true).getListeners(ServerData.builder().resources(LinkedListX.of()).build()),is(this.listeners)); } @Test public void testGetListenersUnchanged() { - assertThat(unchanged.getListeners(ServerData.builder().resources(PStackX.empty()).build()).size() , - is(m.getListeners(ServerData.builder().resources(PStackX.empty()).build()).size())); + assertThat(unchanged.getListeners(ServerData.builder().resources(LinkedListX.empty()).build()).size() , + is(m.getListeners(ServerData.builder().resources(LinkedListX.empty()).build()).size())); } @Test public void testGetRequestListeners() { - assertThat(module.getRequestListeners(ServerData.builder().resources(PStackX.of()).build()).size(), - is(m.getRequestListeners(ServerData.builder().resources(PStackX.of()).build()).size()*2)); //doubled + assertThat(module.getRequestListeners(ServerData.builder().resources(LinkedListX.of()).build()).size(), + is(m.getRequestListeners(ServerData.builder().resources(LinkedListX.of()).build()).size()*2)); //doubled } @Test public void testGetRequestListenersReset() { - assertThat(module.withResetAll(true).getRequestListeners(ServerData.builder().resources(PStackX.of()).build()),is(this.requestListeners)); + assertThat(module.withResetAll(true).getRequestListeners(ServerData.builder().resources(LinkedListX.of()).build()),is(this.requestListeners)); } @Test public void testGetRequestListenersUnchanged() { - assertThat(unchanged.getRequestListeners(ServerData.builder().resources(PStackX.of()).build()).size() , - is(m.getRequestListeners(ServerData.builder().resources(PStackX.of()).build()).size())); + assertThat(unchanged.getRequestListeners(ServerData.builder().resources(LinkedListX.of()).build()).size() , + is(m.getRequestListeners(ServerData.builder().resources(LinkedListX.of()).build()).size())); } @Test public void testGetFilters() { - assertThat(module.getFilters(ServerData.builder().resources(PStackX.of()).build()).size(), + assertThat(module.getFilters(ServerData.builder().resources(LinkedListX.of()).build()).size(), is(1 )); } @Test public void testGetFiltersReset() { - assertThat(module.withResetAll(true).getFilters(ServerData.builder().resources(PStackX.of()).build()),is(this.filters)); + assertThat(module.withResetAll(true).getFilters(ServerData.builder().resources(LinkedListX.of()).build()),is(this.filters)); } @Test public void testGetFiltersUnchanged() { - assertThat(unchanged.getFilters(ServerData.builder().resources(PStackX.of()).build()).size(), - equalTo(m.getFilters( ServerData.builder().resources(PStackX.of()).build() ).size())); + assertThat(unchanged.getFilters(ServerData.builder().resources(LinkedListX.of()).build()).size(), + equalTo(m.getFilters( ServerData.builder().resources(LinkedListX.of()).build() ).size())); } @Test public void testGetServlets() { - assertThat(module.getServlets(ServerData.builder().resources(PStackX.of()).build()),is(this.servlets)); + assertThat(module.getServlets(ServerData.builder().resources(LinkedListX.of()).build()),is(this.servlets)); } @Test public void testGetServletsUnchanged() { - assertThat(unchanged.getServlets(ServerData.builder().resources(PStackX.of()).build()),is(m.getServlets(ServerData.builder().resources(PStackX.of()).build()))); + assertThat(unchanged.getServlets(ServerData.builder().resources(LinkedListX.of()).build()),is(m.getServlets(ServerData.builder().resources(LinkedListX.of()).build()))); } @Test @@ -259,7 +261,7 @@ public void testGetContext() { @Test public void testGetSpringConfigurationClassesReset() { - assertThat(module.withResetAll(true).getSpringConfigurationClasses(),is(this.springConfigurationClasses)); + assertThat(module.withResetAll(true).getSpringConfigurationClasses().size(),is(this.springConfigurationClasses.size())); } @Test public void testGetSpringConfigurationClasses() { @@ -292,21 +294,21 @@ public void testWithDefaultResources() { @Test public void testWithListeners() { - assertThat(unchanged.withListeners(this.listeners).getListeners(ServerData.builder().resources(PStackX.of()).build()).size(), - is(module.getListeners(ServerData.builder().resources(PStackX.of()).build()).size())); + assertThat(unchanged.withListeners(this.listeners).getListeners(ServerData.builder().resources(LinkedListX.of()).build()).size(), + is(module.getListeners(ServerData.builder().resources(LinkedListX.of()).build()).size())); } @Test public void testWithFilters() { - assertThat(unchanged.withFilters(this.filters).getFilters(ServerData.builder().resources(PStackX.of()).build()).size(), - is(module.getFilters(ServerData.builder().resources(PStackX.of()).build()).size())); + assertThat(unchanged.withFilters(this.filters).getFilters(ServerData.builder().resources(LinkedListX.of()).build()).size(), + is(module.getFilters(ServerData.builder().resources(LinkedListX.of()).build()).size())); } @Test public void testWithServlets() { - assertThat(unchanged.withServlets(this.servlets).getServlets(ServerData.builder().resources(PStackX.of()).build()).size(), - is(m.getServlets(ServerData.builder().resources(PStackX.of()).build()).size())); + assertThat(unchanged.withServlets(this.servlets).getServlets(ServerData.builder().resources(LinkedListX.of()).build()).size(), + is(m.getServlets(ServerData.builder().resources(LinkedListX.of()).build()).size())); } @@ -329,7 +331,7 @@ public void testWithContext() { @Test public void testWithSpringConfigurationClasses() { - assertThat(unchanged.withSpringConfigurationClasses(this.springConfigurationClasses).getSpringConfigurationClasses(),is(module.getSpringConfigurationClasses())); + assertThat(unchanged.withSpringConfigurationClasses(this.springConfigurationClasses.toSet()).getSpringConfigurationClasses(),is(module.getSpringConfigurationClasses())); } diff --git a/micro-core/src/test/java/com/oath/micro/server/module/ConfigureEnviromentTest.java b/micro-core/src/test/java/com/oath/micro/server/module/ConfigureEnviromentTest.java new file mode 100644 index 000000000..ba1b0c435 --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/module/ConfigureEnviromentTest.java @@ -0,0 +1,32 @@ +package com.oath.micro.server.module; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Properties; + +import org.junit.Before; +import org.junit.Test; + +public class ConfigureEnviromentTest { + + ConfigureEnviroment configureEnviroment = new ConfigureEnviroment(); + ModuleBean moduleBean; + + @Before + public void setUp() { + moduleBean = ModuleBean.builder().port(8080).host("host").module(() -> "simple").build(); + } + + @Test + public void testEnvironmentNoModules() { + MicroserverEnvironment microserverEnvironment = configureEnviroment.microserverEnvironment(new Properties()); + assertThat(microserverEnvironment.getModuleBean(() -> "simple") == null, is(true)); + } + + @Test + public void testEnvironment() { + MicroserverEnvironment microserverEnvironment = configureEnviroment.microserverEnvironment(new Properties()); + assertThat(microserverEnvironment.getModuleBean(() -> "simple") == null, is(true)); + } +} diff --git a/micro-core/src/test/java/com/aol/micro/server/module/DummyQueryIPRetriever.java b/micro-core/src/test/java/com/oath/micro/server/module/DummyQueryIPRetriever.java similarity index 94% rename from micro-core/src/test/java/com/aol/micro/server/module/DummyQueryIPRetriever.java rename to micro-core/src/test/java/com/oath/micro/server/module/DummyQueryIPRetriever.java index 044b457f3..8e2ed3515 100644 --- a/micro-core/src/test/java/com/aol/micro/server/module/DummyQueryIPRetriever.java +++ b/micro-core/src/test/java/com/oath/micro/server/module/DummyQueryIPRetriever.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.module; +package com.oath.micro.server.module; import java.io.IOException; diff --git a/micro-core/src/test/java/com/aol/micro/server/module/EmbeddedModuleTest.java b/micro-core/src/test/java/com/oath/micro/server/module/EmbeddedModuleTest.java similarity index 83% rename from micro-core/src/test/java/com/aol/micro/server/module/EmbeddedModuleTest.java rename to micro-core/src/test/java/com/oath/micro/server/module/EmbeddedModuleTest.java index 640bc167a..a3810b191 100644 --- a/micro-core/src/test/java/com/aol/micro/server/module/EmbeddedModuleTest.java +++ b/micro-core/src/test/java/com/oath/micro/server/module/EmbeddedModuleTest.java @@ -1,6 +1,6 @@ -package com.aol.micro.server.module; +package com.oath.micro.server.module; -import static com.aol.micro.server.module.RestResourceTagBuilder.restAnnotations; +import static com.oath.micro.server.module.RestResourceTagBuilder.restAnnotations; import static org.hamcrest.Matchers.hasItem; import static org.junit.Assert.assertThat; diff --git a/micro-core/src/test/java/com/oath/micro/server/module/HttpServer.java b/micro-core/src/test/java/com/oath/micro/server/module/HttpServer.java new file mode 100644 index 000000000..256f32b03 --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/module/HttpServer.java @@ -0,0 +1,5 @@ +package com.oath.micro.server.module; + +public class HttpServer { + +} diff --git a/micro-core/src/test/java/com/oath/micro/server/module/MicroserverEnvironmentTest.java b/micro-core/src/test/java/com/oath/micro/server/module/MicroserverEnvironmentTest.java new file mode 100644 index 000000000..bc3c8d0a0 --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/module/MicroserverEnvironmentTest.java @@ -0,0 +1,62 @@ +package com.oath.micro.server.module; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.Assert.assertThat; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.Properties; + +import org.junit.Test; + +public class MicroserverEnvironmentTest { + + @Test + public void testGetModuleBean() { + MicroserverEnvironment microserverEnvironment = new MicroserverEnvironment(new Properties(), + Arrays.asList(new ModuleBean(8081, "host1", () -> "test"))); + assertThat(microserverEnvironment.getModuleBean(()-> "test").getPort(), is(8081)); + } + @Test + public void testDefaultPort() { + MicroserverEnvironment microserverEnvironment = new MicroserverEnvironment(new Properties()); + microserverEnvironment.assureModule(() ->"context"); + assertThat(microserverEnvironment.getModuleBean(()-> "context").getPort(), is(8080)); + } + + @Test + public void testGetModuleBeanOverridePort() { + Properties props = new Properties(); + props.put("context.port", 8081); + MicroserverEnvironment microserverEnvironment = new MicroserverEnvironment(props); + microserverEnvironment.assureModule(() ->"context"); + assertThat(microserverEnvironment.getModuleBean(()-> "context").getPort(), is(8081)); + } + + @Test + public void testDefaultHost() throws UnknownHostException { + String host =InetAddress.getLocalHost().getHostName(); + MicroserverEnvironment microserverEnvironment = new MicroserverEnvironment(new Properties()); + microserverEnvironment.assureModule(() ->"context"); + assertThat(microserverEnvironment.getModuleBean(()-> "context").getHost(), is(host)); + } + @Test + public void testDefaultHostNotNull() throws UnknownHostException { + + MicroserverEnvironment microserverEnvironment = new MicroserverEnvironment(new Properties()); + microserverEnvironment.assureModule(() ->"context"); + assertThat(microserverEnvironment.getModuleBean(()-> "context").getHost(), is(not(nullValue()))); + } + @Test + public void testHostOverride() throws UnknownHostException { + + Properties props = new Properties(); + props.put("context.host", "overriden-host"); + MicroserverEnvironment microserverEnvironment = new MicroserverEnvironment(props); + microserverEnvironment.assureModule(() ->"context"); + assertThat(microserverEnvironment.getModuleBean(()-> "context").getHost(), is("overriden-host")); + } +} diff --git a/micro-core/src/test/java/com/oath/micro/server/module/MicroserverPluginsTest.java b/micro-core/src/test/java/com/oath/micro/server/module/MicroserverPluginsTest.java new file mode 100644 index 000000000..c9eaa86dc --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/module/MicroserverPluginsTest.java @@ -0,0 +1,17 @@ +package com.oath.micro.server.module; + +import com.oath.micro.server.MicroserverPlugins; +import com.oath.micro.server.plugin.Bean1; +import cyclops.reactive.ReactiveSeq; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class MicroserverPluginsTest { + + @Test + public void test(){ + assertTrue(ReactiveSeq.of(new MicroserverPlugins().classes()) + .contains(Bean1.class)); + } +} diff --git a/micro-core/src/test/java/com/aol/micro/server/module/ModuleDataExtractorTest.java b/micro-core/src/test/java/com/oath/micro/server/module/ModuleDataExtractorTest.java similarity index 79% rename from micro-core/src/test/java/com/aol/micro/server/module/ModuleDataExtractorTest.java rename to micro-core/src/test/java/com/oath/micro/server/module/ModuleDataExtractorTest.java index ebaf103d8..9c1f4fc38 100644 --- a/micro-core/src/test/java/com/aol/micro/server/module/ModuleDataExtractorTest.java +++ b/micro-core/src/test/java/com/oath/micro/server/module/ModuleDataExtractorTest.java @@ -1,25 +1,25 @@ -package com.aol.micro.server.module; +package com.oath.micro.server.module; -import static com.aol.micro.server.module.RestResourceTagBuilder.restResourceTags; +import static com.oath.micro.server.module.RestResourceTagBuilder.restResourceTags; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import java.util.Arrays; import java.util.Map; import javax.servlet.Filter; import javax.servlet.http.HttpServlet; +import cyclops.reactive.collections.immutable.LinkedListX; import org.junit.Before; import org.junit.Test; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.utility.HashMapBuilder; + +import com.oath.micro.server.servers.model.ServerData; +import com.oath.micro.server.utility.HashMapBuilder; public class ModuleDataExtractorTest { @@ -40,7 +40,7 @@ public void setup(){ .build(); extractor = new ModuleDataExtractor(module); rootContext = mock(AnnotationConfigWebApplicationContext.class); - data = ServerData.builder().resources(PStackX.of()).module(module).build(); + data = ServerData.builder().resources(LinkedListX.of()).module(module).build(); } diff --git a/micro-core/src/test/java/com/oath/micro/server/module/ModuleTest.java b/micro-core/src/test/java/com/oath/micro/server/module/ModuleTest.java new file mode 100644 index 000000000..10e16ff0a --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/module/ModuleTest.java @@ -0,0 +1,36 @@ +package com.oath.micro.server.module; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; + +import cyclops.reactive.ReactiveSeq; +import org.junit.Test; + + +import com.oath.micro.server.Plugin; +public class ModuleTest { + + @Test + public void testProviders(){ + //test MyPlugin working + assertThat("com.oath.micro.server.rest.providers,com.my.new.provider,com.my.new.provider2", + equalTo(ConfigurableModule.builder().build().getProviders())); + System.out.println(new ModuleImpl().getProviders()); + String additional = ReactiveSeq + .fromStream( + Arrays.asList(new MyPlugin()) + .stream()).filter(module -> module.providers()!=null) + .concatMap(Plugin::providers) + .join(","); + + assertThat(additional, equalTo("com.my.new.provider,com.my.new.provider2")); + } + + static class ModuleImpl implements Module{ + public String getContext(){ + return "hello world"; + } + } +} diff --git a/micro-core/src/test/java/com/oath/micro/server/module/MyPlugin.java b/micro-core/src/test/java/com/oath/micro/server/module/MyPlugin.java new file mode 100644 index 000000000..66ee96234 --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/module/MyPlugin.java @@ -0,0 +1,21 @@ +package com.oath.micro.server.module; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.plugin.Bean1; +import cyclops.reactive.collections.mutable.ListX; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.List; +import java.util.Set; + +public class MyPlugin implements Plugin{ + public List providers(){ + return ListX.of("com.my.new.provider","com.my.new.provider2"); + } + + @Override + public Set springClasses() { + return SetX.of(Bean1.class); + } +} diff --git a/micro-core/src/test/java/com/oath/micro/server/module/RestResourceTagBuilderTest.java b/micro-core/src/test/java/com/oath/micro/server/module/RestResourceTagBuilderTest.java new file mode 100644 index 000000000..64921a0dc --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/module/RestResourceTagBuilderTest.java @@ -0,0 +1,35 @@ +package com.oath.micro.server.module; + +import static org.hamcrest.Matchers.hasItem; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +import org.junit.Test; + +import com.oath.micro.server.auto.discovery.CommonRestResource; +public class RestResourceTagBuilderTest { + + @Test(expected=ClassNotFoundException.class) + public void testRestResourceTagNonsense() { + RestResourceTagBuilder.restResourceTags("com.oath.micro.server.module.RestResourceTagBuilderTest","nonsense"); + fail("should not get here, ClassNotFound expected"); + } + @Test + public void testRestResourceTag() { + assertThat(RestResourceTagBuilder.restResourceTags("com.oath.micro.server.module.RestResourceTagBuilderTest"), hasItem( RestResourceTagBuilderTest.class)); + } + @Test + public void testRestResourceTagClasses() { + assertThat(RestResourceTagBuilder.restResourceTags(RestResourceTagBuilderTest.class), hasItem( RestResourceTagBuilderTest.class)); + } + @Test + public void testRestResourceTagDefaults() { + assertThat(RestResourceTagBuilder.restResourceTags("com.oath.micro.server.module.RestResourceTagBuilderTest"), hasItem( CommonRestResource.class)); + } + @Test + public void testRestResourceTagClassesDefaults() { + assertThat(RestResourceTagBuilder.restResourceTags(RestResourceTagBuilderTest.class), hasItem( CommonRestResource.class)); + } + + +} diff --git a/micro-core/src/test/java/com/oath/micro/server/package-info.java b/micro-core/src/test/java/com/oath/micro/server/package-info.java new file mode 100644 index 000000000..58ab0676a --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/package-info.java @@ -0,0 +1 @@ +package com.oath.micro.server; diff --git a/micro-core/src/test/java/com/oath/micro/server/plugin/Bean1.java b/micro-core/src/test/java/com/oath/micro/server/plugin/Bean1.java new file mode 100644 index 000000000..404e9534e --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/plugin/Bean1.java @@ -0,0 +1,7 @@ +package com.oath.micro.server.plugin; + +import org.springframework.stereotype.Component; + +@Component +public class Bean1 { +} diff --git a/micro-core/src/test/java/com/oath/micro/server/simpleserver/HelloResource.java b/micro-core/src/test/java/com/oath/micro/server/simpleserver/HelloResource.java new file mode 100644 index 000000000..6d3fb683f --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/simpleserver/HelloResource.java @@ -0,0 +1,19 @@ +package com.oath.micro.server.simpleserver; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/foo") +public class HelloResource { + + @GET + @Produces("text/plain") + @Path("/hello") + public String hello() { + return "world"; + } +} \ No newline at end of file diff --git a/micro-core/src/test/java/com/oath/micro/server/simpleserver/TestMicroserverApp.java b/micro-core/src/test/java/com/oath/micro/server/simpleserver/TestMicroserverApp.java new file mode 100644 index 000000000..333fa6e46 --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/simpleserver/TestMicroserverApp.java @@ -0,0 +1,15 @@ +package com.oath.micro.server.simpleserver; + + +import com.oath.micro.server.MicroserverApp; + +public class TestMicroserverApp { + + public static void main(String[] args) { + // SLF4JBridgeHandler.removeHandlersForRootLogger(); + // SLF4JBridgeHandler.install(); + + new MicroserverApp(()->"simple").start(); + } + +} \ No newline at end of file diff --git a/micro-core/src/test/java/com/aol/micro/server/spring/SpringContextFactoryTest.java b/micro-core/src/test/java/com/oath/micro/server/spring/SpringContextFactoryTest.java similarity index 90% rename from micro-core/src/test/java/com/aol/micro/server/spring/SpringContextFactoryTest.java rename to micro-core/src/test/java/com/oath/micro/server/spring/SpringContextFactoryTest.java index a2e976475..d8ac4b5a0 100644 --- a/micro-core/src/test/java/com/aol/micro/server/spring/SpringContextFactoryTest.java +++ b/micro-core/src/test/java/com/oath/micro/server/spring/SpringContextFactoryTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.spring; +package com.oath.micro.server.spring; import static org.mockito.Matchers.anyObject; import static org.mockito.Mockito.mock; @@ -11,8 +11,8 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.config.Microserver; +import com.oath.micro.server.config.Config; +import com.oath.micro.server.config.Microserver; /** * Any new classes shoud be added into blackListedClasses for test to pass until proper solution with diff --git a/micro-core/src/test/java/com/oath/micro/server/utility/UsefulStaticMethodsTest.java b/micro-core/src/test/java/com/oath/micro/server/utility/UsefulStaticMethodsTest.java new file mode 100644 index 000000000..cb16e3aa9 --- /dev/null +++ b/micro-core/src/test/java/com/oath/micro/server/utility/UsefulStaticMethodsTest.java @@ -0,0 +1,17 @@ +package com.oath.micro.server.utility; + +import static com.oath.micro.server.utility.UsefulStaticMethods.either; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.*; + +import org.junit.Test; + +public class UsefulStaticMethodsTest { + + @Test + public void testEither() { + assertThat(either(null, "answer"), is("answer")); + assertThat(either("answer", "different"), is("answer")); + } + +} diff --git a/micro-core/src/test/java/nonautoscan/com/aol/micro/server/ConfiguredListener.java b/micro-core/src/test/java/nonautoscan/com/aol/micro/server/ConfiguredListener.java deleted file mode 100644 index d15010390..000000000 --- a/micro-core/src/test/java/nonautoscan/com/aol/micro/server/ConfiguredListener.java +++ /dev/null @@ -1,25 +0,0 @@ -package nonautoscan.com.aol.micro.server; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import lombok.Getter; - -public class ConfiguredListener implements ServletContextListener { - - @Getter - private static volatile int called= 0; - - @Override - public void contextInitialized(ServletContextEvent sce) { - called ++; - - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - - - } - -} \ No newline at end of file diff --git a/micro-core/src/test/java/nonautoscan/com/aol/micro/server/PropertyFileConfigTest.java b/micro-core/src/test/java/nonautoscan/com/aol/micro/server/PropertyFileConfigTest.java deleted file mode 100644 index 71f038db3..000000000 --- a/micro-core/src/test/java/nonautoscan/com/aol/micro/server/PropertyFileConfigTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package nonautoscan.com.aol.micro.server; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; - -import java.io.IOException; - -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.config.Config; -import com.aol.micro.server.spring.properties.PropertyFileConfig; -public class PropertyFileConfigTest { - - - - - - PropertyFileConfig config; - @Before - public void setUp() { - config = new PropertyFileConfig(); - } - - @Test - public void testPropertyPlaceholderConfigurer() throws IOException { - Config.instance(); - assertThat( config.propertyPlaceholderConfigurer(),notNullValue()); - } - - - -} diff --git a/micro-core/src/test/java/nonautoscan/com/aol/micro/server/ScheduleAndAsyncConfigTest.groovy b/micro-core/src/test/java/nonautoscan/com/aol/micro/server/ScheduleAndAsyncConfigTest.groovy deleted file mode 100644 index 071c36e08..000000000 --- a/micro-core/src/test/java/nonautoscan/com/aol/micro/server/ScheduleAndAsyncConfigTest.groovy +++ /dev/null @@ -1,56 +0,0 @@ -package nonautoscan.com.aol.micro.server - -import static org.junit.Assert.* -import groovy.transform.CompileStatic - -import org.junit.Before -import org.junit.Test -import org.mockito.Mockito -import org.springframework.scheduling.config.ScheduledTaskRegistrar -@CompileStatic -class ScheduleAndAsyncConfigTest { - - - ScheduleAndAsyncConfig config - @Before - public void setup(){ - config = new ScheduleAndAsyncConfig() - config.schedulerThreadPoolSize=3 - config.executorThreadPoolSize=3 - } - @Test - public void testSetExecutorThreadPoolSize() { - assert config.@executorThreadPoolSize==3 - } - - @Test - public void testSetSchedulerThreadPoolSize() { - - assert config.@schedulerThreadPoolSize==3 - } - - @Test - public void testGetAsyncExecutor() { - assert config.asyncExecutor !=null - } - - @Test - public void testConfigureTasks() { - ScheduledTaskRegistrar mock = Mockito.mock(ScheduledTaskRegistrar) - config.configureTasks(mock) - Mockito.verify(mock).setScheduler(Mockito.anyObject()) - } - - @Test - public void testTaskScheduler() { - assert config.taskScheduler()!=null - } - - @Test - public void testTaskExecutor() { - assert config.taskExecutor() != null - } - - - -} \ No newline at end of file diff --git a/micro-core/src/test/java/nonautoscan/com/oath/micro/server/ConfiguredListener.java b/micro-core/src/test/java/nonautoscan/com/oath/micro/server/ConfiguredListener.java new file mode 100644 index 000000000..cc1161808 --- /dev/null +++ b/micro-core/src/test/java/nonautoscan/com/oath/micro/server/ConfiguredListener.java @@ -0,0 +1,25 @@ +package nonautoscan.com.oath.micro.server; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import lombok.Getter; + +public class ConfiguredListener implements ServletContextListener { + + @Getter + private static volatile int called= 0; + + @Override + public void contextInitialized(ServletContextEvent sce) { + called ++; + + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + + + } + +} \ No newline at end of file diff --git a/micro-core/src/test/java/nonautoscan/com/oath/micro/server/PropertyFileConfigTest.java b/micro-core/src/test/java/nonautoscan/com/oath/micro/server/PropertyFileConfigTest.java new file mode 100644 index 000000000..7f341009e --- /dev/null +++ b/micro-core/src/test/java/nonautoscan/com/oath/micro/server/PropertyFileConfigTest.java @@ -0,0 +1,32 @@ +package nonautoscan.com.oath.micro.server; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; + +import java.io.IOException; + +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.config.Config; +import com.oath.micro.server.spring.properties.PropertyFileConfig; +public class PropertyFileConfigTest { + + + + + + PropertyFileConfig config; + @Before + public void setUp() { + config = new PropertyFileConfig(); + } + + @Test + public void testPropertyPlaceholderConfigurer() throws IOException { + Config.instance(); + assertThat( config.propertyPlaceholderConfigurer(),notNullValue()); + } + + + +} diff --git a/micro-core/src/test/java/nonautoscan/com/oath/micro/server/ScheduleAndAsyncConfigTest.groovy b/micro-core/src/test/java/nonautoscan/com/oath/micro/server/ScheduleAndAsyncConfigTest.groovy new file mode 100644 index 000000000..3090aa418 --- /dev/null +++ b/micro-core/src/test/java/nonautoscan/com/oath/micro/server/ScheduleAndAsyncConfigTest.groovy @@ -0,0 +1,55 @@ +package nonautoscan.com.oath.micro.server + +import groovy.transform.CompileStatic + +import org.junit.Before +import org.junit.Test +import org.mockito.Mockito +import org.springframework.scheduling.config.ScheduledTaskRegistrar +@CompileStatic +class ScheduleAndAsyncConfigTest { + + + ScheduleAndAsyncConfig config + @Before + public void setup(){ + config = new ScheduleAndAsyncConfig() + config.schedulerThreadPoolSize=3 + config.executorThreadPoolSize=3 + } + @Test + public void testSetExecutorThreadPoolSize() { + assert config.@executorThreadPoolSize==3 + } + + @Test + public void testSetSchedulerThreadPoolSize() { + + assert config.@schedulerThreadPoolSize==3 + } + + @Test + public void testGetAsyncExecutor() { + assert config.asyncExecutor !=null + } + + @Test + public void testConfigureTasks() { + ScheduledTaskRegistrar mock = Mockito.mock(ScheduledTaskRegistrar) + config.configureTasks(mock) + Mockito.verify(mock).setScheduler(Mockito.anyObject()) + } + + @Test + public void testTaskScheduler() { + assert config.taskScheduler()!=null + } + + @Test + public void testTaskExecutor() { + assert config.taskExecutor() != null + } + + + +} \ No newline at end of file diff --git a/micro-core/src/test/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-core/src/test/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index a9bb6d2fb..000000000 --- a/micro-core/src/test/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.module.MyPlugin \ No newline at end of file diff --git a/micro-core/src/test/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-core/src/test/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..665e9a846 --- /dev/null +++ b/micro-core/src/test/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.module.MyPlugin \ No newline at end of file diff --git a/micro-cors/README.md b/micro-cors/README.md new file mode 100644 index 000000000..bcf9cfabd --- /dev/null +++ b/micro-cors/README.md @@ -0,0 +1,44 @@ +# CORS Plugin + +[micro-cors example apps](https://github.com/aol/micro-server/tree/master/micro-cors/src/test/java/app) + +Set response headers for Cross Domain support via a Servlet Filter. Two CORS Filters are provided - simple and the more advanced Ebay CORS Filter. The Ebay CORS Filter is used by default. + +To select between them use the property cors.simple + + cors.simple=true + +or for the [ebay CORS Filter](https://github.com/eBay/cors-filter) + + cors.simple=false + + +## Configuration + +This simple CORS Filter sets the following headers + + Access-Control-Allow-Origin:"*" + Access-Control-Allow-Methods:"GET, POST, DELETE, PUT" + Access-Control-Allow-Headers:"X-Requested-With, Content-Type, X-Codingpedia + +The Ebay CORS Filter offers much more configuration options [https://github.com/eBay/cors-filter](https://github.com/eBay/cors-filter). You can optionally create a Spring bean of type Map with the name ebay-cors-config to configure the Filter init params descibed on the Ebay CORS Filter Github site. + + + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-cors/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-cors) + +Simply add to the classpath + +Maven + + + com.oath.microservices + micro-cors + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-cors:x.yz' diff --git a/micro-cors/build.gradle b/micro-cors/build.gradle index 7ae831560..d486bdfc3 100644 --- a/micro-cors/build.gradle +++ b/micro-cors/build.gradle @@ -1,61 +1,58 @@ description = 'micro-cors' -dependencies { - - compile project(':micro-core') - compile 'org.ebaysf.web:cors-filter:'+ebayCORSVersion - testCompile project(':micro-grizzly-with-jersey') - testCompile group: 'org.hamcrest', name: 'hamcrest-all', version:hamcrestVersion - - +dependencies { + compile project(':micro-core') + compile 'org.ebaysf.web:cors-filter:' + ebayCORSVersion + testCompile project(':micro-grizzly-with-jersey') + testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: hamcrestVersion } modifyPom { - project { - name 'Microserver cors' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-cors' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'marcocast' - name 'Marco Castigliego' - email 'marcocast@gmail.com' - } - } - - } + project { + name 'Microserver cors' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-cors' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'marcocast' + name 'Marco Castigliego' + email 'marcocast@gmail.com' + } + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-cors/readme.md b/micro-cors/readme.md deleted file mode 100644 index fad7f8d10..000000000 --- a/micro-cors/readme.md +++ /dev/null @@ -1,44 +0,0 @@ -# CORS Plugin - -[micro-cors example apps](https://github.com/aol/micro-server/tree/master/micro-cors/src/test/java/app) - -Set response headers for Cross Domain support via a Servlet Filter. Two CORS Filters are provided - simple and the more advanced Ebay CORS Filter. The Ebay CORS Filter is used by default. - -To select between them use the property cors.simple - - cors.simple=true - -or for the [ebay CORS Filter](https://github.com/eBay/cors-filter) - - cors.simple=false - - -## Configuration - -This simple CORS Filter sets the following headers - - Access-Control-Allow-Origin:"*" - Access-Control-Allow-Methods:"GET, POST, DELETE, PUT" - Access-Control-Allow-Headers:"X-Requested-With, Content-Type, X-Codingpedia - -The Ebay CORS Filter offers much more configuration options [https://github.com/eBay/cors-filter](https://github.com/eBay/cors-filter). You can optionally create a Spring bean of type Map with the name ebay-cors-config to configure the Filter init params descibed on the Ebay CORS Filter Github site. - - - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-cors/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-cors) - -Simply add to the classpath - -Maven - - - com.aol.microservices - micro-cors - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-cors:x.yz' diff --git a/micro-cors/src/main/java/com/aol/micro/server/web/cors/CorsPlugin.java b/micro-cors/src/main/java/com/aol/micro/server/web/cors/CorsPlugin.java deleted file mode 100644 index e0d00adca..000000000 --- a/micro-cors/src/main/java/com/aol/micro/server/web/cors/CorsPlugin.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.aol.micro.server.web.cors; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.web.cors.ebay.EbayCorsFilter; - - - - -public class CorsPlugin implements Plugin{ - - @Override - public PSetX springClasses(){ - return PSetX.of(CrossDomainFilter.class,EbayCorsFilter.class); - } - - - - -} diff --git a/micro-cors/src/main/java/com/aol/micro/server/web/cors/CrossDomainFilter.java b/micro-cors/src/main/java/com/aol/micro/server/web/cors/CrossDomainFilter.java deleted file mode 100644 index 1f0cdf3ec..000000000 --- a/micro-cors/src/main/java/com/aol/micro/server/web/cors/CrossDomainFilter.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.aol.micro.server.web.cors; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.FilterConfiguration; - -@Component(value = "crossDomainFilter") -public class CrossDomainFilter implements Filter, FilterConfiguration { - - private final boolean simple; - private final String mapping; - @Autowired - public CrossDomainFilter(@Value("${cors.simple:false}")boolean simple, - @Value("${cors.mapping:/*}")String mapping){ - this.simple=simple; - this.mapping = mapping; - } - public CrossDomainFilter(){ - simple=true; - mapping = "/*"; - } - @Override - public String[] getMapping() { - if(simple) - return new String[] {mapping }; - else - return new String[0]; - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - - } - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - HttpServletResponse resp = (HttpServletResponse) response; - resp.addHeader("Access-Control-Allow-Origin", "*"); - resp.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); - resp.addHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, X-Codingpedia"); - chain.doFilter(request, response); - } - - @Override - public void destroy() { - } -} diff --git a/micro-cors/src/main/java/com/aol/micro/server/web/cors/ebay/EbayCorsFilter.java b/micro-cors/src/main/java/com/aol/micro/server/web/cors/ebay/EbayCorsFilter.java deleted file mode 100644 index 3e44736dd..000000000 --- a/micro-cors/src/main/java/com/aol/micro/server/web/cors/ebay/EbayCorsFilter.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.aol.micro.server.web.cors.ebay; - -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.Filter; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.FilterConfiguration; - -@Component -public class EbayCorsFilter implements FilterConfiguration { - - - private final Map initParameters; - private final boolean simple; - private final String mapping; - - @Autowired(required=false) - public EbayCorsFilter(@Value("${cors.simple:false}")boolean simple, - @Qualifier("ebay-cors-config" ) Map initParameters, - @Value("${cors.mapping:/*}")String mapping){ - this.simple=simple; - this.initParameters = initParameters; - this.mapping = mapping; - } - - @Autowired(required=false) - public EbayCorsFilter(@Value("${cors.simple:false}")boolean simple,@Value("${cors.mapping:/*}")String mapping){ - this.simple=simple; - this.initParameters = new HashMap<>(); - this.mapping = mapping; - } - - @Override - public String[] getMapping() { - if(!simple) - return new String[] {mapping }; - else - return new String[0]; - } - - public Class getFilter() { - return org.ebaysf.web.cors.CORSFilter.class; - } - - public String getName() { - return "CORS Filter"; - } - - public Map getInitParameters(){ - return initParameters; - - } -} diff --git a/micro-cors/src/main/java/com/oath/micro/server/web/cors/ConfigureBeans.java b/micro-cors/src/main/java/com/oath/micro/server/web/cors/ConfigureBeans.java new file mode 100644 index 000000000..80542f952 --- /dev/null +++ b/micro-cors/src/main/java/com/oath/micro/server/web/cors/ConfigureBeans.java @@ -0,0 +1,86 @@ +package com.oath.micro.server.web.cors; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import javax.servlet.Filter; + +import cyclops.control.Either; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +import com.oath.micro.server.auto.discovery.FilterConfiguration; + +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; + +@Configuration +@NoArgsConstructor +@AllArgsConstructor +public class ConfigureBeans { + + @Value("${cors.simple:false}") + private boolean simple = false; + @Value("${cors.mapping:/*}") + private String mapping; + @Qualifier("ebay-cors-config" ) + @Autowired(required=false) + private Map initParameters; + + @Bean + public FilterConfiguration crossDomain(){ + return new FilterConfiguration() { + + @Override + public String getName() { + return "simple-cors"; + } + + @Override + public String[] getMapping() { + if(simple) + return new String[] {mapping }; + else + return new String[0]; + } + @Override + public Map getInitParameters() { + return Optional.ofNullable(initParameters).orElse(new HashMap<>()); + } + @Override + public Either, Filter> getFilter() { + return Either.left(CrossDomainFilter.class); + } + }; + } + @Bean + public FilterConfiguration ebayCrossDomain(){ + return new FilterConfiguration() { + @Override + public String getName() { + return "ebay-cors"; + } + @Override + public String[] getMapping() { + if(!simple) + return new String[] {mapping }; + else + return new String[0]; + } + + @Override + public Map getInitParameters() { + return Optional.ofNullable(initParameters).orElse(new HashMap<>()); + } + @Override + public Either, Filter> getFilter() { + return Either.left( org.ebaysf.web.cors.CORSFilter.class); + } + }; + } +} diff --git a/micro-cors/src/main/java/com/oath/micro/server/web/cors/CorsPlugin.java b/micro-cors/src/main/java/com/oath/micro/server/web/cors/CorsPlugin.java new file mode 100644 index 000000000..b2aaec16b --- /dev/null +++ b/micro-cors/src/main/java/com/oath/micro/server/web/cors/CorsPlugin.java @@ -0,0 +1,16 @@ +package com.oath.micro.server.web.cors; + + +import com.oath.micro.server.Plugin; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +public class CorsPlugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of(ConfigureBeans.class); + } + +} diff --git a/micro-cors/src/main/java/com/oath/micro/server/web/cors/CrossDomainFilter.java b/micro-cors/src/main/java/com/oath/micro/server/web/cors/CrossDomainFilter.java new file mode 100644 index 000000000..1e47a4d50 --- /dev/null +++ b/micro-cors/src/main/java/com/oath/micro/server/web/cors/CrossDomainFilter.java @@ -0,0 +1,34 @@ +package com.oath.micro.server.web.cors; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; + + +public class CrossDomainFilter implements Filter { + + + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletResponse resp = (HttpServletResponse) response; + resp.addHeader("Access-Control-Allow-Origin", "*"); + resp.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); + resp.addHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, X-Codingpedia"); + chain.doFilter(request, response); + } + + @Override + public void destroy() { + } +} diff --git a/micro-cors/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-cors/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index f5ffeac13..000000000 --- a/micro-cors/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.web.cors.CorsPlugin \ No newline at end of file diff --git a/micro-cors/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-cors/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..fff80b6fb --- /dev/null +++ b/micro-cors/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.web.cors.CorsPlugin \ No newline at end of file diff --git a/micro-cors/src/test/java/app/ebay/com/aol/micro/server/SingleClassTest.java b/micro-cors/src/test/java/app/ebay/com/aol/micro/server/SingleClassTest.java deleted file mode 100644 index d0f61f11c..000000000 --- a/micro-cors/src/test/java/app/ebay/com/aol/micro/server/SingleClassTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package app.ebay.com.aol.micro.server; - -import static org.junit.Assert.*; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -@Path("/single") -public class SingleClassTest implements RestResource{ - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( SingleClassTest.class, ()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target("http://localhost:8080/simple-app/single/ping"); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - assertFalse(request.get().getHeaders().containsKey("Access-Control-Allow-Origin")); - - - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-cors/src/test/java/app/ebay/com/oath/micro/server/SingleClassTest.java b/micro-cors/src/test/java/app/ebay/com/oath/micro/server/SingleClassTest.java new file mode 100644 index 000000000..8abafdf4b --- /dev/null +++ b/micro-cors/src/test/java/app/ebay/com/oath/micro/server/SingleClassTest.java @@ -0,0 +1,68 @@ +package app.ebay.com.oath.micro.server; + +import static org.junit.Assert.*; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +@Path("/single") +public class SingleClassTest implements RestResource{ + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( SingleClassTest.class, ()-> "simple-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target("http://localhost:8080/simple-app/single/ping"); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + assertFalse(request.get().getHeaders().containsKey("Access-Control-Allow-Origin")); + + + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-cors/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java b/micro-cors/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java deleted file mode 100644 index f5e62ceda..000000000 --- a/micro-cors/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package app.single.com.aol.micro.server; - -import static org.junit.Assert.assertTrue; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(properties={"cors.simple","true"}) -@Path("/single") -public class SingleClassTest implements RestResource{ - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( SingleClassTest.class, ()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target("http://localhost:8080/simple-app/single/ping"); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - assertTrue(request.get().getHeaders().containsKey("Access-Control-Allow-Origin")); - - - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-cors/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java b/micro-cors/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java new file mode 100644 index 000000000..66f1f6cd9 --- /dev/null +++ b/micro-cors/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java @@ -0,0 +1,68 @@ +package app.single.com.oath.micro.server; + +import static org.junit.Assert.assertTrue; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties={"cors.simple","true"}) +@Path("/single") +public class SingleClassTest implements RestResource{ + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( SingleClassTest.class, ()-> "simple-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target("http://localhost:8080/simple-app/single/ping"); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + assertTrue(request.get().getHeaders().containsKey("Access-Control-Allow-Origin")); + + + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-cors/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-cors/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-cors/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-cors/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-cors/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-cors/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-cors/src/test/java/com/oath/micro/server/web/cors/ConfigureBeansTest.java b/micro-cors/src/test/java/com/oath/micro/server/web/cors/ConfigureBeansTest.java new file mode 100644 index 000000000..a7190a582 --- /dev/null +++ b/micro-cors/src/test/java/com/oath/micro/server/web/cors/ConfigureBeansTest.java @@ -0,0 +1,35 @@ +package com.oath.micro.server.web.cors; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.fail; + +import java.util.HashMap; + +import org.junit.Test; +import static org.junit.Assert.assertThat; + +public class ConfigureBeansTest { + + @Test + public void testCrossDomainOn() { + ConfigureBeans config = new ConfigureBeans(true,"/*",new HashMap<>()); + assertThat(config.crossDomain().getMapping().length,equalTo(1)); + } + @Test + public void testCrossDomainOff() { + ConfigureBeans config = new ConfigureBeans(false,"/*",new HashMap<>()); + assertThat(config.crossDomain().getMapping().length,equalTo(0)); + } + + @Test + public void testEbayCrossDomainOn() { + ConfigureBeans config = new ConfigureBeans(false,"/*",new HashMap<>()); + assertThat(config.ebayCrossDomain().getMapping().length,equalTo(1)); + } + @Test + public void testEbayCrossDomainOff() { + ConfigureBeans config = new ConfigureBeans(true,"/*",new HashMap<>()); + assertThat(config.ebayCrossDomain().getMapping().length,equalTo(0)); + } + +} diff --git a/micro-cors/src/test/java/com/aol/micro/server/web/cors/CrossDomainFilterTest.java b/micro-cors/src/test/java/com/oath/micro/server/web/cors/CrossDomainFilterTest.java similarity index 78% rename from micro-cors/src/test/java/com/aol/micro/server/web/cors/CrossDomainFilterTest.java rename to micro-cors/src/test/java/com/oath/micro/server/web/cors/CrossDomainFilterTest.java index e87b4479b..5dcbee58c 100644 --- a/micro-cors/src/test/java/com/aol/micro/server/web/cors/CrossDomainFilterTest.java +++ b/micro-cors/src/test/java/com/oath/micro/server/web/cors/CrossDomainFilterTest.java @@ -1,6 +1,5 @@ -package com.aol.micro.server.web.cors; +package com.oath.micro.server.web.cors; -import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -23,7 +22,7 @@ public class CrossDomainFilterTest { @Before public void init() { - this.crossDomainFilter = new CrossDomainFilter(true,"/*"); + this.crossDomainFilter = new CrossDomainFilter(); } @Test @@ -44,10 +43,5 @@ public void testFilter() throws IOException, ServletException { inOrder.verify(filterChain, times(1)).doFilter(request, response); } - @Test - public void testFilterFalse() throws IOException, ServletException { - this.crossDomainFilter = new CrossDomainFilter(false,"/*"); - assertTrue(this.crossDomainFilter.getMapping().length==0); - - } + } diff --git a/micro-couchbase/README.md b/micro-couchbase/README.md new file mode 100644 index 000000000..9508a84e7 --- /dev/null +++ b/micro-couchbase/README.md @@ -0,0 +1,182 @@ +# Couchbase plugin for BASE microservices + +[micro-couchbase example apps](https://github.com/aol/micro-server/tree/master/micro-couchbase/src/test/java/app) + +Basically Available Soft statE + +* Simple Couchbase Client (Couchbase bucket as distributed / persistent map) +* Manifest comparator : Versioned key for loading refreshed state + +# Manifest comparison + +Manifest comparison stores a manifest along with each value. The manifest contains the version for the value, if the version has changed, the latest verson of the value will be loaded. + + + key : manifest [contains version info] + versionedKey : key with version + +This allows large immutable datastructures to be stored in as a key/value pair (with separate key/value pairing for version info), and reloaded automatically on change. + +## Injecting the manifest comparator + +Inject the Spring bean created by micro-couchbase ManifestComparator into your own beans. Customise the key used (allows multiple ManifestComparators to be used) + +```java +public class ManifestComparatorResource { + + + private final ManifestComparator comparator; + @Autowired + public ManifestComparatorResource(ManifestComparator comparator) { + this.comparator = comparator.withKey("test-key"); + } +``` + +## Create a scheduled job + +See micro-events, for Microserver help in managing scheduled jobs. + +Create a scheduled job to check the manifest for changes & automatically reload data when stale. + +In the example below we run the versioned key cleaner once per day, and check for changes every minute. + + ```java +@Component +public class DataLoader implements ScheduledJob{ + + private final ManifestComparator comparator; + @Autowired + public DataLoader(ManifestComparator comparator) { + this.comparator = comparator.withKey("test-key"); + } + @Override + public SystemData scheduleAndLog() { + try{ + boolean changed = comparator.isOutOfDate(); + comparator.load(); + return SystemData.builder().errors(0).processed(isOutOfDate?1:0).build(); + }catch(Exception e){ + return SystemData.builder().errors(1).processed(0).build(); + } + } + +} + +@Component +public class DataCleaner implements ScheduledJob{ + + private final ManifestComparator comparator; + @Autowired + public DataCleaner(ManifestComparator comparator) { + this.comparator = comparator.withKey("test-key"); + } + @Override + public SystemData scheduleAndLog() { + try{ + comparator.cleanAll(); + return SystemData.builder().errors(0).processed(1).build(); + }catch(Exception e){ + return SystemData.builder().errors(1).processed(0).build(); + } + + } + +} + +@Component +public class Schedular{ + + private final DataCleaner cleaner; + private final DataLoader loader; + + public Schedular(DataCleaner cleaner,DataLoader loader){ + this.cleaner = cleaner; + this.loader = loader; + } + + + @Scheduled(cron = "0 1 1 * * ?") + public synchronized void scheduleCleaner(){ + cleaner.scheduleAndLog(); + } + @Scheduled(cron = "0 * * * * *") + public synchronized void scheduleLoader(){ + loader.scheduleAndLog(); + } + +} + + ``` + +Elsewhere a single writer service can write data to the store for all services of a type to load. See micro-mysql or micro-curator for a DistributedLock implementation + +e.g. + + ```java + + @Component + public class DataWriter { + + private final DistributedLockService lockService; + + private final ManifestComparator comparator; + @Autowired + public DataWriter(DistributedLockService lockService,ManifestComparator comparator) { + this.lockService = lockService; + this.comparator = comparator.withKey("test-key"); + } + + public void write(Supplier data){ + if(lockService.tryLock("single-writer-lock-a") { + comparator.saveAndIncrement(data.get()); + } + } + + + + } + + ``` + +## Configurable properties + +Key used to store data used by the configured ManfiestComparator in Couchbase (default is default-key) + +couchbase.manifest.comparison.key=default-key + +Comma separate list of Couchbase servers + +couchbaseServers= + +Couchbase bucket (default is couchbase_bucket) to store / read data in + +couchbaseBucket=couchbase_bucket + +Couchbase password + +couchbasePassword= + +Switch off Couchbase enabled / disabled + +couchbaseClientEnabled:true + +Couchbase client operation + +couchbaseClientOperationTimeout:120000 + +## Getting The Microserver Couchbase Plugin + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-couchbase/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-couchbase) + +### Maven +```xml + + com.oath.microservices + micro-couchbase + x.yz + +``` +### Gradle +```groovy + compile 'com.oath.microservices:micro-couchbase:x.yz' + ``` diff --git a/micro-couchbase/build.gradle b/micro-couchbase/build.gradle index 6336ddedc..3b7e1b0da 100644 --- a/micro-couchbase/build.gradle +++ b/micro-couchbase/build.gradle @@ -1,94 +1,97 @@ +description = 'micro-couchbase' + apply plugin: 'groovy' apply plugin: 'java' + repositories { - - maven { url "https://jitpack.io" } + maven { url "https://jitpack.io" } } -description = 'micro-couchbase' dependencies { - compile group: 'com.couchbase.client', name: 'couchbase-client', version:'1.4.8' - compile project(':micro-core') - compile project(':micro-guava') - testCompile group: 'org.codehaus.groovy', name: 'groovy-all', version:'2.3.3' - testCompile(group: 'org.spockframework', name: 'spock-core', version:'0.7-groovy-2.0') { exclude(module: 'groovy-all') } - testCompile group: 'com.cyrusinnovation', name: 'mockito-groovy-support', version:'1.3' - testCompile 'cglib:cglib-nodep:2.2' - testCompile 'com.github.johnmcclean-aol:couchbasemock:master' - testCompile group: 'org.hamcrest', name: 'hamcrest-all', version:hamcrestVersion - testCompile project(':micro-grizzly-with-jersey') + compile group: 'com.couchbase.client', name: 'couchbase-client', version: '1.4.8' + compile project(':micro-manifest-comparator') + compile project(':micro-core') + compile project(':micro-guava') + testCompile group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.3.3' + testCompile(group: 'org.spockframework', name: 'spock-core', version: '0.7-groovy-2.0') { + exclude(module: 'groovy-all') + } + testCompile group: 'com.cyrusinnovation', name: 'mockito-groovy-support', version: '1.3' + testCompile 'cglib:cglib-nodep:2.2' + testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: hamcrestVersion + testCompile project(':micro-grizzly-with-jersey') } sourceSets { - main { - java { srcDirs = ['src/main/java']} - resources { srcDir 'src/main/resources' } - } - - test { - java { srcDirs = []} - groovy { srcDirs = ['src/test/java'] } - resources { srcDir 'src/test/resources' } - } - + main { + java { srcDirs = ['src/main/java'] } + resources { srcDir 'src/main/resources' } + } + + test { + java { srcDirs = [] } + groovy { srcDirs = ['src/test/java'] } + resources { srcDir 'src/test/resources' } + } + } modifyPom { - project { - name 'Microserver couchbase' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-couchbase' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - developer { - id 'pbujko' - name 'Przemyslaw Bujko' - email 'przemyslaw.bujko@teamaol.com' - } - } - - } + project { + name 'Microserver couchbase' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-couchbase' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'pbujko' + name 'Przemyslaw Bujko' + email 'przemyslaw.bujko@teamaol.com' + } + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-couchbase/readme.md b/micro-couchbase/readme.md deleted file mode 100644 index c1e090b1e..000000000 --- a/micro-couchbase/readme.md +++ /dev/null @@ -1,155 +0,0 @@ -# Couchbase plugin for BASE microservices - -[micro-couchbase example apps](https://github.com/aol/micro-server/tree/master/micro-couchbase/src/test/java/app) - -Basically Available Soft statE - -* Simple Couchbase Client (Couchbase bucket as distributed / persistent map) -* Manifest comparator : Versioned key for loading refreshed state - -# Manifest comparison - -Manifest comparison stores a manifest along with each value. The manifest contains the version for the value, if the version has changed, the latest verson of the value will be loaded. - - - key : manifest [contains version info] - versionedKey : key with version - -This allows large immutable datastructures to be stored in as a key/value pair (with separate key/value pairing for version info), and reloaded automatically on change. - -## Injecting the manifest comparator - -Inject the Spring bean created by micro-couchbase ManifestComparator into your own beans. Customise the key used (allows multiple ManifestComparators to be used) - -```java -public class ManifestComparatorResource { - - - private final ManifestComparator comparator; - @Autowired - public ManifestComparatorResource(ManifestComparator comparator) { - this.comparator = comparator.withKey("test-key"); - } -``` - -## Create a scheduled job - -See micro-events, for Microserver help in managing scheduled jobs. - -Create a scheduled job to check the manifest for changes & automatically reload data when stale. - -In the example below we run the versioned key cleaner once per day, and check for changes every minute. - - ```java -@Component -public class DataLoader implements ScheduledJob{ - - private final ManifestComparator comparator; - @Autowired - public DataLoader(ManifestComparator comparator) { - this.comparator = comparator.withKey("test-key"); - } - @Override - public SystemData scheduleAndLog() { - try{ - boolean changed = comparator.isOutOfDate(); - comparator.load(); - return SystemData.builder().errors(0).processed(isOutOfDate?1:0).build(); - }catch(Exception e){ - return SystemData.builder().errors(1).processed(0).build(); - } - } - -} - -@Component -public class DataCleaner implements ScheduledJob{ - - private final ManifestComparator comparator; - @Autowired - public DataCleaner(ManifestComparator comparator) { - this.comparator = comparator.withKey("test-key"); - } - @Override - public SystemData scheduleAndLog() { - try{ - comparator.cleanAll(); - return SystemData.builder().errors(0).processed(1).build(); - }catch(Exception e){ - return SystemData.builder().errors(1).processed(0).build(); - } - - } - -} - -@Component -public class Schedular{ - - private final DataCleaner cleaner; - private final DataLoader loader; - - public Schedular(DataCleaner cleaner,DataLoader loader){ - this.cleaner = cleaner; - this.loader = loader; - } - - - @Scheduled(cron = "0 1 1 * * ?") - public synchronized void scheduleCleaner(){ - cleaner.scheduleAndLog(); - } - @Scheduled(cron = "0 * * * * *") - public synchronized void scheduleLoader(){ - loader.scheduleAndLog(); - } - -} - - ``` - -Elsewhere a single writer service can write data to the store for all services of a type to load. See micro-mysql or micro-curator for a DistributedLock implementation - -e.g. - - ```java - @Component - public class DataWriter { - - private final DistributedLockService lockService; - - private final ManifestComparator comparator; - @Autowired - public DataWriter(DistributedLockService lockService,ManifestComparator comparator) { - this.lockService = lockService; - this.comparator = comparator.withKey("test-key"); - } - - public void write(Supplier data){ - if(lockService.tryLock("single-writer-lock-a") { - comparator.saveAndIncrement(data.get()); - } - } - - - - } - - ``` - -## Getting The Microserver Couchbase Plugin - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-couchbase/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-couchbase) - -### Maven -```xml - - com.aol.microservices - micro-couchbase - x.yz - -``` -### Gradle -```groovy - compile 'com.aol.microservices:micro-couchbase:x.yz' - ``` diff --git a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/ConfigureCouchbase.java b/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/ConfigureCouchbase.java deleted file mode 100644 index 19ff7f964..000000000 --- a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/ConfigureCouchbase.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.aol.micro.server.couchbase; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import lombok.Setter; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.StringUtils; - -import com.aol.micro.server.couchbase.base.ManifestComparator; -import com.couchbase.client.CouchbaseClient; -import com.couchbase.client.CouchbaseConnectionFactory; -import com.couchbase.client.CouchbaseConnectionFactoryBuilder; - -@Configuration -public class ConfigureCouchbase { - - private Logger logger = LoggerFactory.getLogger(getClass()); - - @Setter - @Value("${couchbaseServers:}") - private String couchbaseServers; - - @Value("${couchbaseBucket:couchbase_bucket}") - private String couchbaseBucket; - - @Value("${couchbasePassword:}") - private String couchbasePassword; - - - - @Setter - @Value("${couchbaseClientEnabled:true}") - private boolean couchbaseClientEnabled = true; - - @Value("${couchbaseClientOperationTimeout:120000}") - private long opTimeout; - - @SuppressWarnings("rawtypes") - @Bean(name = "couchbaseDistributedMap") - public DistributedMapClient simpleCouchbaseClient() throws IOException, URISyntaxException { - if (couchbaseClientEnabled) { - return new DistributedMapClient(couchbaseClient()); - } else { - return new DistributedMapClient(null); - } - } - - @Bean(name = "couchbaseClient") - public CouchbaseClient couchbaseClient() throws IOException, URISyntaxException { - if (couchbaseClientEnabled) { - logger.info("Creating CouchbaseClient for servers: {}", couchbaseServers); - CouchbaseConnectionFactoryBuilder builder = new CouchbaseConnectionFactoryBuilder(); - builder.setOpTimeout(opTimeout); - CouchbaseConnectionFactory cf = builder.buildCouchbaseConnection(getServersList(), couchbaseBucket, - StringUtils.trimAllWhitespace(Optional.ofNullable(couchbasePassword).orElse(""))); - return new CouchbaseClient(cf); - } - return null; - - } - @Bean - public ManifestComparator couchbaseManifestComparator() throws IOException, URISyntaxException{ - return new ManifestComparator(this.simpleCouchbaseClient()); - } - - private List getServersList() throws URISyntaxException { - List uris = new ArrayList(); - if(couchbaseServers.indexOf(',')==-1){ - uris.add(new URI(couchbaseServers)); - return uris; - } - - for (String serverHost : StringUtils.split(couchbaseServers, ",")) { - uris.add(new URI(serverHost)); - } - return uris; - } - -} diff --git a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/CouchbasePlugin.java b/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/CouchbasePlugin.java deleted file mode 100644 index 9b5729941..000000000 --- a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/CouchbasePlugin.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.aol.micro.server.couchbase; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; - -public class CouchbasePlugin implements Plugin { - - public PSetX springClasses() { - return PSetX.of(ConfigureCouchbase.class); - } -} diff --git a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/DistributedMapClient.java b/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/DistributedMapClient.java deleted file mode 100644 index 4aecbacf3..000000000 --- a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/DistributedMapClient.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.aol.micro.server.couchbase; - -import java.util.Optional; -import java.util.concurrent.ExecutionException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.aol.cyclops.util.ExceptionSoftener; -import com.couchbase.client.CouchbaseClient; - -public class DistributedMapClient { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private final Optional couchbaseClient; - - public DistributedMapClient(CouchbaseClient couchbaseClient) { - - this.couchbaseClient = Optional.ofNullable(couchbaseClient); - } - - - public boolean put(final String key, final V value) { - logger.debug("put '{}', value:{}", key, value); - return couchbaseClient.map(c->putInternal(c,key,value)).orElse(false); - - } - private boolean putInternal(final CouchbaseClient client, final String key, final V value){ - - try{ - return client.set(key, value).get(); - } catch (InterruptedException | ExecutionException e) { - throw ExceptionSoftener.throwSoftenedException(e); - - } - } - - - - public Optional get(String key) { - return couchbaseClient.map(c->(V)c.get(key)); - - } - - public void delete(String key) { - couchbaseClient.map(c->c.delete(key)); - } -} diff --git a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/base/Data.java b/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/base/Data.java deleted file mode 100644 index ee1a1a1e0..000000000 --- a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/base/Data.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.aol.micro.server.couchbase.base; - -import java.io.Serializable; -import java.util.Date; - -import lombok.Getter; - -public class Data implements Serializable{ - - private static final long serialVersionUID = 1L; - @Getter - private final T data; - @Getter - private final Date date; - @Getter - private final String versionedKey; - - public Data(T data, Date date, String versionedKey){ - this.data = data; - this.date = date; - this.versionedKey = versionedKey; - } -} diff --git a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/base/ManifestComparator.java b/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/base/ManifestComparator.java deleted file mode 100644 index a006113e9..000000000 --- a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/base/ManifestComparator.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.aol.micro.server.couchbase.base; - -import java.util.Date; -import java.util.Optional; - -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Wither; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.aol.cyclops.util.ExceptionSoftener; -import com.aol.micro.server.couchbase.DistributedMapClient; -import com.aol.micro.server.rest.jackson.JacksonUtil; - -/** - * Manifest comparator for use with a distributed map -assumes single producer / multiple consumers - * - * Uses to entries in the map - * - * key : versioned key - * versioned key : actual data - * - * ManifestComparator stores the current version number, only when the version changes is the full - * data set loaded from the remote store. - * - * Usage as a Spring Bean - inject into the host class, and use withKey to customise for the targeted Key. - * - * - *
- * {@code 
- * @Rest
-	public class MyDataService {
-	
-
-	
-	private final ManifestComparator comparator;
-	@Autowired
-	public  MyDataService(ManifestComparator comparator) {
-		this.comparator = comparator.withKey("test-key");
-	}
- * 
- * }
- * 
- * - * micro-couchbase configures a single ManifestComparator bean that can be customized for multiple different keys via - * withKey - * - * When your bean is injected save via saveAndIncrement, and periodically call load() to refresh data if (and only if) - * it has changed. - * - * ManifestComparator will automatically remove old versions on saveAndIncrement, but system outages may occasionally cause old keys - * to linger, you can also use clean & cleanAll to periodically to remove old key versions. - * - * - * @author johnmcclean - * - * @param - */ -@AllArgsConstructor(access=AccessLevel.PRIVATE) -public class ManifestComparator { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - @Wither - private final String key; - - @Getter - private volatile T data; - - @Getter - private volatile String versionedKey; - private final DistributedMapClient connection; - - /** - * Create a ManifestComparator with the supplied distributed map client - * Data stored by ManifestComparator will be - * - * key : versioned key - * versioned key : actual data - * @param connection DistributedMapClient to store comparison data - */ - public ManifestComparator(DistributedMapClient connection) { - this.key = "default"; - this.versionedKey = newKey(1L).toJson(); - this.connection = connection; - } - /** - * Create a ManifestComparator with the supplied distributed map client - * - * Data stored by ManifestComparator will be - * - * key : versioned key - * versioned key : actual data - * - * @param key To store actual data with - * @param connection DistributeMapClient connection - */ - public ManifestComparator(String key,DistributedMapClient connection) { - this.key = key; - this.versionedKey = newKey(1L).toJson(); - this.connection = connection; - } - - /** - * Create a new ManifestComparator with the same distributed map connection - * that targets a different key - * - * @param key Key to store data with - * @return new ManifestComparator that targets specified key - */ - public ManifestComparator withKey(String key){ - return new ManifestComparator<>(key, connection); - } - - private VersionedKey newKey(Long version) { - return new VersionedKey(key, version); - } - - private VersionedKey increment() { - VersionedKey currentVersionedKey = loadKeyFromCouchbase(); - return currentVersionedKey.withVersion(currentVersionedKey.getVersion() + 1); - } - - private VersionedKey loadKeyFromCouchbase() { - Optional optionalKey = connection.get(key); - return optionalKey.flatMap( val -> Optional.of(JacksonUtil.convertFromJson( val, VersionedKey.class))) - .orElse( newKey(0L)); - - } - - /** - * @return true - if current data is stale and needs refreshed - */ - public boolean isOutOfDate() { - - return !versionedKey.equals(loadKeyFromCouchbase().toJson()); - } - - /** - * Load data from remote store if stale - */ - public synchronized void load() { - T oldData = data; - String oldKey = versionedKey; - try { - if (isOutOfDate()) { - String newVersionedKey = (String) connection.get(key).get(); - data = (T) nonAtomicload(newVersionedKey); - versionedKey = newVersionedKey; - } - } catch (Throwable e) { - data = oldData; - versionedKey = oldKey; - logger.debug( e.getMessage(), e); - throw ExceptionSoftener.throwSoftenedException(e); - } - } - - @SuppressWarnings("unchecked") - private Object nonAtomicload(String newVersionedKey) throws Throwable { - Data data = (Data) connection.get(newVersionedKey).orElseThrow(() -> { - return new ManifestComparatorKeyNotFoundException("Missing versioned key " + newVersionedKey + " - likely data changed during read"); - }); - logger.info( "Loaded new data with date {} for key {}, versionedKey {}, versionedKey from data ", - new Object[]{data.getDate(), key, newVersionedKey, data.getVersionedKey()}); - return data.getData(); - } - - /** - * Clean all old (not current) versioned keys - */ - public void cleanAll() { - clean(-1); - } - - /** - * Clean specified number of old (not current) versioned keys) - * - * @param numberToClean - */ - public void clean(int numberToClean) { - logger.info("Attempting to delete the last {} records for key {}",numberToClean,key); - VersionedKey currentVersionedKey = loadKeyFromCouchbase(); - long start = 0; - if (numberToClean != -1) - start = currentVersionedKey.getVersion() - numberToClean; - for (long i = start; i < currentVersionedKey.getVersion(); i++) { - delete(currentVersionedKey.withVersion(i).toJson()); - } - logger.info("Finished deleting the last {} records for key {}",numberToClean,key); - } - - private void delete(String withVersion) { - connection.delete(withVersion); - } - - /** - * Save provided data with the key this ManifestComparator manages - * bump the versioned key version. - * - * NB : To avoid race conditions - make sure only one service (an elected leader) can write at a time (see micro-mysql for a mysql distributed lock, - * or micro-curator for a curator / zookeeper distributed lock implementation). - * - * @param data to save - */ - public void saveAndIncrement(T data) { - T oldData = this.data; - VersionedKey newVersionedKey = increment(); - logger.info( "Saving data with key {}, new version is {}", key,newVersionedKey.toJson()); - connection.put(newVersionedKey.toJson(), new Data(data, new Date(), newVersionedKey.toJson())); - connection.put(key, newVersionedKey.toJson()); - try { - this.data = data; - delete(versionedKey); - - } catch(Throwable t){ - this.data = oldData; - }finally { - versionedKey = newVersionedKey.toJson(); - } - } - -} diff --git a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/base/ManifestComparatorKeyNotFoundException.java b/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/base/ManifestComparatorKeyNotFoundException.java deleted file mode 100644 index fa34f2627..000000000 --- a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/base/ManifestComparatorKeyNotFoundException.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.aol.micro.server.couchbase.base; - - - -public class ManifestComparatorKeyNotFoundException extends RuntimeException{ - - public ManifestComparatorKeyNotFoundException(String message) { - super(message); - - } - -} diff --git a/micro-couchbase/src/main/java/com/oath/micro/server/couchbase/ConfigureCouchbase.java b/micro-couchbase/src/main/java/com/oath/micro/server/couchbase/ConfigureCouchbase.java new file mode 100644 index 000000000..b718f065a --- /dev/null +++ b/micro-couchbase/src/main/java/com/oath/micro/server/couchbase/ConfigureCouchbase.java @@ -0,0 +1,97 @@ +package com.oath.micro.server.couchbase; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; + +import com.oath.micro.server.couchbase.base.CouchbaseManifestComparator; +import com.couchbase.client.CouchbaseClient; +import com.couchbase.client.CouchbaseConnectionFactory; +import com.couchbase.client.CouchbaseConnectionFactoryBuilder; + +import lombok.Setter; + +@Configuration +public class ConfigureCouchbase { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Value("${couchbase.manifest.comparison.key:default-key}") + private String defaultCouchbaseManifestComparisonKey; + @Setter + @Value("${couchbaseServers:}") + private String couchbaseServers; + + @Value("${couchbaseBucket:couchbase_bucket}") + private String couchbaseBucket; + + @Value("${couchbasePassword:}") + private String couchbasePassword; + + @Setter + @Value("${couchbaseClientEnabled:true}") + private boolean couchbaseClientEnabled = true; + + @Value("${couchbaseClientOperationTimeout:120000}") + private long opTimeout; + + @SuppressWarnings("rawtypes") + @Bean(name = "couchbaseDistributedMap") + public CouchbaseDistributedMapClient simpleCouchbaseClient() throws IOException, URISyntaxException { + if (couchbaseClientEnabled) { + return new CouchbaseDistributedMapClient( + couchbaseClient()); + } else { + return new CouchbaseDistributedMapClient( + null); + } + } + + @Bean(name = "couchbaseClient") + public CouchbaseClient couchbaseClient() throws IOException, URISyntaxException { + if (couchbaseClientEnabled) { + logger.info("Creating CouchbaseClient for servers: {}", couchbaseServers); + CouchbaseConnectionFactoryBuilder builder = new CouchbaseConnectionFactoryBuilder(); + builder.setOpTimeout(opTimeout); + CouchbaseConnectionFactory cf = builder.buildCouchbaseConnection(getServersList(), couchbaseBucket, + StringUtils.trimAllWhitespace(Optional.ofNullable(couchbasePassword) + .orElse(""))); + return new CouchbaseClient( + cf); + } + return null; + + } + + @Bean + public CouchbaseManifestComparator couchbaseManifestComparator() throws IOException, URISyntaxException { + return new CouchbaseManifestComparator( + this.simpleCouchbaseClient()).withKey(defaultCouchbaseManifestComparisonKey); + } + + private List getServersList() throws URISyntaxException { + List uris = new ArrayList(); + if (couchbaseServers.indexOf(',') == -1) { + uris.add(new URI( + couchbaseServers)); + return uris; + } + + for (String serverHost : StringUtils.split(couchbaseServers, ",")) { + uris.add(new URI( + serverHost)); + } + return uris; + } + +} diff --git a/micro-couchbase/src/main/java/com/oath/micro/server/couchbase/CouchbaseDistributedMapClient.java b/micro-couchbase/src/main/java/com/oath/micro/server/couchbase/CouchbaseDistributedMapClient.java new file mode 100644 index 000000000..70435ed9e --- /dev/null +++ b/micro-couchbase/src/main/java/com/oath/micro/server/couchbase/CouchbaseDistributedMapClient.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.couchbase; + +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +import com.oath.cyclops.util.ExceptionSoftener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.oath.micro.server.distributed.DistributedMap; +import com.couchbase.client.CouchbaseClient; + +public class CouchbaseDistributedMapClient implements DistributedMap { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + private final Optional couchbaseClient; + + public CouchbaseDistributedMapClient(CouchbaseClient couchbaseClient) { + + this.couchbaseClient = Optional.ofNullable(couchbaseClient); + } + + @Override + public boolean put(final String key, final V value) { + logger.debug("put '{}', value:{}", key, value); + return couchbaseClient.map(c -> putInternal(c, key, value)) + .orElse(false); + + } + + private boolean putInternal(final CouchbaseClient client, final String key, final V value) { + + try { + return client.set(key, value) + .get(); + } catch (InterruptedException | ExecutionException e) { + throw ExceptionSoftener.throwSoftenedException(e); + + } + } + + @Override + public Optional get(String key) { + return couchbaseClient.map(c -> (V) c.get(key)); + + } + + @Override + public void delete(String key) { + couchbaseClient.map(c -> c.delete(key)); + } +} diff --git a/micro-couchbase/src/main/java/com/oath/micro/server/couchbase/CouchbasePlugin.java b/micro-couchbase/src/main/java/com/oath/micro/server/couchbase/CouchbasePlugin.java new file mode 100644 index 000000000..430c9979d --- /dev/null +++ b/micro-couchbase/src/main/java/com/oath/micro/server/couchbase/CouchbasePlugin.java @@ -0,0 +1,13 @@ +package com.oath.micro.server.couchbase; + +import com.oath.micro.server.Plugin; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +public class CouchbasePlugin implements Plugin { + + public Set springClasses() { + return SetX.of(ConfigureCouchbase.class); + } +} diff --git a/micro-couchbase/src/main/java/com/oath/micro/server/couchbase/base/CouchbaseManifestComparator.java b/micro-couchbase/src/main/java/com/oath/micro/server/couchbase/base/CouchbaseManifestComparator.java new file mode 100644 index 000000000..1bd352839 --- /dev/null +++ b/micro-couchbase/src/main/java/com/oath/micro/server/couchbase/base/CouchbaseManifestComparator.java @@ -0,0 +1,279 @@ +package com.oath.micro.server.couchbase.base; + +import java.util.Date; +import java.util.Optional; + +import com.oath.cyclops.util.ExceptionSoftener; +import cyclops.control.Either; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +import com.oath.micro.server.distributed.DistributedMap; +import com.oath.micro.server.manifest.Data; +import com.oath.micro.server.manifest.ManifestComparator; +import com.oath.micro.server.manifest.ManifestComparatorKeyNotFoundException; +import com.oath.micro.server.manifest.VersionedKey; +import com.oath.micro.server.rest.jackson.JacksonUtil; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.SneakyThrows; + +/** + * Manifest comparator for use with a distributed map -assumes single producer / + * multiple consumers + * + * Uses to entries in the map + * + * key : versioned key versioned key : actual data + * + * ManifestComparator stores the current version number, only when the version + * changes is the full data set loaded from the remote store. + * + * Usage as a Spring Bean - inject into the host class, and use withKey to + * customise for the targeted Key. + * + * + *
+ * {@code 
+ * @Rest
+	public class MyDataService {
+	
+
+	
+	private final ManifestComparator comparator;
+	@Autowired
+	public  MyDataService(ManifestComparator comparator) {
+		this.comparator = comparator.withKey("test-key");
+	}
+ * 
+ * }
+ * 
+ * + * micro-couchbase configures a single ManifestComparator bean that can be + * customized for multiple different keys via withKey + * + * When your bean is injected save via saveAndIncrement, and periodically call + * load() to refresh data if (and only if) it has changed. + * + * ManifestComparator will automatically remove old versions on + * saveAndIncrement, but system outages may occasionally cause old keys to + * linger, you can also use clean & cleanAll to periodically to remove old key + * versions. + * + * + * @author johnmcclean + * + * @param + */ +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class CouchbaseManifestComparator implements ManifestComparator { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + private final String key; + + private volatile Either data = Either.left(null); // Void represents + // an unitialized + // state + + @Getter + private volatile String versionedKey; + private final DistributedMap connection; + + /** + * Create a ManifestComparator with the supplied distributed map client Data + * stored by ManifestComparator will be + * + * key : versioned key versioned key : actual data + * + * @param connection + * DistributedMapClient to store comparison data + */ + public CouchbaseManifestComparator(DistributedMap connection) { + this.key = "default"; + this.versionedKey = newKey(1L).toJson(); + this.connection = connection; + } + + /** + * Create a ManifestComparator with the supplied distributed map client + * + * Data stored by ManifestComparator will be + * + * key : versioned key versioned key : actual data + * + * @param key + * To store actual data with + * @param connection + * DistributeMapClient connection + */ + public CouchbaseManifestComparator(String key, DistributedMap connection) { + this.key = key; + this.versionedKey = newKey(1L).toJson(); + this.connection = connection; + } + + /** + * Create a new ManifestComparator with the same distributed map connection + * that targets a different key + * + * @param key + * Key to store data with + * @return new ManifestComparator that targets specified key + */ + @Override + public CouchbaseManifestComparator withKey(String key) { + return new CouchbaseManifestComparator<>( + key, connection); + } + + private VersionedKey newKey(Long version) { + return new VersionedKey( + key, version); + } + + private VersionedKey increment() { + VersionedKey currentVersionedKey = loadKeyFromCouchbase(); + return currentVersionedKey.withVersion(currentVersionedKey.getVersion() + 1); + } + + private VersionedKey loadKeyFromCouchbase() { + Optional optionalKey = connection.get(key); + return optionalKey.flatMap(val -> Optional.of(JacksonUtil.convertFromJson(val, VersionedKey.class))) + .orElse(newKey(0L)); + + } + + @Override + @SneakyThrows + public T getData() { + while (data.isLeft()) { + Thread.sleep(500); + } + return data.orElse(null); + } + + @Override + public T getCurrentData() { + return data.fold(present -> present, () -> null); + } + + /** + * @return true - if current data is stale and needs refreshed + */ + @Override + public boolean isOutOfDate() { + + return !versionedKey.equals(loadKeyFromCouchbase().toJson()); + } + + /** + * Load data from remote store if stale + */ + @Override + public synchronized boolean load() { + Either oldData = data; + String oldKey = versionedKey; + try { + if (isOutOfDate()) { + String newVersionedKey = (String) connection.get(key) + .get(); + data = Either.right((T) nonAtomicload(newVersionedKey)); + versionedKey = newVersionedKey; + } else { + return false; + } + } catch (Throwable e) { + data = oldData; + versionedKey = oldKey; + logger.debug(e.getMessage(), e); + throw ExceptionSoftener.throwSoftenedException(e); + } + return true; + } + + @SuppressWarnings("unchecked") + private Object nonAtomicload(String newVersionedKey) throws Throwable { + Data data = (Data) connection.get(newVersionedKey) + .orElseThrow(() -> { + return new ManifestComparatorKeyNotFoundException( + "Missing versioned key " + + newVersionedKey + + " - likely data changed during read"); + }); + logger.info("Loaded new data with date {} for key {}, versionedKey {}, versionedKey from data ", + new Object[] { data.getDate(), key, newVersionedKey, data.getVersionedKey() }); + return data.getData(); + } + + /** + * Clean all old (not current) versioned keys + */ + @Override + public void cleanAll() { + clean(-1); + } + + /** + * Clean specified number of old (not current) versioned keys) + * + * @param numberToClean + */ + @Override + public void clean(int numberToClean) { + logger.info("Attempting to delete the last {} records for key {}", numberToClean, key); + VersionedKey currentVersionedKey = loadKeyFromCouchbase(); + long start = 0; + if (numberToClean != -1) + start = currentVersionedKey.getVersion() - numberToClean; + for (long i = start; i < currentVersionedKey.getVersion(); i++) { + delete(currentVersionedKey.withVersion(i) + .toJson()); + } + logger.info("Finished deleting the last {} records for key {}", numberToClean, key); + } + + private void delete(String withVersion) { + connection.delete(withVersion); + } + + /** + * Save provided data with the key this ManifestComparator manages bump the + * versioned key version. + * + * NB : To avoid race conditions - make sure only one service (an elected + * leader) can write at a time (see micro-mysql for a mysql distributed + * lock, or micro-curator for a curator / zookeeper distributed lock + * implementation). + * + * @param data + * to save + */ + @Override + public void saveAndIncrement(T data) { + Either oldData = this.data; + VersionedKey newVersionedKey = increment(); + logger.info("Saving data with key {}, new version is {}", key, newVersionedKey.toJson()); + connection.put(newVersionedKey.toJson(), new Data( + data, new Date(), newVersionedKey.toJson())); + connection.put(key, newVersionedKey.toJson()); + try { + this.data = Either.right(data); + delete(versionedKey); + + } catch (Throwable t) { + this.data = oldData; + } finally { + versionedKey = newVersionedKey.toJson(); + } + } + + @Override + public String toString() { + return "[CouchbaseManifestComparator:key:" + key + ",versionedKey:" + JacksonUtil.serializeToJson(versionedKey) + + "]"; + } +} diff --git a/micro-couchbase/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-couchbase/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 2785a0dfc..000000000 --- a/micro-couchbase/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.couchbase.CouchbasePlugin \ No newline at end of file diff --git a/micro-couchbase/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-couchbase/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..4db0ad9b8 --- /dev/null +++ b/micro-couchbase/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.couchbase.CouchbasePlugin \ No newline at end of file diff --git a/micro-couchbase/src/test/java/app/couchbase/distributed/map/com/aol/micro/server/CouchbaseResource.java b/micro-couchbase/src/test/java/app/couchbase/distributed/map/com/aol/micro/server/CouchbaseResource.java deleted file mode 100644 index 6e01b266d..000000000 --- a/micro-couchbase/src/test/java/app/couchbase/distributed/map/com/aol/micro/server/CouchbaseResource.java +++ /dev/null @@ -1,31 +0,0 @@ -package app.couchbase.distributed.map.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import org.springframework.beans.factory.annotation.Autowired; - -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.couchbase.DistributedMapClient; - -@Path("/couchbase") -@Rest -public class CouchbaseResource { - - private final DistributedMapClient client; - @Autowired - public CouchbaseResource(DistributedMapClient client) { - this.client = client; - } - @GET - @Path("/get") - public String bucket(){ - return client.get("hello").toString(); - } - @GET - @Path("/put") - public String put(){ - client.put("hello", "world"); - return "added"; - } -} diff --git a/micro-couchbase/src/test/java/app/couchbase/distributed/map/com/aol/micro/server/CouchbaseRunnerTest.java b/micro-couchbase/src/test/java/app/couchbase/distributed/map/com/aol/micro/server/CouchbaseRunnerTest.java deleted file mode 100644 index 42753e749..000000000 --- a/micro-couchbase/src/test/java/app/couchbase/distributed/map/com/aol/micro/server/CouchbaseRunnerTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package app.couchbase.distributed.map.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.containsString; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.couchbase.mock.CouchbaseMock; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(properties={"couchbaseServers","http://localhost:8091/pools", - "couchbasePassword","", - "couchbaseBucket","beer-sample"}) -public class CouchbaseRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer() { - try{ - //couchbase already running? - rest.get("http://localhost:8091/pools"); - }catch(Exception e){ - //start mock couchbase - CouchbaseMock.main(new String[]{"-S"}); - } - server = new MicroserverApp(ConfigurableModule.builder() - .context("simple-app").build()); - - server.start(); - - } - - @After - public void stopServer() { - server.stop(); - } - - @Test @Ignore - public void runAppAndBasicTest() throws InterruptedException, - ExecutionException { - rest.get("http://localhost:8080/simple-app/couchbase/put"); - assertThat(rest.get("http://localhost:8080/simple-app/couchbase/get"), - containsString("world")); - - } - -} diff --git a/micro-couchbase/src/test/java/app/couchbase/distributed/map/com/oath/micro/server/CouchbaseResource.java b/micro-couchbase/src/test/java/app/couchbase/distributed/map/com/oath/micro/server/CouchbaseResource.java new file mode 100644 index 000000000..599a78018 --- /dev/null +++ b/micro-couchbase/src/test/java/app/couchbase/distributed/map/com/oath/micro/server/CouchbaseResource.java @@ -0,0 +1,35 @@ +package app.couchbase.distributed.map.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.distributed.DistributedMap; + +@Path("/couchbase") +@Rest +public class CouchbaseResource { + + private final DistributedMap client; + + @Autowired + public CouchbaseResource(DistributedMap client) { + this.client = client; + } + + @GET + @Path("/get") + public String bucket() { + return client.get("hello") + .toString(); + } + + @GET + @Path("/put") + public String put() { + client.put("hello", "world"); + return "added"; + } +} diff --git a/micro-couchbase/src/test/java/app/couchbase/distributed/map/com/oath/micro/server/CouchbaseRunnerTest.java b/micro-couchbase/src/test/java/app/couchbase/distributed/map/com/oath/micro/server/CouchbaseRunnerTest.java new file mode 100644 index 000000000..52de3a77d --- /dev/null +++ b/micro-couchbase/src/test/java/app/couchbase/distributed/map/com/oath/micro/server/CouchbaseRunnerTest.java @@ -0,0 +1,58 @@ +package app.couchbase.distributed.map.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.couchbase.mock.CouchbaseMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { "couchbaseServers", "http://localhost:8091/pools", "couchbasePassword", "", + "couchbaseBucket", "beer-sample" }) +public class CouchbaseRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + try { + // couchbase already running? + rest.get("http://localhost:8091/pools"); + } catch (Exception e) { + // start mock couchbase + CouchbaseMock.main(new String[] { "-S" }); + } + server = new MicroserverApp( + ConfigurableModule.builder() + .context("simple-app") + .build()); + + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + @Ignore + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + rest.get("http://localhost:8080/simple-app/couchbase/put"); + assertThat(rest.get("http://localhost:8080/simple-app/couchbase/get"), containsString("world")); + + } + +} diff --git a/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/aol/micro/server/copy/ManifestComparatorResource.java b/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/aol/micro/server/copy/ManifestComparatorResource.java deleted file mode 100644 index 0e4f89a0a..000000000 --- a/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/aol/micro/server/copy/ManifestComparatorResource.java +++ /dev/null @@ -1,44 +0,0 @@ -package app.couchbase.manifest.comparator.com.aol.micro.server.copy; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import org.springframework.beans.factory.annotation.Autowired; - -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.couchbase.DistributedMapClient; -import com.aol.micro.server.couchbase.base.ManifestComparator; -import com.aol.micro.server.couchbase.base.VersionedKey; -import com.aol.micro.server.rest.jackson.JacksonUtil; - -@Path("/comparator") -@Rest -public class ManifestComparatorResource { - - - private volatile int count = 1; - private final ManifestComparator comparator; - @Autowired - public ManifestComparatorResource(ManifestComparator comparator) { - this.comparator = comparator.withKey("test-key"); - } - @GET - @Path("/increment") - public String bucket(){ - comparator.saveAndIncrement("hello"+(count++)); - return "increment"; - } - @GET - @Path("/get") - public String get(){ - comparator.load(); - return comparator.getData().toString(); - - } - @GET - @Path("/check") - public String check(){ - return ""+!comparator.isOutOfDate(); - - } -} diff --git a/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/aol/micro/server/copy/ManifestComparatorRunnerTest.java b/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/aol/micro/server/copy/ManifestComparatorRunnerTest.java deleted file mode 100644 index f4d27aa9c..000000000 --- a/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/aol/micro/server/copy/ManifestComparatorRunnerTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package app.couchbase.manifest.comparator.com.aol.micro.server.copy; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.couchbase.mock.CouchbaseMock; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(properties={"couchbaseServers","http://localhost:8091/pools", - "couchbasePassword","", - "couchbaseBucket","beer-sample"}) -public class ManifestComparatorRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer() { - try{ - //couchbase already running? - rest.get("http://localhost:8091/pools"); - }catch(Exception e){ - //start mock couchbase - CouchbaseMock.main(new String[]{"-S"}); - } - server = new MicroserverApp(ConfigurableModule.builder() - .context("simple-app").build()); - - server.start(); - - } - - @After - public void stopServer() { - server.stop(); - } - - @Test @Ignore - public void runAppAndBasicTest() throws InterruptedException, - ExecutionException { - rest.get("http://localhost:8080/simple-app/comparator/increment"); - - assertThat(rest.get("http://localhost:8080/simple-app/comparator/check"),equalTo("true")); - assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"),equalTo("hello1")); - rest.get("http://localhost:8080/simple-app/comparator/increment"); - assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"),equalTo("hello2")); - - rest.get("http://localhost:8080/simple-app/comparator2/increment"); - - assertThat(rest.get("http://localhost:8080/simple-app/comparator/check"),equalTo("false")); - assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"),equalTo("hellob")); - - - } - -} diff --git a/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/aol/micro/server/copy/SecondComparatorResource.java b/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/aol/micro/server/copy/SecondComparatorResource.java deleted file mode 100644 index 7b986834c..000000000 --- a/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/aol/micro/server/copy/SecondComparatorResource.java +++ /dev/null @@ -1,43 +0,0 @@ -package app.couchbase.manifest.comparator.com.aol.micro.server.copy; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import org.springframework.beans.factory.annotation.Autowired; - -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.couchbase.base.ManifestComparator; -import com.aol.micro.server.couchbase.base.VersionedKey; -import com.aol.micro.server.rest.jackson.JacksonUtil; - - -@Path("/comparator2") -@Rest -public class SecondComparatorResource { - - - private final ManifestComparator comparator; - @Autowired - public SecondComparatorResource(ManifestComparator comparator) { - this.comparator = comparator.withKey("test-key"); - } - @GET - @Path("/increment") - public String bucket(){ - comparator.saveAndIncrement("hellob"); - return "increment"; - } - @GET - @Path("/get") - public String get(){ - comparator.load(); - return comparator.getData().toString(); - - } - @GET - @Path("/check") - public String check(){ - return ""+!comparator.isOutOfDate(); - - } -} \ No newline at end of file diff --git a/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/oath/micro/server/second/ManifestComparatorResource.java b/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/oath/micro/server/second/ManifestComparatorResource.java new file mode 100644 index 000000000..f584b12bf --- /dev/null +++ b/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/oath/micro/server/second/ManifestComparatorResource.java @@ -0,0 +1,45 @@ +package app.couchbase.manifest.comparator.com.oath.micro.server.second; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.manifest.ManifestComparator; + +@Path("/comparator") +@Rest +public class ManifestComparatorResource { + + private volatile int count = 1; + private final ManifestComparator comparator; + + @Autowired + public ManifestComparatorResource(ManifestComparator comparator) { + this.comparator = comparator. withKey("test-key"); + } + + @GET + @Path("/increment") + public String bucket() { + comparator.saveAndIncrement("hello" + (count++)); + return "increment"; + } + + @GET + @Path("/get") + public String get() { + comparator.load(); + return comparator.getData() + .toString(); + + } + + @GET + @Path("/check") + public String check() { + return "" + !comparator.isOutOfDate(); + + } +} diff --git a/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/oath/micro/server/second/ManifestComparatorRunnerTest.java b/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/oath/micro/server/second/ManifestComparatorRunnerTest.java new file mode 100644 index 000000000..a3c46d493 --- /dev/null +++ b/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/oath/micro/server/second/ManifestComparatorRunnerTest.java @@ -0,0 +1,65 @@ +package app.couchbase.manifest.comparator.com.oath.micro.server.second; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.couchbase.mock.CouchbaseMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { "couchbaseServers", "http://localhost:8091/pools", "couchbasePassword", "", + "couchbaseBucket", "beer-sample" }) +public class ManifestComparatorRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + try { + // couchbase already running? + rest.get("http://localhost:8091/pools"); + } catch (Exception e) { + // start mock couchbase + CouchbaseMock.main(new String[] { "-S" }); + } + server = new MicroserverApp( + ConfigurableModule.builder() + .context("simple-app") + .build()); + + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + rest.get("http://localhost:8080/simple-app/comparator/increment"); + + assertThat(rest.get("http://localhost:8080/simple-app/comparator/check"), equalTo("true")); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"), equalTo("hello1")); + rest.get("http://localhost:8080/simple-app/comparator/increment"); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"), equalTo("hello2")); + + rest.get("http://localhost:8080/simple-app/comparator2/increment"); + + assertThat(rest.get("http://localhost:8080/simple-app/comparator/check"), equalTo("false")); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"), equalTo("hellob")); + + } + +} diff --git a/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/oath/micro/server/second/SecondComparatorResource.java b/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/oath/micro/server/second/SecondComparatorResource.java new file mode 100644 index 000000000..c69e7735b --- /dev/null +++ b/micro-couchbase/src/test/java/app/couchbase/manifest/comparator/com/oath/micro/server/second/SecondComparatorResource.java @@ -0,0 +1,44 @@ +package app.couchbase.manifest.comparator.com.oath.micro.server.second; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.manifest.ManifestComparator; + +@Path("/comparator2") +@Rest +public class SecondComparatorResource { + + private final ManifestComparator comparator; + + @Autowired + public SecondComparatorResource(ManifestComparator comparator) { + this.comparator = comparator.withKey("test-key"); + } + + @GET + @Path("/increment") + public String bucket() { + comparator.saveAndIncrement("hellob"); + return "increment"; + } + + @GET + @Path("/get") + public String get() { + comparator.load(); + return comparator.getData() + .toString(); + + } + + @GET + @Path("/check") + public String check() { + return "" + !comparator.isOutOfDate(); + + } +} \ No newline at end of file diff --git a/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/ConfigureCouchbaseTest.java b/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/ConfigureCouchbaseTest.java deleted file mode 100644 index 95486964e..000000000 --- a/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/ConfigureCouchbaseTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.aol.micro.server.couchbase; - -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.Optional; - -import org.junit.Before; -import org.junit.Test; - -public class ConfigureCouchbaseTest { - - ConfigureCouchbase config; - - @Before - public void setUp() throws Exception { - config = new ConfigureCouchbase(); - } - - @Test - public void createDistributedCacheMemcachedOff() throws IOException, URISyntaxException { - config.setCouchbaseClientEnabled(false); - DistributedMapClient cache = config.simpleCouchbaseClient(); - assertThat(cache.get("hello"), is(Optional.empty())); - - } - - @Test(expected = NullPointerException.class) - public void createDistributedCache() throws IOException, URISyntaxException { - memcachedOn(); - config.simpleCouchbaseClient(); - fail("Memcache should throw exception"); - - } - - private void memcachedOn() { - config.setCouchbaseClientEnabled(true); - config.setCouchbaseServers(null); - } - -} \ No newline at end of file diff --git a/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/MockEntity.java b/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/MockEntity.java deleted file mode 100644 index 7e1b42f32..000000000 --- a/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/MockEntity.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.aol.micro.server.couchbase; - -public class MockEntity { - -} diff --git a/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/SimpleCouchbaseClientTest.groovy b/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/SimpleCouchbaseClientTest.groovy deleted file mode 100644 index 5071aba2c..000000000 --- a/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/SimpleCouchbaseClientTest.groovy +++ /dev/null @@ -1,108 +0,0 @@ -package com.aol.micro.server.couchbase; - -import static org.junit.Assert.* -import net.spy.memcached.internal.OperationFuture - - -import com.couchbase.client.CouchbaseClient - -class SimpleCouchbaseClientTest extends spock.lang.Specification { - - - def "test get() when cache match"() { - - CouchbaseClient mockMemcachedClient = Mock() - String aKey = "1,2,3,4" - - def distributedCache = new DistributedMapClient(mockMemcachedClient) - def result - - when: - result = distributedCache.get(aKey) - - then: - 1 * mockMemcachedClient.get(aKey) >> Mock(MockEntity) - result.isPresent() - } - - def "test get() when cache miss"() { - - CouchbaseClient mockMemcachedClient = Mock() - String aKey = "1,2,3,4" - def distributedCache = new DistributedMapClient(mockMemcachedClient) - def isPresent - - when: - isPresent = distributedCache.get(aKey).isPresent() - - then: - 1 * mockMemcachedClient.get(_) - !isPresent - } - - def "test put with success"() { - CouchbaseClient mockMemcachedClient = Mock() - String aKey = "1,2,3,4" - def distributedCache = new DistributedMapClient(mockMemcachedClient) - def bitset = Mock(MockEntity) - def putResult - - when: - putResult = distributedCache.put(aKey, bitset) - - then: - 1 * mockMemcachedClient.set(aKey, _) >> mockSuccessfulCachePutResult() - putResult - } - - def "test retries when first put fails"() { - - CouchbaseClient mockMemcachedClient = Mock() - String aKey = "1,2,3,4" - def distributedCache = new DistributedMapClient(mockMemcachedClient) - def bitset = Mock(MockEntity) - def putResult - - when: - putResult = distributedCache.put(aKey, bitset) - - then: - 1 * mockMemcachedClient.set(aKey, _) >> mockSuccessfulCachePutResult() - putResult - } - - def "test when put fails"() { - - def maxRetries = 1 - CouchbaseClient mockMemcachedClient = Mock() - String aKey = "1,2,3,4" - def distributedCache = new DistributedMapClient(mockMemcachedClient) - def bitset = Mock(MockEntity) - def putResult - - when: - putResult = distributedCache.put(aKey, bitset) - - then: - maxRetries * mockMemcachedClient.set(aKey, _) >> mockUnsuccessfulCachePutResult() - !putResult - } - - - - private mockSuccessfulCachePutResult() { - def setResult = Mock(OperationFuture) - setResult.get() >> true - setResult - } - - private mockUnsuccessfulCachePutResult() { - def setResult = Mock(OperationFuture) - setResult.get() >> false - setResult - } - - - - -} diff --git a/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/base/ManifestComparatorKeyNotFoundExceptionTest.java b/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/base/ManifestComparatorKeyNotFoundExceptionTest.java deleted file mode 100644 index af16ed38f..000000000 --- a/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/base/ManifestComparatorKeyNotFoundExceptionTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.aol.micro.server.couchbase.base; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import org.junit.Test; - -import com.aol.micro.server.couchbase.base.ManifestComparatorKeyNotFoundException; - -public class ManifestComparatorKeyNotFoundExceptionTest { - - @Test - public void testConstructor() { - ManifestComparatorKeyNotFoundException exception = new ManifestComparatorKeyNotFoundException("hello"); - assertThat(exception.getMessage(), is("hello")); - } - -} diff --git a/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/base/ManifestComparatorTest.groovy b/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/base/ManifestComparatorTest.groovy deleted file mode 100644 index c5febb965..000000000 --- a/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/base/ManifestComparatorTest.groovy +++ /dev/null @@ -1,140 +0,0 @@ -package com.aol.micro.server.couchbase.base; - -import static org.junit.Assert.* -import static org.mockito.Mockito.* -import groovy.transform.CompileStatic - -import org.junit.Before -import org.junit.Test -import org.mockito.Mockito - -import com.aol.micro.server.couchbase.DistributedMapClient -import com.fasterxml.jackson.core.JsonParseException - - - -@CompileStatic -class ManifestComparatorTest { - - ManifestComparator manifestComparator - DistributedMapClient mock - String key = "key" - - @Before - public void setup(){ - mock = Mockito.mock(DistributedMapClient) - manifestComparator = new ManifestComparator(key,mock) - } - - @Test - public void newKeyScenario(){ - Mockito.when(mock.get(key)).thenReturn(Optional.empty()) - assert manifestComparator.isOutOfDate() - } - @Test - public void newKeySavesAsVersion1(){ - Mockito.when(mock.get(key)).thenReturn(Optional.empty()) - - VersionedKey version = new VersionedKey("key",1L) - - manifestComparator.saveAndIncrement("data") - Mockito.verify(mock,times(1)).put(eq(version.withVersion(1L).toJson()),any(Data)) - Mockito.verify(mock).put(key,version.withVersion(1L).toJson()) - assert manifestComparator.versionedKey == version.withVersion(1L).toJson() - } - - @Test - public void testIsOutofDateFalse() { - VersionedKey version = new VersionedKey("key",2L) - Mockito.when(mock.get(key)).thenReturn(Optional.of(version.toJson())) - assert manifestComparator.isOutOfDate() - } - - @Test - public void testIsOutofDateTrue() { - Mockito.when(mock.get(key)).thenReturn(Optional.of(manifestComparator.@versionedKey)) - assert !manifestComparator.isOutOfDate() - } - - @Test - public void testLoad() { - VersionedKey version = new VersionedKey("key",2L) - Mockito.when(mock.get(key)).thenReturn(Optional.of(version.toJson())) - Mockito.when(mock.get(version.toJson())).thenReturn(Optional.of(new Data(["hello"], new Date(),"hello"))) - manifestComparator.load() - List result = (List)manifestComparator.getData() - assert result.get(0) == "hello" - } - - @Test(expected=JsonParseException) - public void testChangeMidLoad() { - Mockito.when(mock.get(key)).thenReturn(Optional.of("v1")) - Mockito.when(mock.get("v1")).thenReturn(Optional.empty()) - manifestComparator.load() - List result =(List) manifestComparator.getData() - fail("should not reach here") - } - - - @Test - public void "when succesful save, version is incremented"(){ - VersionedKey version = new VersionedKey("key",1L) - Mockito.when(mock.get(key)).thenReturn(Optional.of(version.toJson())) - manifestComparator.saveAndIncrement("data") - Mockito.verify(mock,times(1)).put(eq(version.withVersion(2L).toJson()),any(Data)) - Mockito.verify(mock).put(key,version.withVersion(2L).toJson()) - assert manifestComparator.versionedKey == version.withVersion(2L).toJson() - } - @Test - public void "when succesful save, old version deleted"(){ - VersionedKey version = new VersionedKey("key",1L) - Mockito.when(mock.get(key)).thenReturn(Optional.of(version.toJson())) - manifestComparator.saveAndIncrement("data") - - Mockito.verify(mock).delete(version.toJson()) - } - @Test - public void "when unsuccesful save, version is same"(){ - VersionedKey version = new VersionedKey("key",1L) - Mockito.when(mock.get(key)).thenReturn(Optional.of(version.toJson())) - Mockito.when(mock.put(any(String),any(Object))).thenThrow(new RuntimeException("boo!")) - try{ - manifestComparator.saveAndIncrement("data") - }catch(Exception e){ - } - - assert manifestComparator.versionedKey == version.toJson() - } - @Test - public void "when unsuccesful save, old version not deleted"(){ - VersionedKey version = new VersionedKey("key",1l) - Mockito.when(mock.put(any(String),any(Object))).thenThrow(new RuntimeException("boo!")) - try{ - manifestComparator.saveAndIncrement("data") - }catch(Exception e){ - } - - Mockito.verify(mock,times(0)).delete(version.toJson()) - } - @Test - public void "when delete fails, version still incremented"(){ - VersionedKey version = new VersionedKey("key",1l) - Mockito.when(mock.get(key)).thenReturn(Optional.of(version.toJson())) - Mockito.when(mock.delete(any(String))).thenThrow(new RuntimeException("boo!")) - try{ - manifestComparator.saveAndIncrement("data") - }catch(Exception e){ - } - Mockito.verify(mock,times(1)).put(eq(version.withVersion(2l).toJson()),any(Data)) - Mockito.verify(mock).put(key,version.withVersion(2l).toJson()) - assert manifestComparator.versionedKey == version.withVersion(2l).toJson() - } - - @Test - public void "when clean, old versions deleted"(){ - VersionedKey version = new VersionedKey("key",100L) - Mockito.when(mock.get(key)).thenReturn(Optional.of(version.toJson())) - manifestComparator.cleanAll() - Mockito.verify(mock,times(100)).delete(any(String)) - } -} diff --git a/micro-couchbase/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-couchbase/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index 991ffed12..000000000 --- a/micro-couchbase/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.aol.micro.server.testing; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -public class RestAgent { - - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - - - -} diff --git a/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/ConfigureCouchbaseTest.java b/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/ConfigureCouchbaseTest.java new file mode 100644 index 000000000..b12d6d16f --- /dev/null +++ b/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/ConfigureCouchbaseTest.java @@ -0,0 +1,46 @@ +package com.oath.micro.server.couchbase; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.Optional; + +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.distributed.DistributedMap; + +public class ConfigureCouchbaseTest { + + ConfigureCouchbase config; + + @Before + public void setUp() throws Exception { + config = new ConfigureCouchbase(); + } + + @Test + public void createDistributedCacheMemcachedOff() throws IOException, URISyntaxException { + config.setCouchbaseClientEnabled(false); + DistributedMap cache = config.simpleCouchbaseClient(); + assertThat(cache.get("hello"), is(Optional.empty())); + + } + + @Test(expected = NullPointerException.class) + public void createDistributedCache() throws IOException, URISyntaxException { + memcachedOn(); + config.simpleCouchbaseClient(); + fail("Memcache should throw exception"); + + } + + private void memcachedOn() { + config.setCouchbaseClientEnabled(true); + config.setCouchbaseServers(null); + } + +} \ No newline at end of file diff --git a/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/MockEntity.java b/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/MockEntity.java new file mode 100644 index 000000000..238164228 --- /dev/null +++ b/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/MockEntity.java @@ -0,0 +1,5 @@ +package com.oath.micro.server.couchbase; + +public class MockEntity { + +} diff --git a/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/SimpleCouchbaseClientConnectionTest.groovy b/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/SimpleCouchbaseClientConnectionTest.groovy similarity index 76% rename from micro-couchbase/src/test/java/com/aol/micro/server/couchbase/SimpleCouchbaseClientConnectionTest.groovy rename to micro-couchbase/src/test/java/com/oath/micro/server/couchbase/SimpleCouchbaseClientConnectionTest.groovy index f1a364f23..0aaa75869 100644 --- a/micro-couchbase/src/test/java/com/aol/micro/server/couchbase/SimpleCouchbaseClientConnectionTest.groovy +++ b/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/SimpleCouchbaseClientConnectionTest.groovy @@ -1,4 +1,4 @@ -package com.aol.micro.server.couchbase; +package com.oath.micro.server.couchbase; import static org.hamcrest.Matchers.is import static org.junit.Assert.* @@ -8,17 +8,18 @@ import org.junit.Before import org.junit.Test import org.mockito.Mockito +import com.oath.micro.server.distributed.DistributedMap; import com.couchbase.client.CouchbaseClient class SimpleCouchbaseClientConnectionTest { CouchbaseClient client - DistributedMapClient con + DistributedMap con @Before public void setup() { client = Mockito.mock(CouchbaseClient) - con = new DistributedMapClient(client) + con = new CouchbaseDistributedMapClient(client) } @Test public void testDelete() { @@ -34,7 +35,7 @@ class SimpleCouchbaseClientConnectionTest { @Test public void testGetDistributedCacheDisabled() { - con = new DistributedMapClient(null) + con = new CouchbaseDistributedMapClient(null) Optional result = con.get("key") assertThat(result, is(Optional.empty())) } diff --git a/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/SimpleCouchbaseClientTest.groovy b/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/SimpleCouchbaseClientTest.groovy new file mode 100644 index 000000000..abd584458 --- /dev/null +++ b/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/SimpleCouchbaseClientTest.groovy @@ -0,0 +1 @@ +package com.oath.micro.server.couchbase; diff --git a/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/base/ManifestComparatorKeyNotFoundExceptionTest.java b/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/base/ManifestComparatorKeyNotFoundExceptionTest.java new file mode 100644 index 000000000..92a9b01fd --- /dev/null +++ b/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/base/ManifestComparatorKeyNotFoundExceptionTest.java @@ -0,0 +1,19 @@ +package com.oath.micro.server.couchbase.base; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.Test; + +import com.oath.micro.server.manifest.ManifestComparatorKeyNotFoundException; + +public class ManifestComparatorKeyNotFoundExceptionTest { + + @Test + public void testConstructor() { + ManifestComparatorKeyNotFoundException exception = new ManifestComparatorKeyNotFoundException( + "hello"); + assertThat(exception.getMessage(), is("hello")); + } + +} diff --git a/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/base/ManifestComparatorTest.groovy b/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/base/ManifestComparatorTest.groovy new file mode 100644 index 000000000..670b26b32 --- /dev/null +++ b/micro-couchbase/src/test/java/com/oath/micro/server/couchbase/base/ManifestComparatorTest.groovy @@ -0,0 +1 @@ +package com.oath.micro.server.couchbase.base; diff --git a/micro-couchbase/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-couchbase/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..7b82e1257 --- /dev/null +++ b/micro-couchbase/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,24 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +public class RestAgent { + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + +} diff --git a/micro-curator/README.md b/micro-curator/README.md new file mode 100644 index 000000000..c9b9e23f4 --- /dev/null +++ b/micro-curator/README.md @@ -0,0 +1,62 @@ +# Curator Plugin + +[micro-curator example apps](https://github.com/aol/micro-server/tree/master/micro-curator/src/test/java/app) + +This adds a facility to use curator locks. + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-curator/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-curator) + +Simply add to the classpath + +Maven +```xml + + com.oath.microservices + micro-curator + x.yz + +``` +Gradle +```groovy + compile 'com.oath.microservices:micro-curator:x.yz' +``` +## Example api for taking lock + + ```java +@Rest(isSingleton=true) +@Path("/status") +public class CuratorStatusResource { + + private final DistributedLockService service; + private final DistributedLockService service2; + + @Autowired + public CuratorStatusResource(CuratorDistributedLockServiceProvider provider) { + this.service = provider.getDistributedLock(1_000); + this.service2 = provider.getDistributedLock(1_000); + } + @GET + @Path("/lock") + public String lock() { + if(service.tryLock("hello2")) + return "got"; + return "not"; + + } + + @GET + @Path("/lock2") + public String lock2() { + if(service2.tryLock("hello2")) + return "got"; + return "not"; + + } + +} + ``` + +If you'll call one of method, it will be returning "got", if you'll switch to another it will be returning "not" since they are both aiming to the same lock. DistributedLockService object itself **is a** lock, fact that `service` hold the lock, doesn't grant `service2` in any thread to obtain lock with the same name and vice versa. Despite the fact they use same name, from viewpoint of curator they are different locks. +Plugin allow you to have multiple number of locks using single connection. diff --git a/micro-curator/build.gradle b/micro-curator/build.gradle index ee64d3b24..803f4b622 100644 --- a/micro-curator/build.gradle +++ b/micro-curator/build.gradle @@ -1,83 +1,84 @@ description = 'micro-curator' + sourceSets { - integTest { - java { - compileClasspath += main.output + test.output - runtimeClasspath += main.output + test.output - srcDir file('src/integration/java') - } - resources.srcDir file('src/integration/resources') + integTest { + java { + compileClasspath += main.output + test.output + runtimeClasspath += main.output + test.output + srcDir file('src/integration/java') } + resources.srcDir file('src/integration/resources') + } } task integTest(type: Test) { - testClassesDir = sourceSets.integTest.output.classesDir - classpath = sourceSets.integTest.runtimeClasspath + testClassesDirs = sourceSets.integTest.output.classesDirs + classpath = sourceSets.integTest.runtimeClasspath } check.dependsOn integTest integTest.dependsOn test dependencies { - compile 'org.apache.curator:curator-framework:' + curatorVersion - compile 'org.apache.curator:curator-recipes:' + curatorVersion - compile project(':micro-core') - - testCompile 'commons-io:commons-io:2.4' - testCompile project(':micro-grizzly-with-jersey') - integTestCompile sourceSets.main.output - integTestCompile sourceSets.test.output - - integTestCompile configurations.testCompile - integTestRuntime configurations.testRuntime + compile 'org.apache.curator:curator-framework:' + curatorVersion + compile 'org.apache.curator:curator-recipes:' + curatorVersion + compile project(':micro-dist-lock') + + testCompile 'commons-io:commons-io:' + commonsIOVersion + testCompile project(':micro-grizzly-with-jersey') + integTestCompile sourceSets.main.output + integTestCompile sourceSets.test.output + + integTestCompile configurations.testCompile + integTestRuntime configurations.testRuntime } modifyPom { - project { - name 'Microserver curator integration' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-curator' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'earlzero' - name 'Nikita Sapozhnikov' - email 'nikita.sapozhnikov@teamaol.com' - } - } - - } + project { + name 'Microserver curator integration' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-curator' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-curator/readme.md b/micro-curator/readme.md deleted file mode 100644 index 9481eab90..000000000 --- a/micro-curator/readme.md +++ /dev/null @@ -1,62 +0,0 @@ -# Curator Plugin - -[micro-curator example apps](https://github.com/aol/micro-server/tree/master/micro-curator/src/test/java/app) - -This adds a facility to use curator locks. - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-curator/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-curator) - -Simply add to the classpath - -Maven -```xml - - com.aol.microservices - micro-curator - x.yz - -``` -Gradle -```groovy - compile 'com.aol.microservices:micro-curator:x.yz' -``` -## Example api for taking lock - - ```java -@Rest(isSingleton=true) -@Path("/status") -public class CuratorStatusResource { - - private final DistributedLockService service; - private final DistributedLockService service2; - - @Autowired - public CuratorStatusResource(CuratorDistributedLockServiceProvider provider) { - this.service = provider.getDistributedLock(1_000); - this.service2 = provider.getDistributedLock(1_000); - } - @GET - @Path("/lock") - public String lock() { - if(service.tryLock("hello2")) - return "got"; - return "not"; - - } - - @GET - @Path("/lock2") - public String lock2() { - if(service2.tryLock("hello2")) - return "got"; - return "not"; - - } - -} - ``` - -If you'll call one of method, it will be returning "got", if you'll switch to another it will be returning "not" since they are both aiming to the same lock. DistributedLockService object itself **is a** lock, fact that `service` hold the lock, doesn't grant `service2` in any thread to obtain lock with the same name and vice versa. Despite the fact they use same name, from viewpoint of curator they are different locks. -Plugin allow you to have multiple number of locks using single connection. diff --git a/micro-curator/src/integration/java/com/aol/micro/server/curator/lock/IntegrationTest.java b/micro-curator/src/integration/java/com/aol/micro/server/curator/lock/IntegrationTest.java deleted file mode 100644 index 63c5fbb8d..000000000 --- a/micro-curator/src/integration/java/com/aol/micro/server/curator/lock/IntegrationTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.aol.micro.server.curator.lock; - -import java.io.IOException; -import java.util.Properties; -import java.util.UUID; - -import org.apache.zookeeper.server.ServerConfig; -import org.apache.zookeeper.server.ZooKeeperServerMain; -import org.apache.zookeeper.server.quorum.QuorumPeerConfig; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.utility.DistributedLockService; - -public class IntegrationTest { - - private CuratorDistributedLockServiceProvider provider; - - private ZooKeeperServerMain zooKeeperServer; - - @Before - public void initialize() { - - Properties startupProperties = new Properties(); - - startupProperties.put("dataDir", "/tmp/zookeeper"); - startupProperties.put("clientPort", "12181"); - - - QuorumPeerConfig quorumConfiguration = new QuorumPeerConfig(); - try { - quorumConfiguration.parseProperties(startupProperties); - } catch(Exception e) { - throw new RuntimeException(e); - } - - zooKeeperServer = new ZooKeeperServerMain(); - final ServerConfig configuration = new ServerConfig(); - configuration.readFrom(quorumConfiguration); - - new Thread() { - public void run() { - try { - zooKeeperServer.runFromConfig(configuration); - } catch (IOException e) { - e.printStackTrace(); - } - } - }.start(); - - - provider = new CuratorDistributedLockServiceProvider("localhost:12181", "1000", "1", "/test"); - } - - @Test - public void lock() { - final String lockName = UUID.randomUUID().toString(); - - DistributedLockService lock = provider.getDistributedLock(1000); - Assert.assertTrue(lock.tryLock(lockName)); - Assert.assertTrue(lock.tryLock(lockName)); - DistributedLockService lock2 = provider.getDistributedLock(1000); - Assert.assertFalse(lock2.tryLock(lockName)); - } - -} diff --git a/micro-curator/src/integration/java/com/oath/micro/server/curator/lock/IntegrationTest.java b/micro-curator/src/integration/java/com/oath/micro/server/curator/lock/IntegrationTest.java new file mode 100644 index 000000000..e2afd7b9a --- /dev/null +++ b/micro-curator/src/integration/java/com/oath/micro/server/curator/lock/IntegrationTest.java @@ -0,0 +1,71 @@ +package com.oath.micro.server.curator.lock; + +import java.io.IOException; +import java.util.Properties; +import java.util.UUID; + +import org.apache.zookeeper.server.ServerConfig; +import org.apache.zookeeper.server.ZooKeeperServerMain; +import org.apache.zookeeper.server.admin.AdminServer.AdminServerException; +import org.apache.zookeeper.server.quorum.QuorumPeerConfig; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.dist.lock.DistributedLockService; + +public class IntegrationTest { + + private CuratorDistributedLockServiceProvider provider; + + private ZooKeeperServerMain zooKeeperServer; + + @Before + public void initialize() { + + Properties startupProperties = new Properties(); + + startupProperties.put("dataDir", "/tmp/zookeeper"); + startupProperties.put("clientPort", "12181"); + + + QuorumPeerConfig quorumConfiguration = new QuorumPeerConfig(); + try { + quorumConfiguration.parseProperties(startupProperties); + } catch(Exception e) { + throw new RuntimeException(e); + } + + zooKeeperServer = new ZooKeeperServerMain(); + final ServerConfig configuration = new ServerConfig(); + configuration.readFrom(quorumConfiguration); + + new Thread(() -> { + try { + zooKeeperServer.runFromConfig(configuration); + } catch (IOException | AdminServerException e) { + e.printStackTrace(); + } + }).start(); + + try { + // allow zooKeeperServer enough time to initialize + Thread.sleep(1000); + } catch (InterruptedException e) { + } + + provider = new CuratorDistributedLockServiceProvider("localhost:12181", "1000", "1", "/test"); + } + + @Test + public void lock() { + final String lockName = UUID.randomUUID().toString(); + + DistributedLockService lock = provider.getDistributedLock(10000); + Assert.assertTrue(lock.tryLock(lockName)); + Assert.assertTrue(lock.tryLock(lockName)); + DistributedLockService lock2 = provider.getDistributedLock(10000); + Assert.assertFalse(lock2.tryLock(lockName)); + } + +} diff --git a/micro-curator/src/main/java/com/aol/micro/server/curator/CuratorPlugin.java b/micro-curator/src/main/java/com/aol/micro/server/curator/CuratorPlugin.java deleted file mode 100644 index e6bd0aa50..000000000 --- a/micro-curator/src/main/java/com/aol/micro/server/curator/CuratorPlugin.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.aol.micro.server.curator; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.curator.lock.CuratorDistributedLockServiceProvider; - -public class CuratorPlugin implements Plugin { - @Override - public PSetX springClasses() { - return PSetX.of(CuratorDistributedLockServiceProvider.class); - } -} diff --git a/micro-curator/src/main/java/com/aol/micro/server/curator/lock/DistributedLockServiceCuratorImpl.java b/micro-curator/src/main/java/com/aol/micro/server/curator/lock/DistributedLockServiceCuratorImpl.java deleted file mode 100644 index 2578f47ae..000000000 --- a/micro-curator/src/main/java/com/aol/micro/server/curator/lock/DistributedLockServiceCuratorImpl.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.aol.micro.server.curator.lock; - -import java.util.concurrent.TimeUnit; - -import lombok.AllArgsConstructor; -import lombok.experimental.Wither; - -import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.recipes.locks.InterProcessSemaphoreMutex; -import org.apache.curator.framework.state.ConnectionState; -import org.apache.curator.framework.state.ConnectionStateListener; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.aol.micro.server.utility.DistributedLockService; - -@Wither -@AllArgsConstructor -public class DistributedLockServiceCuratorImpl implements DistributedLockService, ConnectionStateListener { - - private volatile boolean acquired; - - private InterProcessSemaphoreMutex curatorLock; - - private String lockName; - - private final String basePath; - - private final CuratorFramework curatorFramework; - - private final int timeout; - - private static final Logger logger = LoggerFactory.getLogger(DistributedLockServiceCuratorImpl.class); - - public DistributedLockServiceCuratorImpl(CuratorFramework curatorFramework, String basePath, int timeout) throws Exception { - this.curatorFramework = curatorFramework; - this.basePath = basePath; - this.timeout = timeout; - createIfNotExists(basePath); - } - - private void createIfNotExists(String path) throws Exception { - if (curatorFramework.checkExists().forPath(path) == null) { - curatorFramework.create().creatingParentContainersIfNeeded().forPath(path, new byte[0]); - } - } - - @Override - public boolean tryLock(String key) { - if (curatorLock == null) { - lockName = key; - curatorLock = new InterProcessSemaphoreMutex(curatorFramework, String.join("/", basePath, key)); - acquired = acquire(); - return acquired; - } else if (lockName.equals(key)) { - acquired = acquire(); - return acquired; - } else { - throw new IllegalArgumentException( - String.format("Lock can't change the name old:%s, new:%s", lockName, key)); - } - } - - private boolean acquire() { - try { - return acquired ? acquired : curatorLock.acquire(timeout, TimeUnit.MILLISECONDS); - } catch (Exception e) { - return false; - } - } - - @Override - public boolean tryReleaseLock(String key) { - acquired = false; - try { - curatorLock.release(); - return true; - } catch (Exception e) { - logger.warn("Can't release lock", e); - return false; - } - } - - @Override - public void stateChanged(CuratorFramework client, ConnectionState newState) { - switch (newState) { - case LOST: - case SUSPENDED: - acquired = false; - break; - default: - } - } - -} diff --git a/micro-curator/src/main/java/com/oath/micro/server/curator/CuratorPlugin.java b/micro-curator/src/main/java/com/oath/micro/server/curator/CuratorPlugin.java new file mode 100644 index 000000000..fc86201f5 --- /dev/null +++ b/micro-curator/src/main/java/com/oath/micro/server/curator/CuratorPlugin.java @@ -0,0 +1,14 @@ +package com.oath.micro.server.curator; + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.curator.lock.CuratorDistributedLockServiceProvider; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +public class CuratorPlugin implements Plugin { + @Override + public Set springClasses() { + return SetX.of(CuratorDistributedLockServiceProvider.class); + } +} diff --git a/micro-curator/src/main/java/com/aol/micro/server/curator/lock/CuratorDistributedLockServiceProvider.java b/micro-curator/src/main/java/com/oath/micro/server/curator/lock/CuratorDistributedLockServiceProvider.java similarity index 81% rename from micro-curator/src/main/java/com/aol/micro/server/curator/lock/CuratorDistributedLockServiceProvider.java rename to micro-curator/src/main/java/com/oath/micro/server/curator/lock/CuratorDistributedLockServiceProvider.java index 5007d89ca..948a97429 100644 --- a/micro-curator/src/main/java/com/aol/micro/server/curator/lock/CuratorDistributedLockServiceProvider.java +++ b/micro-curator/src/main/java/com/oath/micro/server/curator/lock/CuratorDistributedLockServiceProvider.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.curator.lock; +package com.oath.micro.server.curator.lock; import org.apache.curator.RetryPolicy; import org.apache.curator.framework.CuratorFramework; @@ -8,7 +8,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import com.aol.micro.server.utility.DistributedLockService; +import com.oath.micro.server.dist.lock.DistributedLockService; @Component public class CuratorDistributedLockServiceProvider { @@ -34,7 +34,9 @@ public CuratorDistributedLockServiceProvider( */ public DistributedLockService getDistributedLock(int timeout) { try { - return new DistributedLockServiceCuratorImpl(curatorFramework, lockBasePath, timeout); + DistributedLockServiceCuratorImpl lock = new DistributedLockServiceCuratorImpl(curatorFramework, lockBasePath, timeout); + curatorFramework.getConnectionStateListenable().addListener(lock); + return lock; } catch (Exception e) { throw new RuntimeException(e); } diff --git a/micro-curator/src/main/java/com/oath/micro/server/curator/lock/DistributedLockServiceCuratorImpl.java b/micro-curator/src/main/java/com/oath/micro/server/curator/lock/DistributedLockServiceCuratorImpl.java new file mode 100644 index 000000000..46c97b0d1 --- /dev/null +++ b/micro-curator/src/main/java/com/oath/micro/server/curator/lock/DistributedLockServiceCuratorImpl.java @@ -0,0 +1,109 @@ +package com.oath.micro.server.curator.lock; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; + +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.recipes.locks.InterProcessMutex; +import org.apache.curator.framework.state.ConnectionState; +import org.apache.curator.framework.state.ConnectionStateListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.oath.micro.server.dist.lock.DistributedLockService; + +import lombok.AllArgsConstructor; +import lombok.experimental.Wither; + +/** + * DistributedLockService suitable for single threaded use only + * + */ +@Wither +@AllArgsConstructor +public class DistributedLockServiceCuratorImpl implements DistributedLockService, ConnectionStateListener { + + + + private final ConcurrentMap locks = new ConcurrentHashMap<>(); + + private final String basePath; + + private final CuratorFramework curatorFramework; + + private final int timeout; + + private static final Logger logger = LoggerFactory.getLogger(DistributedLockServiceCuratorImpl.class); + + public DistributedLockServiceCuratorImpl(CuratorFramework curatorFramework, String basePath, int timeout) + throws Exception { + this.curatorFramework = curatorFramework; + this.basePath = basePath; + this.timeout = timeout; + createIfNotExists(basePath); + } + + private void createIfNotExists(String path) throws Exception { + if (curatorFramework.checkExists().forPath(path) == null) { + curatorFramework.create().creatingParentContainersIfNeeded().forPath(path, new byte[0]); + } + } + + @Override + public boolean tryLock(String key) { + try { + InterProcessMutex mutex = locks.computeIfAbsent(key, + __ -> new InterProcessMutex(curatorFramework, String.join("/", basePath, key))); + + + boolean owned = mutex.isAcquiredInThisProcess(); + if(owned) { + return true; + } else { + mutex.acquire(timeout, TimeUnit.MILLISECONDS); + } + return mutex.isAcquiredInThisProcess(); + } catch (Exception e) { + return false; + } + } + + @Override + public boolean tryReleaseLock(String key) { + return Optional.ofNullable(locks.get(key)).map(c -> { + try { + c.release(); + return true; + } catch (Exception e) { + return false; + } + }).orElse(false); + } + + @Override + public void stateChanged(CuratorFramework client, ConnectionState newState) { + + switch (newState) { + case LOST: + case SUSPENDED: + + Collection oldLocks = new ArrayList<>(locks.values()); + locks.clear(); + + oldLocks.stream().parallel().forEach(lock -> { + try { + lock.release(); + } catch (Exception e) { + logger.trace("Can't release lock on " + newState); + } + }); + break; + default: + } + } + +} diff --git a/micro-curator/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-curator/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index f4f8779c1..000000000 --- a/micro-curator/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.curator.CuratorPlugin \ No newline at end of file diff --git a/micro-curator/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-curator/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..df740a31a --- /dev/null +++ b/micro-curator/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.curator.CuratorPlugin \ No newline at end of file diff --git a/micro-curator/src/test/java/app/prototype/com/aol/micro/server/CuratorStatusResource.java b/micro-curator/src/test/java/app/prototype/com/aol/micro/server/CuratorStatusResource.java index 516470d52..45d1eddf9 100644 --- a/micro-curator/src/test/java/app/prototype/com/aol/micro/server/CuratorStatusResource.java +++ b/micro-curator/src/test/java/app/prototype/com/aol/micro/server/CuratorStatusResource.java @@ -5,9 +5,9 @@ import org.springframework.beans.factory.annotation.Autowired; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.curator.lock.CuratorDistributedLockServiceProvider; -import com.aol.micro.server.utility.DistributedLockService; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.curator.lock.CuratorDistributedLockServiceProvider; +import com.oath.micro.server.dist.lock.DistributedLockService; @Rest @Path("/status") diff --git a/micro-curator/src/test/java/app/prototype/com/aol/micro/server/DummyLock.java b/micro-curator/src/test/java/app/prototype/com/aol/micro/server/DummyLock.java new file mode 100644 index 000000000..d457c0c65 --- /dev/null +++ b/micro-curator/src/test/java/app/prototype/com/aol/micro/server/DummyLock.java @@ -0,0 +1,20 @@ +package app.prototype.com.aol.micro.server; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.dist.lock.DistributedLockService; + +@Component +public class DummyLock implements DistributedLockService { + + @Override + public boolean tryLock(String key) { + return false; + } + + @Override + public boolean tryReleaseLock(String key) { + return false; + } + +} diff --git a/micro-curator/src/test/java/app/prototype/com/aol/micro/server/PrototypeLockCuratorRunnerTest.java b/micro-curator/src/test/java/app/prototype/com/aol/micro/server/PrototypeLockCuratorRunnerTest.java index 4abe2d2f7..a763a983c 100644 --- a/micro-curator/src/test/java/app/prototype/com/aol/micro/server/PrototypeLockCuratorRunnerTest.java +++ b/micro-curator/src/test/java/app/prototype/com/aol/micro/server/PrototypeLockCuratorRunnerTest.java @@ -6,7 +6,6 @@ import java.io.File; import java.io.IOException; -import java.util.Arrays; import java.util.concurrent.ExecutionException; import org.apache.commons.io.FileUtils; @@ -14,10 +13,9 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; @Microserver public class PrototypeLockCuratorRunnerTest { diff --git a/micro-curator/src/test/java/app/prototype/com/aol/micro/server/Zookeeper.java b/micro-curator/src/test/java/app/prototype/com/aol/micro/server/Zookeeper.java index 0150178a6..a41a44caa 100644 --- a/micro-curator/src/test/java/app/prototype/com/aol/micro/server/Zookeeper.java +++ b/micro-curator/src/test/java/app/prototype/com/aol/micro/server/Zookeeper.java @@ -7,6 +7,7 @@ import org.apache.zookeeper.server.ServerConfig; import org.apache.zookeeper.server.ZooKeeperServerMain; +import org.apache.zookeeper.server.admin.AdminServer.AdminServerException; import org.apache.zookeeper.server.quorum.QuorumPeerConfig; import org.springframework.stereotype.Component; @@ -41,7 +42,10 @@ public void run() { zooKeeperServer.runFromConfig(configuration); } catch (IOException e) { e.printStackTrace(); - } + } catch (AdminServerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } }.start(); diff --git a/micro-curator/src/test/java/app/singleton/com/aol/micro/server/copy/CuratorStatusResource.java b/micro-curator/src/test/java/app/singleton/com/oath/micro/server/copy/CuratorStatusResource.java similarity index 75% rename from micro-curator/src/test/java/app/singleton/com/aol/micro/server/copy/CuratorStatusResource.java rename to micro-curator/src/test/java/app/singleton/com/oath/micro/server/copy/CuratorStatusResource.java index 285eb8402..d8ae88e45 100644 --- a/micro-curator/src/test/java/app/singleton/com/aol/micro/server/copy/CuratorStatusResource.java +++ b/micro-curator/src/test/java/app/singleton/com/oath/micro/server/copy/CuratorStatusResource.java @@ -1,13 +1,13 @@ -package app.singleton.com.aol.micro.server.copy; +package app.singleton.com.oath.micro.server.copy; import javax.ws.rs.GET; import javax.ws.rs.Path; import org.springframework.beans.factory.annotation.Autowired; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.curator.lock.CuratorDistributedLockServiceProvider; -import com.aol.micro.server.utility.DistributedLockService; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.curator.lock.CuratorDistributedLockServiceProvider; +import com.oath.micro.server.dist.lock.DistributedLockService; @Rest(isSingleton=true) @Path("/status") diff --git a/micro-curator/src/test/java/app/singleton/com/oath/micro/server/copy/DummyLock.java b/micro-curator/src/test/java/app/singleton/com/oath/micro/server/copy/DummyLock.java new file mode 100644 index 000000000..851b8dcf9 --- /dev/null +++ b/micro-curator/src/test/java/app/singleton/com/oath/micro/server/copy/DummyLock.java @@ -0,0 +1,20 @@ +package app.singleton.com.oath.micro.server.copy; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.dist.lock.DistributedLockService; + +@Component +public class DummyLock implements DistributedLockService { + + @Override + public boolean tryLock(String key) { + return false; + } + + @Override + public boolean tryReleaseLock(String key) { + return false; + } + +} diff --git a/micro-curator/src/test/java/app/singleton/com/aol/micro/server/copy/KeepLockCuratorRunnerTest.java b/micro-curator/src/test/java/app/singleton/com/oath/micro/server/copy/KeepLockCuratorRunnerTest.java similarity index 84% rename from micro-curator/src/test/java/app/singleton/com/aol/micro/server/copy/KeepLockCuratorRunnerTest.java rename to micro-curator/src/test/java/app/singleton/com/oath/micro/server/copy/KeepLockCuratorRunnerTest.java index 44e76be3e..6d35732c1 100644 --- a/micro-curator/src/test/java/app/singleton/com/aol/micro/server/copy/KeepLockCuratorRunnerTest.java +++ b/micro-curator/src/test/java/app/singleton/com/oath/micro/server/copy/KeepLockCuratorRunnerTest.java @@ -1,4 +1,4 @@ -package app.singleton.com.aol.micro.server.copy; +package app.singleton.com.oath.micro.server.copy; import static org.hamcrest.CoreMatchers.is; @@ -13,9 +13,9 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; @Microserver public class KeepLockCuratorRunnerTest { diff --git a/micro-curator/src/test/java/app/singleton/com/aol/micro/server/copy/Zookeeper.java b/micro-curator/src/test/java/app/singleton/com/oath/micro/server/copy/Zookeeper.java similarity index 81% rename from micro-curator/src/test/java/app/singleton/com/aol/micro/server/copy/Zookeeper.java rename to micro-curator/src/test/java/app/singleton/com/oath/micro/server/copy/Zookeeper.java index 495e5dab0..8da99e7d0 100644 --- a/micro-curator/src/test/java/app/singleton/com/aol/micro/server/copy/Zookeeper.java +++ b/micro-curator/src/test/java/app/singleton/com/oath/micro/server/copy/Zookeeper.java @@ -1,14 +1,12 @@ -package app.singleton.com.aol.micro.server.copy; +package app.singleton.com.oath.micro.server.copy; import java.io.IOException; import java.util.Properties; -import javax.annotation.PostConstruct; - import org.apache.zookeeper.server.ServerConfig; import org.apache.zookeeper.server.ZooKeeperServerMain; +import org.apache.zookeeper.server.admin.AdminServer.AdminServerException; import org.apache.zookeeper.server.quorum.QuorumPeerConfig; -import org.springframework.stereotype.Component; public class Zookeeper { @@ -41,7 +39,10 @@ public void run() { zooKeeperServer.runFromConfig(configuration); } catch (IOException e) { e.printStackTrace(); - } + } catch (AdminServerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } }.start(); diff --git a/micro-curator/src/test/java/com/aol/micro/server/curator/lock/DistributedLockServiceCuratorImplTest.java b/micro-curator/src/test/java/com/aol/micro/server/curator/lock/DistributedLockServiceCuratorImplTest.java deleted file mode 100644 index bf06e028c..000000000 --- a/micro-curator/src/test/java/com/aol/micro/server/curator/lock/DistributedLockServiceCuratorImplTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.aol.micro.server.curator.lock; - -import static org.mockito.Matchers.*; -import static org.mockito.Mockito.*; -import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.api.CreateBuilder; -import org.apache.curator.framework.api.ExistsBuilder; -import org.apache.curator.framework.api.ProtectACLCreateModePathAndBytesable; -import org.apache.zookeeper.data.Stat; -import org.junit.Test; - -import com.aol.micro.server.curator.lock.DistributedLockServiceCuratorImpl; -import com.aol.micro.server.utility.DistributedLockService; - -public class DistributedLockServiceCuratorImplTest { - @Test - public void createNonExisting() throws Exception { - CuratorFramework client = mock(CuratorFramework.class); - ExistsBuilder builder = mock(ExistsBuilder.class); - CreateBuilder createBuilder = mock(CreateBuilder.class); - @SuppressWarnings("unchecked") - ProtectACLCreateModePathAndBytesable protector = mock(ProtectACLCreateModePathAndBytesable.class); - when(builder.forPath(anyString())).thenReturn(null); - when(client.checkExists()).thenReturn(builder); - when(client.create()).thenReturn(createBuilder); - when(createBuilder.creatingParentContainersIfNeeded()).thenReturn(protector); - new DistributedLockServiceCuratorImpl(client, "/", 0); - verify(protector).forPath(anyString(), anyObject()); - } - - @Test - public void createNonExisting2() throws Exception { - CuratorFramework client = mock(CuratorFramework.class); - ExistsBuilder builder = mock(ExistsBuilder.class); - CreateBuilder createBuilder = mock(CreateBuilder.class); - @SuppressWarnings("unchecked") - ProtectACLCreateModePathAndBytesable protector = mock(ProtectACLCreateModePathAndBytesable.class); - when(builder.forPath(anyString())).thenReturn(new Stat()); - when(client.checkExists()).thenReturn(builder); - when(client.create()).thenReturn(createBuilder); - when(createBuilder.creatingParentContainersIfNeeded()).thenReturn(protector); - new DistributedLockServiceCuratorImpl(client, "/", 0); - verify(protector, times(0)).forPath(anyString(), anyObject()); - } - - @Test(expected = IllegalArgumentException.class) - public void lock() throws Exception { - CuratorFramework client = mock(CuratorFramework.class); - ExistsBuilder builder = mock(ExistsBuilder.class); - CreateBuilder createBuilder = mock(CreateBuilder.class); - @SuppressWarnings("unchecked") - ProtectACLCreateModePathAndBytesable protector = mock(ProtectACLCreateModePathAndBytesable.class); - when(builder.forPath(anyString())).thenReturn(new Stat()); - when(client.checkExists()).thenReturn(builder); - when(client.create()).thenReturn(createBuilder); - when(createBuilder.creatingParentContainersIfNeeded()).thenReturn(protector); - DistributedLockService lock = new DistributedLockServiceCuratorImpl(client, "/", 0); - lock.tryLock("test"); - } -} diff --git a/micro-curator/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-curator/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-curator/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-curator/src/test/java/com/oath/micro/server/curator/lock/DistributedLockServiceCuratorImplTest.java b/micro-curator/src/test/java/com/oath/micro/server/curator/lock/DistributedLockServiceCuratorImplTest.java new file mode 100644 index 000000000..aace413f7 --- /dev/null +++ b/micro-curator/src/test/java/com/oath/micro/server/curator/lock/DistributedLockServiceCuratorImplTest.java @@ -0,0 +1,50 @@ +package com.oath.micro.server.curator.lock; + +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.api.CreateBuilder; +import org.apache.curator.framework.api.ExistsBuilder; +import org.apache.curator.framework.api.ProtectACLCreateModeStatPathAndBytesable; +import org.apache.zookeeper.data.Stat; +import org.junit.Test; + + +public class DistributedLockServiceCuratorImplTest { + @Test + public void createNonExisting() throws Exception { + CuratorFramework client = mock(CuratorFramework.class); + ExistsBuilder builder = mock(ExistsBuilder.class); + CreateBuilder createBuilder = mock(CreateBuilder.class); + + + ProtectACLCreateModeStatPathAndBytesable protector = mock(ProtectACLCreateModeStatPathAndBytesable.class); + when(builder.forPath(anyString())).thenReturn(null); + when(client.checkExists()).thenReturn(builder); + when(client.create()).thenReturn(createBuilder); + when(createBuilder.creatingParentContainersIfNeeded()).thenReturn((ProtectACLCreateModeStatPathAndBytesable)protector); + new DistributedLockServiceCuratorImpl(client, "/", 0); + verify(protector).forPath(anyString(), anyObject()); + } + + @Test + public void createNonExisting2() throws Exception { + CuratorFramework client = mock(CuratorFramework.class); + ExistsBuilder builder = mock(ExistsBuilder.class); + CreateBuilder createBuilder = mock(CreateBuilder.class); + + ProtectACLCreateModeStatPathAndBytesable protector = mock(ProtectACLCreateModeStatPathAndBytesable.class); + when(builder.forPath(anyString())).thenReturn(new Stat()); + when(client.checkExists()).thenReturn(builder); + when(client.create()).thenReturn(createBuilder); + when(createBuilder.creatingParentContainersIfNeeded()).thenReturn(protector); + new DistributedLockServiceCuratorImpl(client, "/", 0); + verify(protector, times(0)).forPath(anyString(), anyObject()); + } + +} diff --git a/micro-curator/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-curator/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-curator/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-dbcp/README.md b/micro-dbcp/README.md new file mode 100644 index 000000000..012c0afae --- /dev/null +++ b/micro-dbcp/README.md @@ -0,0 +1,59 @@ + # DBCP plugin + +[micro-dbcp example apps](https://github.com/aol/micro-server/tree/master/micro-dbcp/src/test/java/app) + +Creates a DataSource Spring Bean with name "mainDataSource". This will be based on [DBCP2](https://commons.apache.org/proper/commons-dbcp/). + +## To use + + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-dbcp/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-dbcp) + +Simply add to the classpath + +Maven + + + com.oath.microservices + micro-dbcp + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-dbcp:x.yz' + +# Configuring a data source + +A datasource can be configured by setting the following properties in application.properties, instance.properties or via the Microserver annotation + + db.connection.driver: (e.g. (org.hsqldb.jdbcDriver) + db.connection.url: (e.g. jdbc:hsqldb:mem:aname) + db.connection.username: (e.g. admin) + db.connection.password: (e.g. password) + db.connection.dialect: (e.g. org.hibernate.dialect.HSQLDialect) + db.connection.hibernate.showsql: (e.g. true | false) + db.connection.ddl.auto: (e.g. create-drop) + dbcp.db.test.on.borrow: (e.g. true | false) + dbcp.db.validation.query: (e.g. SELECT 1) + dbcp.db.max.total: (e.g. -1) + dbcp.db.min.evictable.idle.time: (e.g. 1800000) + dbcp.db.time.between.eviction.runs: (e.g. 1800000) + dbcp.db.num.tests.per.eviction.run: (e.g. 3) + dbcp.db.test.while.idle: (e.g. true | false) + dbcp.db.test.on.return: (e.g. true | false) + + +The Microserver annotation can also be used to set some default properties, or they can be set in an application.properties or instance.properties file ([see wiki for more details](https://github.com/aol/micro-server/wiki/Defining-Properties)). + + +The important properties for us to set are the datasource properties + + @Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", + "db.connection.url","jdbc:hsqldb:mem:aname", + "db.connection.username", "sa"}) + + public class MyMainClass { + + + } diff --git a/micro-dbcp/build.gradle b/micro-dbcp/build.gradle index 8bbd8c105..5c7369b8a 100644 --- a/micro-dbcp/build.gradle +++ b/micro-dbcp/build.gradle @@ -1,72 +1,71 @@ description = 'micro-dbcp' + dependencies { - - compile 'org.apache.commons:commons-dbcp2:'+dbcp2Version - compile project(':micro-core') - compile project(':micro-jdbc') - - testCompile project(':micro-client') - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') - testCompile group: 'org.hsqldb', name:'hsqldb', version:'2.0.0' + compile 'org.apache.commons:commons-dbcp2:' + dbcp2Version + compile project(':micro-core') + compile project(':micro-jdbc') + testCompile project(':micro-client') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') + testCompile group: 'org.hsqldb', name: 'hsqldb', version: '2.0.0' } modifyPom { - project { - name 'Microserver dbcp' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver dbcp' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-dbcp' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } - groupId 'com.aol.microservices' - artifactId 'micro-dbcp' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - developer { - id 'earlzero' - name 'Nikita Sapozhnikov' - email 'nikita.sapozhnikov@teamaol.com' - } - } - - } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-dbcp/readme.md b/micro-dbcp/readme.md deleted file mode 100644 index 5cc573ee5..000000000 --- a/micro-dbcp/readme.md +++ /dev/null @@ -1,59 +0,0 @@ - # DBCP plugin - -[micro-dbcp example apps](https://github.com/aol/micro-server/tree/master/micro-dbcp/src/test/java/app) - -Creates a DataSource Spring Bean with name "mainDataSource". This will be based on [DBCP2](https://commons.apache.org/proper/commons-dbcp/). - -## To use - - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-dbcp/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-dbcp) - -Simply add to the classpath - -Maven - - - com.aol.microservices - micro-dbcp - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-dbcp:x.yz' - -# Configuring a data source - -A datasource can be configured by setting the following properties in application.properties, instance.properties or via the Microserver annotation - - db.connection.driver: (e.g. (org.hsqldb.jdbcDriver) - db.connection.url: (e.g. jdbc:hsqldb:mem:aname) - db.connection.username: (e.g. admin) - db.connection.password: (e.g. password) - db.connection.dialect: (e.g. org.hibernate.dialect.HSQLDialect) - db.connection.hibernate.showsql: (e.g. true | false) - db.connection.ddl.auto: (e.g. create-drop) - dbcp.db.test.on.borrow: (e.g. true | false) - dbcp.db.validation.query: (e.g. SELECT 1) - dbcp.db.max.total: (e.g. -1) - dbcp.db.min.evictable.idle.time: (e.g. 1800000) - dbcp.db.time.between.eviction.runs: (e.g. 1800000) - dbcp.db.num.tests.per.eviction.run: (e.g. 3) - dbcp.db.test.while.idle: (e.g. true | false) - dbcp.db.test.on.return: (e.g. true | false) - - -The Microserver annotation can also be used to set some default properties, or they can be set in an application.properties or instance.properties file ([see wiki for more details](https://github.com/aol/micro-server/wiki/Defining-Properties)). - - -The important properties for us to set are the datasource properties - - @Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", - "db.connection.url","jdbc:hsqldb:mem:aname", - "db.connection.username", "sa"}) - - public class MyMainClass { - - - } diff --git a/micro-dbcp/src/main/java/com/aol/micro/server/spring/DBCPPlugin.java b/micro-dbcp/src/main/java/com/aol/micro/server/spring/DBCPPlugin.java deleted file mode 100644 index 299eb04be..000000000 --- a/micro-dbcp/src/main/java/com/aol/micro/server/spring/DBCPPlugin.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.aol.micro.server.spring; - -import java.util.Set; -import java.util.function.Function; - -import javax.servlet.ServletContextListener; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.spring.datasource.DBCPConfig; -import com.aol.micro.server.spring.datasource.DBCPDataSourceBuilder; - -/** - * - * @author kewang - * - */ -public class DBCPPlugin implements Plugin { - - @Override - public PSetX springClasses() { - return PSetX.of(DBCPConfig.class, DBCPDataSourceBuilder.class); - } - - - -} diff --git a/micro-dbcp/src/main/java/com/oath/micro/server/spring/DBCPPlugin.java b/micro-dbcp/src/main/java/com/oath/micro/server/spring/DBCPPlugin.java new file mode 100644 index 000000000..d48ce56d1 --- /dev/null +++ b/micro-dbcp/src/main/java/com/oath/micro/server/spring/DBCPPlugin.java @@ -0,0 +1,25 @@ +package com.oath.micro.server.spring; + +import java.util.Set; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.spring.datasource.DBCPConfig; +import com.oath.micro.server.spring.datasource.DBCPDataSourceBuilder; +import cyclops.reactive.collections.mutable.SetX; + +/** + * + * @author kewang + * + */ +public class DBCPPlugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of(DBCPConfig.class, DBCPDataSourceBuilder.class); + } + + + +} diff --git a/micro-dbcp/src/main/java/com/aol/micro/server/spring/datasource/DBCPConfig.java b/micro-dbcp/src/main/java/com/oath/micro/server/spring/datasource/DBCPConfig.java similarity index 94% rename from micro-dbcp/src/main/java/com/aol/micro/server/spring/datasource/DBCPConfig.java rename to micro-dbcp/src/main/java/com/oath/micro/server/spring/datasource/DBCPConfig.java index 7a11d5429..363a8e781 100644 --- a/micro-dbcp/src/main/java/com/aol/micro/server/spring/datasource/DBCPConfig.java +++ b/micro-dbcp/src/main/java/com/oath/micro/server/spring/datasource/DBCPConfig.java @@ -1,7 +1,7 @@ -package com.aol.micro.server.spring.datasource; +package com.oath.micro.server.spring.datasource; import lombok.Getter; -import lombok.experimental.Builder; +import lombok.Builder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; diff --git a/micro-dbcp/src/main/java/com/aol/micro/server/spring/datasource/DBCPDataSourceBuilder.java b/micro-dbcp/src/main/java/com/oath/micro/server/spring/datasource/DBCPDataSourceBuilder.java similarity index 94% rename from micro-dbcp/src/main/java/com/aol/micro/server/spring/datasource/DBCPDataSourceBuilder.java rename to micro-dbcp/src/main/java/com/oath/micro/server/spring/datasource/DBCPDataSourceBuilder.java index d108464bd..be6081857 100644 --- a/micro-dbcp/src/main/java/com/aol/micro/server/spring/datasource/DBCPDataSourceBuilder.java +++ b/micro-dbcp/src/main/java/com/oath/micro/server/spring/datasource/DBCPDataSourceBuilder.java @@ -1,11 +1,11 @@ -package com.aol.micro.server.spring.datasource; +package com.oath.micro.server.spring.datasource; import javax.annotation.Resource; import javax.sql.DataSource; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; -import lombok.experimental.Builder; +import lombok.Builder; import org.apache.commons.dbcp2.BasicDataSource; import org.springframework.context.annotation.Bean; @@ -16,7 +16,7 @@ @NoArgsConstructor @AllArgsConstructor public class DBCPDataSourceBuilder { - + @Resource(name = "mainEnv") private JdbcConfig mainEnv; @@ -35,12 +35,12 @@ private DataSource getDataSource() { ds.setUrl(mainEnv.getUrl()); ds.setUsername(mainEnv.getUsername()); ds.setPassword(mainEnv.getPassword()); - + retrySetup(ds); return ds; } - + private void retrySetup(BasicDataSource ds) { if (!"org.hibernate.dialect.HSQLDialect".equals(mainEnv.getDialect())) { ds.setTestOnBorrow(dbcpEnv.isTestOnBorrow()); diff --git a/micro-dbcp/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-dbcp/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index d27aedb74..000000000 --- a/micro-dbcp/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.spring.DBCPPlugin \ No newline at end of file diff --git a/micro-dbcp/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-dbcp/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..ed9a6a54a --- /dev/null +++ b/micro-dbcp/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.spring.DBCPPlugin \ No newline at end of file diff --git a/micro-dbcp/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcEntity.java b/micro-dbcp/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcEntity.java deleted file mode 100644 index 5fd88b137..000000000 --- a/micro-dbcp/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcEntity.java +++ /dev/null @@ -1,27 +0,0 @@ -package app.pure.jdbc.com.aol.micro.server; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.experimental.Builder; - - - - -@Setter -@Getter -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class JdbcEntity implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - - private Long id; - private String name; - private String value; - private int version; - - -} diff --git a/micro-dbcp/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcRunnerTest.java b/micro-dbcp/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcRunnerTest.java deleted file mode 100644 index 4bbe1dda9..000000000 --- a/micro-dbcp/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcRunnerTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package app.pure.jdbc.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(properties = { "db.connection.driver", "org.hsqldb.jdbcDriver", "db.connection.url", "jdbc:hsqldb:mem:aname", "db.connection.username", - "sa", "db.connection.dialect", "org.hibernate.dialect.HSQLDialect" }) -public class JdbcRunnerTest { - - private final AsyncRestClient listClient = new AsyncRestClient(1000, 1000).withResponse(JdbcEntity.class); - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer() { - - server = new MicroserverApp(() -> "jdbc-app"); - server.start(); - rest.get("http://localhost:8080/jdbc-app/persistence/gen"); - - } - - @After - public void stopServer() { - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException { - - assertThat(rest.get("http://localhost:8080/jdbc-app/persistence/create"), is("ok")); - assertThat(listClient.get("http://localhost:8080/jdbc-app/persistence/get").get(), is(JdbcEntity.class)); - - } - -} diff --git a/micro-dbcp/src/test/java/app/pure/jdbc/com/aol/micro/server/PersistentResource.java b/micro-dbcp/src/test/java/app/pure/jdbc/com/aol/micro/server/PersistentResource.java deleted file mode 100644 index b826e9cd5..000000000 --- a/micro-dbcp/src/test/java/app/pure/jdbc/com/aol/micro/server/PersistentResource.java +++ /dev/null @@ -1,48 +0,0 @@ -package app.pure.jdbc.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.BeanPropertyRowMapper; - -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.spring.datasource.jdbc.SQL; - -@Rest -@Path("/persistence") -public class PersistentResource { - - private final SQL dao; - - @Autowired - public PersistentResource(SQL dao) { - - this.dao = dao; - } - @GET - @Produces("text/plain") - @Path("/gen") - public String gen() { - dao.getJdbc().execute("create table t_jdbc(id bigint,name varchar(255),value varchar(255),version int);"); - - return "ok"; - } - @GET - @Produces("text/plain") - @Path("/create") - public String createEntity() { - dao.getJdbc().update("insert into t_jdbc VALUES (1,'hello','world',1)"); - - return "ok"; - } - - @GET - @Produces("application/json") - @Path("/get") - public JdbcEntity get() { - return dao.getJdbc(). queryForObject("select * from t_jdbc", new BeanPropertyRowMapper(JdbcEntity.class)); - } - -} \ No newline at end of file diff --git a/micro-dbcp/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcEntity.java b/micro-dbcp/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcEntity.java new file mode 100644 index 000000000..c92fd662b --- /dev/null +++ b/micro-dbcp/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcEntity.java @@ -0,0 +1,27 @@ +package app.pure.jdbc.com.oath.micro.server; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.Builder; + + + + +@Setter +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class JdbcEntity implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + private String name; + private String value; + private int version; + + +} diff --git a/micro-dbcp/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcRunnerTest.java b/micro-dbcp/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcRunnerTest.java new file mode 100644 index 000000000..f677ac354 --- /dev/null +++ b/micro-dbcp/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcRunnerTest.java @@ -0,0 +1,49 @@ +package app.pure.jdbc.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { "db.connection.driver", "org.hsqldb.jdbcDriver", "db.connection.url", "jdbc:hsqldb:mem:aname", "db.connection.username", + "sa", "db.connection.dialect", "org.hibernate.dialect.HSQLDialect" }) +public class JdbcRunnerTest { + + private final AsyncRestClient listClient = new AsyncRestClient(1000, 1000).withResponse(JdbcEntity.class); + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + + server = new MicroserverApp(() -> "jdbc-app"); + server.start(); + rest.get("http://localhost:8080/jdbc-app/persistence/gen"); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + assertThat(rest.get("http://localhost:8080/jdbc-app/persistence/create"), is("ok")); + assertThat(listClient.get("http://localhost:8080/jdbc-app/persistence/get").get(), is(JdbcEntity.class)); + + } + +} diff --git a/micro-dbcp/src/test/java/app/pure/jdbc/com/oath/micro/server/PersistentResource.java b/micro-dbcp/src/test/java/app/pure/jdbc/com/oath/micro/server/PersistentResource.java new file mode 100644 index 000000000..869898590 --- /dev/null +++ b/micro-dbcp/src/test/java/app/pure/jdbc/com/oath/micro/server/PersistentResource.java @@ -0,0 +1,48 @@ +package app.pure.jdbc.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.BeanPropertyRowMapper; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.spring.datasource.jdbc.SQL; + +@Rest +@Path("/persistence") +public class PersistentResource { + + private final SQL dao; + + @Autowired + public PersistentResource(SQL dao) { + + this.dao = dao; + } + @GET + @Produces("text/plain") + @Path("/gen") + public String gen() { + dao.getJdbc().execute("create table t_jdbc(id bigint,name varchar(255),value varchar(255),version int);"); + + return "ok"; + } + @GET + @Produces("text/plain") + @Path("/create") + public String createEntity() { + dao.getJdbc().update("insert into t_jdbc VALUES (1,'hello','world',1)"); + + return "ok"; + } + + @GET + @Produces("application/json") + @Path("/get") + public JdbcEntity get() { + return dao.getJdbc(). queryForObject("select * from t_jdbc", new BeanPropertyRowMapper(JdbcEntity.class)); + } + +} \ No newline at end of file diff --git a/micro-dbcp/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-dbcp/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-dbcp/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-dbcp/src/test/java/com/aol/micro/server/DBCPConfigTest.java b/micro-dbcp/src/test/java/com/oath/micro/server/DBCPConfigTest.java similarity index 90% rename from micro-dbcp/src/test/java/com/aol/micro/server/DBCPConfigTest.java rename to micro-dbcp/src/test/java/com/oath/micro/server/DBCPConfigTest.java index 439846bd8..cb7a4abc3 100644 --- a/micro-dbcp/src/test/java/com/aol/micro/server/DBCPConfigTest.java +++ b/micro-dbcp/src/test/java/com/oath/micro/server/DBCPConfigTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server; +package com.oath.micro.server; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; @@ -7,7 +7,7 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.spring.datasource.DBCPConfig; +import com.oath.micro.server.spring.datasource.DBCPConfig; public class DBCPConfigTest { diff --git a/micro-dbcp/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-dbcp/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-dbcp/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-dist-lock/README.md b/micro-dist-lock/README.md new file mode 100644 index 000000000..466df7749 --- /dev/null +++ b/micro-dist-lock/README.md @@ -0,0 +1,55 @@ +# Distributed lock plugin + +[micro-dist-lock example apps](https://github.com/aol/micro-server/tree/master/micro-dist-lock/src/test/java/app) + +This plugin provides some common code for distributed lock. + +## DistributedLockManager + +DistributedLockManager provides a way to bundle a DistributedLock Service and the lock together, it can be instantiated directly + +```java + DistributedLockService distributedLockService; + DistributedLockManager manager = new DistributedLockManager("key",distributedLockService); + + manager.isMainProcess(); +``` + +You can create your own Spring Beans via Spring Configuration class +```java + @Configuration + public class MyConfig{ + + @Autowired + DistributedLockService distributedLockService; + + @Bean + public DistributedLockManager manager(){ + return new DistributedLockManager("key",distributedLockService); + } + + } +``` + + + +This plugin is abstract and to take effect needs to be used in conjunction with a concrete distributed lock plugin i.e. micro-mysql plugin. + +This plugin also provides a rest end point which can be used to check if a process owns a lock for a given lockName or lockKey. + +## Getting The Microserver Distributed Lock Plugin + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-dist-lock/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-dist-lock) + +### Maven +```xml + + com.oath.microservices + micro-dist-lock + x.yz + +``` +### Gradle +```groovy + compile 'com.oath.microservices:micro-dist-lock:x.yz' +``` diff --git a/micro-dist-lock/build.gradle b/micro-dist-lock/build.gradle new file mode 100644 index 000000000..3422443db --- /dev/null +++ b/micro-dist-lock/build.gradle @@ -0,0 +1,68 @@ +description = 'micro-dist-lock' + +dependencies { + compile project(':micro-core') + testCompile project(':micro-client') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') +} + +modifyPom { + project { + name 'Microserver distributed lock' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-dist-lock' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } + + } +} + +extraArchive { + sources = true + tests = true + javadoc = true +} + +nexus { + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' +} + diff --git a/micro-dist-lock/src/main/java/com/oath/micro/server/dist/lock/DistLockPlugin.java b/micro-dist-lock/src/main/java/com/oath/micro/server/dist/lock/DistLockPlugin.java new file mode 100644 index 000000000..4ca2de699 --- /dev/null +++ b/micro-dist-lock/src/main/java/com/oath/micro/server/dist/lock/DistLockPlugin.java @@ -0,0 +1,20 @@ +package com.oath.micro.server.dist.lock; + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.dist.lock.rest.DistLockResource; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +/** + * + * @author Ke Wang + * + */ +public class DistLockPlugin implements Plugin { + @Override + public Set springClasses() { + return SetX.of(DistLockResource.class); + } + +} diff --git a/micro-dist-lock/src/main/java/com/oath/micro/server/dist/lock/DistributedLockManager.java b/micro-dist-lock/src/main/java/com/oath/micro/server/dist/lock/DistributedLockManager.java new file mode 100644 index 000000000..6a61f4566 --- /dev/null +++ b/micro-dist-lock/src/main/java/com/oath/micro/server/dist/lock/DistributedLockManager.java @@ -0,0 +1,20 @@ +package com.oath.micro.server.dist.lock; + +import lombok.Getter; + +public class DistributedLockManager { + + private final DistributedLockService distributedLockService; + @Getter + private final String key; + + public DistributedLockManager(DistributedLockService distributedLockService, String lockKey) { + this.distributedLockService = distributedLockService; + this.key = lockKey; + } + + public boolean isMainProcess() { + return distributedLockService.tryLock(key); + } + +} diff --git a/micro-dist-lock/src/main/java/com/oath/micro/server/dist/lock/DistributedLockService.java b/micro-dist-lock/src/main/java/com/oath/micro/server/dist/lock/DistributedLockService.java new file mode 100644 index 000000000..2b31270eb --- /dev/null +++ b/micro-dist-lock/src/main/java/com/oath/micro/server/dist/lock/DistributedLockService.java @@ -0,0 +1,11 @@ + +package com.oath.micro.server.dist.lock; + + +public interface DistributedLockService { + + boolean tryLock(String key); + + boolean tryReleaseLock(String key); + +} diff --git a/micro-dist-lock/src/main/java/com/oath/micro/server/dist/lock/rest/DistLockResource.java b/micro-dist-lock/src/main/java/com/oath/micro/server/dist/lock/rest/DistLockResource.java new file mode 100644 index 000000000..1cee815e2 --- /dev/null +++ b/micro-dist-lock/src/main/java/com/oath/micro/server/dist/lock/rest/DistLockResource.java @@ -0,0 +1,46 @@ +package com.oath.micro.server.dist.lock.rest; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import cyclops.reactive.collections.mutable.ListX; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.SingletonRestResource; +import com.oath.micro.server.dist.lock.DistributedLockManager; + +@Component +@Path("/lock-owner") +public class DistLockResource implements SingletonRestResource { + + private final Map lockController; + + @Autowired(required = false) + public DistLockResource(List lockController) { + this.lockController = ListX.fromIterable(lockController) + .toMap(lc -> lc.getKey(), lc -> lc); + } + + public DistLockResource() { + lockController = new HashMap<>(); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{lockName}") + public boolean ownLock(@PathParam("lockName") final String lockName) { + if (!lockController.containsKey(lockName)) + return false; + return lockController.get(lockName) + .isMainProcess(); + } + +} diff --git a/micro-dist-lock/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-dist-lock/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..42e5b06c3 --- /dev/null +++ b/micro-dist-lock/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.dist.lock.DistLockPlugin \ No newline at end of file diff --git a/micro-dist-lock/src/test/java/app/com/oath/micro/server/dist/lock/rest/ConfigureDistLock.java b/micro-dist-lock/src/test/java/app/com/oath/micro/server/dist/lock/rest/ConfigureDistLock.java new file mode 100644 index 000000000..88aed2da8 --- /dev/null +++ b/micro-dist-lock/src/test/java/app/com/oath/micro/server/dist/lock/rest/ConfigureDistLock.java @@ -0,0 +1,21 @@ +package app.com.oath.micro.server.dist.lock.rest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.dist.lock.DistributedLockManager; +import com.oath.micro.server.dist.lock.DistributedLockService; + +@Configuration +public class ConfigureDistLock { + + @Autowired + private DistributedLockService distributedLockService; + + @Bean + public DistributedLockManager manager() { + return new DistributedLockManager( + distributedLockService, "dummy-key"); + } +} diff --git a/micro-dist-lock/src/test/java/app/com/oath/micro/server/dist/lock/rest/DistLockRunnerTest.java b/micro-dist-lock/src/test/java/app/com/oath/micro/server/dist/lock/rest/DistLockRunnerTest.java new file mode 100644 index 000000000..6352f513a --- /dev/null +++ b/micro-dist-lock/src/test/java/app/com/oath/micro/server/dist/lock/rest/DistLockRunnerTest.java @@ -0,0 +1,38 @@ +package app.com.oath.micro.server.dist.lock.rest; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class DistLockRunnerTest { + + RestAgent rest = new RestAgent(); + MicroserverApp server; + + @Before + public void startServer() { + server = new MicroserverApp( + () -> "test-app"); + server.start(); + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void testOwnLock() { + assertThat(rest.getJson("http://localhost:8080/test-app/lock-owner/dummy-key"), is("true")); + assertThat(rest.getJson("http://localhost:8080/test-app/lock-owner/dummyKeyProvider2"), is("false")); + + } +} diff --git a/micro-dist-lock/src/test/java/app/com/oath/micro/server/dist/lock/rest/DummyLock.java b/micro-dist-lock/src/test/java/app/com/oath/micro/server/dist/lock/rest/DummyLock.java new file mode 100644 index 000000000..f70766227 --- /dev/null +++ b/micro-dist-lock/src/test/java/app/com/oath/micro/server/dist/lock/rest/DummyLock.java @@ -0,0 +1,23 @@ +package app.com.oath.micro.server.dist.lock.rest; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.dist.lock.DistributedLockService; + +@Component +public class DummyLock implements DistributedLockService { + + @Override + public boolean tryLock(String key) { + if (key.equals("dummy-key")) { + return true; + } + return false; + } + + @Override + public boolean tryReleaseLock(String key) { + return false; + } + +} diff --git a/micro-dist-lock/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-dist-lock/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-dist-lock/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-error-codes/README.md b/micro-error-codes/README.md new file mode 100644 index 000000000..0cbf1532f --- /dev/null +++ b/micro-error-codes/README.md @@ -0,0 +1,119 @@ +# micro-error-codes Plugin + +A plugin for standardized error handling and health checking across your Microservices + +[micro-error-codes example apps](https://github.com/aol/micro-server/tree/master/micro-error-codes/src/test/java/app) + +This plugin provides a core ErrorCode class for representing errors, and provides an Abstract BaseException (along with an implementation InvalidStateException). class that ensures error codes are attached to Exceptions. + +All Errors created under this system are published to an EventBus (a Guava EventBus). The micro-error-codes health checker subscribes to this event bus to determine system help. Users can attach other listeners also. + +A set of Rest end points is provided to + +1. Check system health (Untested, Ok, Errors, Fatal) +2. Show recoverable and fatal errors +3. Set max number of showable errors + +## Properties + +Time to return the system from Error state to Ok after the last generally recoverable error (Default is 360000 millis - which is 1 hour) + +health.check.time.threshold.from.error.to.normal=360000 + +Number of errors to show in show errors Rest end point (default is 25) + +health.check.error.list.size=25 + +As this is configurable via the Rest end point, users can also set a hard maximum beyond which Rest configuration can not increase the number of retained errors (default is 2500) + +health.check.max.error.list.size=2500 + +Users can switch off the facility to make recent errors and fatal errors available over Rest + +health.check.show.errors=true + +## Rest End points + +### Health status + +GET : text/plain +://system-errors/status + +Returns one of Untested, Ok, Errors, Fatal + + +### System errors + +GET : application/json +://system-errors/errors + +Returns a view into the most recent recoverable and fatal errors + +### Set max number of errors to show + +POST : application/json +://system-errors/max-errors/{maxErrors} + +Note this can not go past the hard maximum configurable by property + +### Get max number of errors to show + +GET : application/json +://system-errors/max-errors + + +# Defining ErrorCodes + +Create a class or interface per service to hold your error code constants. + +```java + +public interface Errors { + public final static ErrorCode QUERY_FAILURE = ErrorCode.error(1, "User {0} missing", Severity.CRITICAL); + public final static ErrorCode SYSTEM_FAILURE = ErrorCode.error(2, "data {0} mismatch, corruption likely", Severity.FATAL); +} + +``` + +Error Codes have three components + +1. An Error Code Id (should be unique per Microservice or even across your system) +2. A text description of what happened, parameters can be provided using {0} {1} {2} etc. placeholders +3. A severity level, Errors at Fatal severity level are treated and stored separately. The system is regarded as unrecoverable at Fatal level. + +# Using error codes + +Simply throw and InvalidStateException passing the ErrorCode (formated to include any parameters) + +```java + +throw new InvalidStateException(Errors.QUERY_FAILURE.format(userId)); + +``` + +and optionally include an Exception if handling a caught Exception +```java + +try{ + +}catch(Exception e){ + throw new InvalidStateException(Errors.SYSTEM_FAILURE.format(systemRecord),e); +} +``` + +## Getting The Microserver Error Codes + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-error-codes/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-error-codes) + +### Maven +```xml + + com.oath.microservices + micro-error-codes + x.yz + +``` +### Gradle +```groovy + compile 'com.oath.microservices:micro-error-codes:x.yz' + ``` diff --git a/micro-error-codes/build.gradle b/micro-error-codes/build.gradle new file mode 100644 index 000000000..6cebdbe83 --- /dev/null +++ b/micro-error-codes/build.gradle @@ -0,0 +1,67 @@ +description = 'micro-error-codes' + +dependencies { + compile project(':micro-events') + testCompile project(':micro-grizzly-with-jersey') + testCompile project(':micro-application-register') +} + +modifyPom { + project { + name 'Microserver error handling' + description 'Plugin for handling errors in a standardized way' + url 'https://github.com/aol/micro-server' + inceptionYear '2016' + + groupId 'com.oath.microservices' + artifactId 'micro-error-codes' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } + + } +} + +extraArchive { + sources = true + tests = true + javadoc = true +} + +nexus { + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' +} + diff --git a/micro-error-codes/src/main/java/com/oath/micro/server/errors/BaseException.java b/micro-error-codes/src/main/java/com/oath/micro/server/errors/BaseException.java new file mode 100644 index 000000000..23cbef50c --- /dev/null +++ b/micro-error-codes/src/main/java/com/oath/micro/server/errors/BaseException.java @@ -0,0 +1,25 @@ +package com.oath.micro.server.errors; + +import lombok.Getter; + +@SuppressWarnings("serial") +public abstract class BaseException extends RuntimeException { + + @Getter + private final ErrorCode errorCode; + + public BaseException(final ErrorCode errorCode, final Throwable cause) { + super( + errorCode.toString(), cause); + this.errorCode = errorCode; + + } + + public BaseException(final ErrorCode errorCode) { + super( + errorCode.toString()); + this.errorCode = errorCode; + + } + +} diff --git a/micro-error-codes/src/main/java/com/oath/micro/server/errors/ErrorBus.java b/micro-error-codes/src/main/java/com/oath/micro/server/errors/ErrorBus.java new file mode 100644 index 000000000..642f254ab --- /dev/null +++ b/micro-error-codes/src/main/java/com/oath/micro/server/errors/ErrorBus.java @@ -0,0 +1,17 @@ +package com.oath.micro.server.errors; + +import com.google.common.eventbus.EventBus; + +public class ErrorBus { + + private static EventBus errorBus; + + public static synchronized void setErrorBus(final EventBus bus){ + errorBus = bus; + } + public void post(final Object o){ + if(errorBus!=null) { + errorBus.post(o); + } + } +} diff --git a/micro-error-codes/src/main/java/com/oath/micro/server/errors/ErrorCode.java b/micro-error-codes/src/main/java/com/oath/micro/server/errors/ErrorCode.java new file mode 100644 index 000000000..7b5f43eff --- /dev/null +++ b/micro-error-codes/src/main/java/com/oath/micro/server/errors/ErrorCode.java @@ -0,0 +1,64 @@ +package com.oath.micro.server.errors; + +import java.text.MessageFormat; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.Getter; + +@Getter +public class ErrorCode { + + private final int errorId; + private final String message; + private final Severity severity; + + public static ErrorCode error(final int errorId, final String message, final Severity severity) { + return new ErrorCode( + errorId, message, severity); + } + + public static ErrorCode low(final int errorId, final String message) { + return new ErrorCode( + errorId, message, Severity.LOW); + } + + public static ErrorCode medium(final int errorId, final String message) { + return new ErrorCode( + errorId, message, Severity.MEDIUM); + } + + public static ErrorCode high(final int errorId, final String message) { + return new ErrorCode( + errorId, message, Severity.HIGH); + } + + public static ErrorCode critical(final int errorId, final String message) { + return new ErrorCode( + errorId, message, Severity.CRITICAL); + } + + private ErrorCode(@JsonProperty("errorId") final int errorId, @JsonProperty("message") final String message, + @JsonProperty("severity") final Severity severity) { + + this.errorId = errorId; + this.message = message; + this.severity = severity; + + } + + public FormattedErrorCode format(Object... data) { + return new FormattedErrorCode( + new ErrorCode( + errorId, formatStr(data), severity)); + } + + public String formatStr(Object... data) { + return MessageFormat.format(message, data); + } + + @Override + public String toString() { + return "Error ID (" + errorId + ") :" + " - " + message; + } +} diff --git a/micro-error-codes/src/main/java/com/oath/micro/server/errors/FormattedErrorCode.java b/micro-error-codes/src/main/java/com/oath/micro/server/errors/FormattedErrorCode.java new file mode 100644 index 000000000..4e51c1777 --- /dev/null +++ b/micro-error-codes/src/main/java/com/oath/micro/server/errors/FormattedErrorCode.java @@ -0,0 +1,11 @@ +package com.oath.micro.server.errors; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor(access = AccessLevel.PACKAGE) +@Getter +public class FormattedErrorCode { + private final ErrorCode code; +} diff --git a/micro-error-codes/src/main/java/com/oath/micro/server/errors/InvalidStateException.java b/micro-error-codes/src/main/java/com/oath/micro/server/errors/InvalidStateException.java new file mode 100644 index 000000000..94118889b --- /dev/null +++ b/micro-error-codes/src/main/java/com/oath/micro/server/errors/InvalidStateException.java @@ -0,0 +1,23 @@ +package com.oath.micro.server.errors; + +import com.oath.micro.server.health.ErrorEvent; + +public class InvalidStateException extends BaseException { + + private static final long serialVersionUID = 1L; + + public InvalidStateException(final FormattedErrorCode errorCode) { + super( + errorCode.getCode()); + new ErrorBus().post(new ErrorEvent( + this)); + } + + public InvalidStateException(final FormattedErrorCode errorCode, final Throwable cause) { + super( + errorCode.getCode(), cause); + new ErrorBus().post(new ErrorEvent( + this)); + } + +} diff --git a/micro-error-codes/src/main/java/com/oath/micro/server/errors/Severity.java b/micro-error-codes/src/main/java/com/oath/micro/server/errors/Severity.java new file mode 100644 index 000000000..d9b508ee3 --- /dev/null +++ b/micro-error-codes/src/main/java/com/oath/micro/server/errors/Severity.java @@ -0,0 +1,5 @@ +package com.oath.micro.server.errors; + +public enum Severity { + LOW, MEDIUM, HIGH, CRITICAL, FATAL +} diff --git a/micro-error-codes/src/main/java/com/oath/micro/server/health/ErrorEvent.java b/micro-error-codes/src/main/java/com/oath/micro/server/health/ErrorEvent.java new file mode 100644 index 000000000..7a6e7ce17 --- /dev/null +++ b/micro-error-codes/src/main/java/com/oath/micro/server/health/ErrorEvent.java @@ -0,0 +1,64 @@ +package com.oath.micro.server.health; + +import java.io.Serializable; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.function.Function; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; +import javax.xml.bind.annotation.XmlType; + +import com.oath.micro.server.errors.BaseException; +import com.oath.micro.server.errors.ErrorCode; +import com.oath.micro.server.errors.Severity; + +import lombok.Getter; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "error-event") +@XmlType(name = "") +public class ErrorEvent implements Serializable { + + private static final long serialVersionUID = 1L; + + @Getter + private final Date time = new Date(); + + @XmlElement(name = "formatted-date") + private final String formattedDate = new SimpleDateFormat( + "yyyy.MM.dd 'at' HH:mm:ss z").format(new Date()); + + @XmlElement(name = "error-code") + @Getter + private final ErrorCode code; + + @XmlElement(name = "error-message") + @Getter + private final String message; + + @XmlTransient + @Getter + private final boolean fatal; + + public ErrorEvent() { + code = null; + message = null; + fatal = false; + } + + public ErrorEvent(final BaseException exception) { + code = exception.getErrorCode(); + message = exception.getMessage(); + fatal = Severity.FATAL.equals(code.getSeverity()); + } + + public R visit(Function fatalError, Function nonFatalError) { + return fatal ? fatalError.apply(this) : nonFatalError.apply(this); + + } + +} diff --git a/micro-error-codes/src/main/java/com/oath/micro/server/health/HealthCheck.java b/micro-error-codes/src/main/java/com/oath/micro/server/health/HealthCheck.java new file mode 100644 index 000000000..a20ff53c7 --- /dev/null +++ b/micro-error-codes/src/main/java/com/oath/micro/server/health/HealthCheck.java @@ -0,0 +1,82 @@ +package com.oath.micro.server.health; + +import java.util.concurrent.ConcurrentLinkedQueue; + +import javax.annotation.PostConstruct; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.HealthStatusChecker; +import com.oath.micro.server.errors.ErrorBus; +import com.oath.micro.server.health.HealthStatus.State; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +import lombok.Getter; + +@Component +public class HealthCheck implements HealthStatusChecker { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + private final HealthChecker healthCheckHelper; + + @Getter + private volatile int maxSize; + + private final int hardMax; + private final EventBus errorBus; + + @Autowired + public HealthCheck(HealthChecker healthChecker, @Value("${health.check.error.list.size:25}") int maxSize, + @Value("${health.check.max.error.list.size:2500}") int hardMax, EventBus errorBus) { + this.healthCheckHelper = healthChecker; + this.maxSize = maxSize; + this.hardMax = hardMax; + this.errorBus = errorBus; + } + + final ConcurrentLinkedQueue errors = new ConcurrentLinkedQueue<>(); + final ConcurrentLinkedQueue fatalErrors = new ConcurrentLinkedQueue<>(); + + @PostConstruct + public void register() { + errorBus.register(this); + ErrorBus.setErrorBus(errorBus); + } + + public void setMaxSize(int maxSize) { + if (maxSize <= hardMax) + this.maxSize = maxSize; + } + + private Void handle(ErrorEvent e, ConcurrentLinkedQueue queue) { + while (queue.size() >= maxSize) + queue.poll(); + queue.offer(e); + return null; + } + + @Subscribe + public void onEvent(final ErrorEvent event) { + event.visit(e -> handle(e, fatalErrors), e -> handle(e, errors)); + + } + + public HealthStatus checkHealthStatus() { + return healthCheckHelper.checkHealthStatus(errors, this.fatalErrors); + } + + @Override + public boolean isOk() { + State state = checkHealthStatus().getGeneralProcessing(); + if (state.equals(State.Fatal)) + return false; + return true; + } + +} diff --git a/micro-error-codes/src/main/java/com/oath/micro/server/health/HealthChecker.java b/micro-error-codes/src/main/java/com/oath/micro/server/health/HealthChecker.java new file mode 100644 index 000000000..21e9cb5d5 --- /dev/null +++ b/micro-error-codes/src/main/java/com/oath/micro/server/health/HealthChecker.java @@ -0,0 +1,58 @@ +package com.oath.micro.server.health; + +import java.util.Queue; + +import cyclops.control.Maybe; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + + + +@Component +public class HealthChecker { + + private final long timeThresholdForNormal; + + @Autowired + public HealthChecker( + @Value("${health.check.time.threshold.from.error.to.normal:360000}") long timeThresholdForNormalInMillis) { + this.timeThresholdForNormal = timeThresholdForNormalInMillis; + } + + HealthStatus checkHealthStatus(final Queue errors, final Queue fatal) { + + Maybe latest = selectLatestError(errors, fatal); + HealthStatus.State state = state(latest); + + final HealthStatus status = new HealthStatus( + state, errors, fatal); + return status; + } + + private Maybe selectLatestError(Queue errors, Queue fatal) { + if (errors.size() == 0 && fatal.size() == 0) { + return Maybe.nothing(); + } + if (fatal.size() > 0) { + return Maybe.just(fatal.peek()); + } + return Maybe.just(errors.peek()); + + } + + private HealthStatus.State state(Maybe errors) { + return errors.fold(this::handleError, () -> HealthStatus.State.Ok); + } + + private HealthStatus.State handleError(ErrorEvent event) { + return event.visit(e -> HealthStatus.State.Fatal, e -> { + if (System.currentTimeMillis() - event.getTime() + .getTime() < timeThresholdForNormal) { + return HealthStatus.State.Errors; + } else { + return HealthStatus.State.Ok; + } + }); + } +} diff --git a/micro-error-codes/src/main/java/com/oath/micro/server/health/HealthStatus.java b/micro-error-codes/src/main/java/com/oath/micro/server/health/HealthStatus.java new file mode 100644 index 000000000..c6d73007d --- /dev/null +++ b/micro-error-codes/src/main/java/com/oath/micro/server/health/HealthStatus.java @@ -0,0 +1,45 @@ +package com.oath.micro.server.health; + +import java.io.Serializable; +import java.util.Queue; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +import cyclops.reactive.collections.mutable.QueueX; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "health-status") +@XmlType(name = "") +@AllArgsConstructor +public class HealthStatus implements Serializable { + + private static final long serialVersionUID = 1L; + + public enum State { + Ok, Untested, Errors, Fatal + } + + @Getter + @XmlElement(name = "general-processing") + private final State generalProcessing; + + @Getter + @XmlElement(name = "recent-errors") + private final Queue recentErrors; + @Getter + @XmlElement(name = "fatal-errors") + private final Queue fatalErrors; + + public HealthStatus() { + generalProcessing = State.Untested; + recentErrors = QueueX.empty(); + fatalErrors = QueueX.empty(); + } +} diff --git a/micro-error-codes/src/main/java/com/oath/micro/server/plugin/ErrorsPlugin.java b/micro-error-codes/src/main/java/com/oath/micro/server/plugin/ErrorsPlugin.java new file mode 100644 index 000000000..5fbfd16ee --- /dev/null +++ b/micro-error-codes/src/main/java/com/oath/micro/server/plugin/ErrorsPlugin.java @@ -0,0 +1,18 @@ +package com.oath.micro.server.plugin; + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.health.HealthCheck; +import com.oath.micro.server.health.HealthChecker; +import com.oath.micro.server.rest.HealthCheckResource; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +public class ErrorsPlugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of(HealthCheckResource.class, HealthChecker.class, HealthCheck.class); + } + +} diff --git a/micro-error-codes/src/main/java/com/oath/micro/server/rest/HealthCheckResource.java b/micro-error-codes/src/main/java/com/oath/micro/server/rest/HealthCheckResource.java new file mode 100644 index 000000000..113aaa8d0 --- /dev/null +++ b/micro-error-codes/src/main/java/com/oath/micro/server/rest/HealthCheckResource.java @@ -0,0 +1,75 @@ +package com.oath.micro.server.rest; + +import java.util.Map; + +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.CommonRestResource; +import com.oath.micro.server.auto.discovery.SingletonRestResource; +import com.oath.micro.server.health.HealthCheck; +import com.oath.micro.server.utility.HashMapBuilder; + +@Path("/system-errors") +@Component +public class HealthCheckResource implements CommonRestResource, SingletonRestResource { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final HealthCheck healthCheck; + private final boolean showErrors; + + @Autowired + public HealthCheckResource(HealthCheck healthCheck, @Value("${health.check.show.errors:true}") boolean showErrors) { + this.healthCheck = healthCheck; + this.showErrors = showErrors; + + } + + @POST + @Path("/max-errors/{maxErrors}") + @Produces("application/json") + public Map setMaxErrors(@PathParam("maxErrors") int maxErrors) { + healthCheck.setMaxSize(maxErrors); + return getMaxErrors(); + } + + @GET + @Path("/max-errors") + @Produces("application/json") + public Map getMaxErrors() { + + return HashMapBuilder.of("maxErrors", healthCheck.getMaxSize()); + } + + @GET + @Path("/status") + @Produces("text/plain") + public String ping() { + return healthCheck.checkHealthStatus() + .getGeneralProcessing() + .name(); + } + + @GET + @Path("/errors") + @Produces("application/json") + public Response errors() { + if (!showErrors) + Response.status(Status.UNAUTHORIZED) + .build(); + return Response.ok(healthCheck.checkHealthStatus()) + .build(); + } + +} \ No newline at end of file diff --git a/micro-error-codes/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-error-codes/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..a31f0780d --- /dev/null +++ b/micro-error-codes/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.plugin.ErrorsPlugin \ No newline at end of file diff --git a/micro-error-codes/src/test/java/app/errors/com/oath/micro/server/Errors.java b/micro-error-codes/src/test/java/app/errors/com/oath/micro/server/Errors.java new file mode 100644 index 000000000..b7d499f99 --- /dev/null +++ b/micro-error-codes/src/test/java/app/errors/com/oath/micro/server/Errors.java @@ -0,0 +1,9 @@ +package app.errors.com.oath.micro.server; + +import com.oath.micro.server.errors.ErrorCode; +import com.oath.micro.server.errors.Severity; + +public interface Errors { + public final static ErrorCode QUERY_FAILURE = ErrorCode.error(1, "something {0} bad happened", Severity.CRITICAL); + public final static ErrorCode SYSTEM_FAILURE = ErrorCode.error(2, "something {0} really bad", Severity.FATAL); +} diff --git a/micro-error-codes/src/test/java/app/errors/com/oath/micro/server/SingleClassTest.java b/micro-error-codes/src/test/java/app/errors/com/oath/micro/server/SingleClassTest.java new file mode 100644 index 000000000..2abc7346f --- /dev/null +++ b/micro-error-codes/src/test/java/app/errors/com/oath/micro/server/SingleClassTest.java @@ -0,0 +1,90 @@ +package app.errors.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.errors.InvalidStateException; +import com.oath.micro.server.health.HealthStatus; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +@Path("/single") +public class SingleClassTest implements RestResource { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + + server = new MicroserverApp( + SingleClassTest.class, () -> "simple-app"); + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + rest.get("http://localhost:8080/simple-app/single/error"); + + assertThat(rest.get("http://localhost:8080/simple-app/system-errors/status"), + is(HealthStatus.State.Errors.name())); + assertThat(rest.getJson("http://localhost:8080/simple-app/system-errors/errors"), + containsString("formatted-date")); + + rest.get("http://localhost:8080/simple-app/single/fatal"); + + System.out.println(rest.getJson("http://localhost:8080/simple-app/system-errors/errors")); + assertThat(rest.get("http://localhost:8080/simple-app/system-errors/status"), + is(HealthStatus.State.Fatal.name())); + + } + + @GET + @Produces("text/plain") + @Path("/error") + public String error() { + try { + throw new InvalidStateException( + Errors.QUERY_FAILURE.format("*eek*")); + } catch (Exception e) { + e.printStackTrace(); + } + return "error"; + } + + @GET + @Produces("text/plain") + @Path("/fatal") + public String fatal() { + try { + throw new InvalidStateException( + Errors.SYSTEM_FAILURE.format("*eek*")); + } catch (Exception e) { + e.printStackTrace(); + } + return "unrecoverable fatal error"; + } + +} \ No newline at end of file diff --git a/micro-error-codes/src/test/java/com/oath/micro/server/common/exceptions/ErrorBusTest.java b/micro-error-codes/src/test/java/com/oath/micro/server/common/exceptions/ErrorBusTest.java new file mode 100644 index 000000000..14e16c159 --- /dev/null +++ b/micro-error-codes/src/test/java/com/oath/micro/server/common/exceptions/ErrorBusTest.java @@ -0,0 +1,28 @@ +package com.oath.micro.server.common.exceptions; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.junit.Test; + +import com.oath.micro.server.errors.ErrorBus; +import com.google.common.eventbus.EventBus; + +public class ErrorBusTest { + + ErrorBus errorBus = new ErrorBus(); + + @Test + public void testNotSet() { + errorBus.post(this); + } + + @Test + public void testSet() { + EventBus bus = mock(EventBus.class); + ErrorBus.setErrorBus(bus); + errorBus.post(this); + verify(bus).post(this); + } + +} diff --git a/micro-error-codes/src/test/java/com/oath/micro/server/common/exceptions/InvalidStateExceptionTest.java b/micro-error-codes/src/test/java/com/oath/micro/server/common/exceptions/InvalidStateExceptionTest.java new file mode 100644 index 000000000..977e5cef3 --- /dev/null +++ b/micro-error-codes/src/test/java/com/oath/micro/server/common/exceptions/InvalidStateExceptionTest.java @@ -0,0 +1,41 @@ +package com.oath.micro.server.common.exceptions; + +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.errors.ErrorBus; +import com.oath.micro.server.errors.InvalidStateException; +import com.oath.micro.server.health.ErrorEvent; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +import app.errors.com.oath.micro.server.Errors; + +public class InvalidStateExceptionTest { + + boolean eventTriggered = false; + + ErrorBus bus; + + @Before + public void setup() { + bus = new ErrorBus(); + EventBus ebus = new EventBus(); + ebus.register(this); + ErrorBus.setErrorBus(ebus); + } + + @Test + public void testEventErrorSuscriber() { + new InvalidStateException( + Errors.QUERY_FAILURE.format()); + assertTrue(eventTriggered); + } + + @Subscribe + public void onEvent(final ErrorEvent event) { + eventTriggered = true; + } +} diff --git a/micro-error-codes/src/test/java/com/oath/micro/server/health/HealthCheckTest.java b/micro-error-codes/src/test/java/com/oath/micro/server/health/HealthCheckTest.java new file mode 100644 index 000000000..46554b52a --- /dev/null +++ b/micro-error-codes/src/test/java/com/oath/micro/server/health/HealthCheckTest.java @@ -0,0 +1,79 @@ +package com.oath.micro.server.health; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.junit.Before; +import org.junit.Test; + +import com.google.common.eventbus.EventBus; + +public class HealthCheckTest { + + HealthCheck check; + EventBus eventBus; + + @Before + public void setup() { + + eventBus = mock(EventBus.class); + + check = new HealthCheck( + new HealthChecker( + 10000l), + 10, 20, eventBus); + } + + @Test + public void testRegister() { + check.register(); + verify(eventBus).register(check); + } + + @Test + public void testOnEvent() { + check.onEvent(new ErrorEvent()); + assertThat(check.errors.size(), is(1)); + } + + @Test + public void testOnEventMaxNotExceeded() { + for (int i = 0; i < check.getMaxSize() * 2; i++) { + check.onEvent(new ErrorEvent()); + assertThat(check.errors.size(), is(Math.min(i + 1, check.getMaxSize()))); + } + } + + @Test + public void testCheckHealthStatusErrorsOld() throws InterruptedException { + check = new HealthCheck( + new HealthChecker( + 1l), + 10, 20, eventBus); + check.onEvent(new ErrorEvent()); + + Thread.sleep(1l); + + HealthStatus status = check.checkHealthStatus(); + + assertThat(status.getGeneralProcessing(), is(HealthStatus.State.Ok)); + assertThat(status.getRecentErrors() + .size(), + is(1)); + } + + @Test + public void testSetMaxSizeTooBig() { + check.setMaxSize(100); + assertThat(check.getMaxSize(), is(10)); + } + + @Test + public void testSetMaxSizeOk() { + check.setMaxSize(15); + assertThat(check.getMaxSize(), is(15)); + } + +} diff --git a/micro-error-codes/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-error-codes/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-error-codes/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-event-metrics/README.md b/micro-event-metrics/README.md new file mode 100644 index 000000000..2fbe49d37 --- /dev/null +++ b/micro-event-metrics/README.md @@ -0,0 +1,184 @@ +# Event Metrics Plugin + + +Captures Dropwizard metrics based on application events + +[micro-event-metrics example apps](https://github.com/aol/micro-server/tree/master/micro-event-metrics/src/test/java/app) + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-event-metrics/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-event-metrics) + +Simply add to the classpath + +Maven +```xml + + com.oath.microservices + micro-event-metrics + x.yz + +``` +Gradle +```groovy + compile 'com.oath.microservices:micro-event-metrics:x.yz' +``` +### Depends on + +1. [micro-events](https://github.com/aol/micro-server/tree/master/micro-events) +1. [micro-error-codes](https://github.com/aol/micro-server/tree/master/micro-error-codes) +3. [micro-reactive](https://github.com/aol/micro-server/tree/master/micro-reactive) +4. [micro-guava](https://github.com/aol/micro-server/tree/master/micro-guava) + +# Captures metrics on + +1. Scheduled jobs +2. User requests +3. Errors + + +## Properties + + +### Metric name properties + +All Metrics have a prefix, this is configurable + + event.metrics.capture.jobs.prefix= + +By default it is set to com.aol.micro.server.event.metrics.MetricsCatcher + +Job names are configurable as either + +* SIMPLE (simple class name) +* PACKAGE (last part of package + simple class name) +* FULL (canononical class name) + +e.g. + + micro.events.job.name.format:SIMPLE + +or + + micro.events.job.name.format:SIMPLE + +### Error handling properties + +Turn on / off capturing errors by severvity + + event.metrics.capture.errors.by.type=true/false + +Turn on / off capturing errors by error code + + event.metrics.capture.errors.by.code=true/false + +### Query handling properties + +Capture metrics on queries by type + + event.metrics.capture.queries.by.type=true/false + +Number of active queries to cache in memory + + event.metrics.capture.number.of.queries= + +Number of minutes to cache active queries in memory + + event.metrics.capture.queries.minutes= + +### Scheduled job handling properties + +Capture scheduled job metrics by type + + event.metrics.capture.jobs.by.type=true/false + +Number of active jobs to cache in memory + + event.metrics.capture.number.of.jobs= + + Number of minutes to cache active jobs in memory + + event.metrics.capture.jobs.minutes= + +## The following metrics are captured + +### Requests : + +#### Meters : + +```text +com.aol.micro.server.event.metrics.MetricsCatcher.requests-started +com.aol.micro.server.event.metrics.MetricsCatcher.requests-started-interval-count +com.aol.micro.server.event.metrics.MetricsCatcher.request-start- +com.aol.micro.server.event.metrics.MetricsCatcher.request-start--interval-count +com.aol.micro.server.event.metrics.MetricsCatcher.requests-completed +com.aol.micro.server.event.metrics.MetricsCatcher.requests-completed-interval-type +com.aol.micro.server.event.metrics.MetricsCatcher.request-completed- +com.aol.micro.server.event.metrics.MetricsCatcher.request-completed--interval-count + +``` + +#### Timers : + +```text +com.aol.micro.server.event.metrics.MetricsCatcher.request-completed- +``` + +#### Counters : +```text +com.aol.micro.server.event.metrics.MetricsCatcher.requests-started-count +com.aol.micro.server.event.metrics.MetricsCatcher.requests-active-count +``` + +### Jobs : + +#### Meters: +```text +com.aol.micro.server.event.metrics.MetricsCatcher.jobs-completed +com.aol.micro.server.event.metrics.MetricsCatcher.jobs- +``` + +#### Counters : +```text +com.aol.micro.server.event.metrics.MetricsCatcher.jobs-completed-count +com.aol.micro.server.event.metrics.MetricsCatcher.jobs-active-count +``` + +#### Timers : +```text +com.aol.micro.server.event.metrics.MetricsCatcher.job-timer- +``` + +### Errors: + +#### Meters: +```text +com.aol.micro.server.event.metrics.MetricsCatcher.errors +com.aol.micro.server.event.metrics.MetricsCatcher.error-- +com.aol.micro.server.event.metrics.MetricsCatcher.error- +``` + +#### Counters: +```text +com.aol.micro.server.event.metrics.MetricsCatcher.errors-count +com.aol.micro.server.event.metrics.MetricsCatcher.error---count +com.aol.micro.server.event.metrics.MetricsCatcher.error--count +``` + +# Configuration + +Configuration properties and their default values + +```text +event.metrics.capture.errors.by.type=true # errorsByType, +event.metrics.capture.errors.by.code=true # errorsByCode, +event.metrics.capture.queries.by.type=true # queriesByType, +event.metrics.capture.jobs.by.type=true # jobsByType, +event.metrics.capture.number.of.queries=10000 # numQueries, +event.metrics.capture.queries.minutes=180 # holdQueriesForMinutes, +event.metrics.capture.number.of.jobs=10000 # numJobs, +event.metrics.capture.jobs.minutes=180, +event.metrics.capture.timer.interval.seconds=10 +event.metrics.capture.jobs.prefix=null +``` + diff --git a/micro-event-metrics/build.gradle b/micro-event-metrics/build.gradle new file mode 100644 index 000000000..57a49e442 --- /dev/null +++ b/micro-event-metrics/build.gradle @@ -0,0 +1,60 @@ +description = 'micro-event-metrics' + +dependencies { + compile project(':micro-events') + compile project(':micro-metrics') + compile project(':micro-error-codes') + testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: hamcrestVersion + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') +} + +modifyPom { + project { + name 'Microserver event metrics' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2016' + + groupId 'com.oath.microservices' + artifactId 'micro-event-metrics' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + } + + } +} + +extraArchive { + sources = true + tests = true + javadoc = true +} + +nexus { + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' +} + diff --git a/micro-event-metrics/src/main/java/com/oath/micro/server/event/metrics/Configuration.java b/micro-event-metrics/src/main/java/com/oath/micro/server/event/metrics/Configuration.java new file mode 100644 index 000000000..ce0fb47a3 --- /dev/null +++ b/micro-event-metrics/src/main/java/com/oath/micro/server/event/metrics/Configuration.java @@ -0,0 +1,55 @@ +package com.oath.micro.server.event.metrics; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Component +class Configuration { + + private volatile boolean errorsByType = true; + private volatile boolean errorsByCode = true; + private volatile boolean queriesByType = true; + private volatile boolean jobsByType = true; + + private final int numQueries; + private final int holdQueriesForMinutes; + + private final int numJobs; + private final int holdJobsForMinutes; + private final int timerIntervalSeconds; + private final String prefix; + + @Autowired + public Configuration(@Value("${event.metrics.capture.errors.by.type:true}") boolean errorsByType, + @Value("${event.metrics.capture.errors.by.code:true}") boolean errorsByCode, + @Value("${event.metrics.capture.queries.by.type:true}") boolean queriesByType, + @Value("${event.metrics.capture.jobs.by.type:true}") boolean jobsByType, + @Value("${event.metrics.capture.number.of.queries:10000}") int numQueries, + @Value("${event.metrics.capture.queries.minutes:180}") int holdQueriesForMinutes, + @Value("${event.metrics.capture.number.of.jobs:10000}") int numJobs, + @Value("${event.metrics.capture.jobs.minutes:180}") int holdJobsForMinutes, + @Value("${event.metrics.capture.timer.interval.seconds:10}") int timerIntervalSeconds, + @Value("${event.metrics.capture.jobs.prefix:#{null}}") String prefix) { + super(); + this.errorsByType = errorsByType; + this.errorsByCode = errorsByCode; + this.queriesByType = queriesByType; + this.jobsByType = jobsByType; + this.numQueries = numQueries; + this.holdQueriesForMinutes = holdQueriesForMinutes; + this.numJobs = numJobs; + this.holdJobsForMinutes = holdJobsForMinutes; + this.timerIntervalSeconds = timerIntervalSeconds; + this.prefix = Optional.ofNullable(prefix) + .orElseGet(() -> MetricsCatcher.class.getTypeName()); + } + +} diff --git a/micro-event-metrics/src/main/java/com/oath/micro/server/event/metrics/MetricEventsPlugin.java b/micro-event-metrics/src/main/java/com/oath/micro/server/event/metrics/MetricEventsPlugin.java new file mode 100644 index 000000000..c02d5e5d3 --- /dev/null +++ b/micro-event-metrics/src/main/java/com/oath/micro/server/event/metrics/MetricEventsPlugin.java @@ -0,0 +1,30 @@ +package com.oath.micro.server.event.metrics; + + +import com.oath.micro.server.Plugin; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + + +/** + * + * Collections of Spring configuration classes (Classes annotated with @Configuration) + * that configure various useful pieces of functionality - such as property file loading, + * datasources, scheduling etc + * + * @author johnmcclean + * + */ +public class MetricEventsPlugin implements Plugin{ + + @Override + public Set springClasses() { + return SetX.of( + Configuration.class, + MetricsCatcher.class); + } + + + +} diff --git a/micro-event-metrics/src/main/java/com/oath/micro/server/event/metrics/MetricsCatcher.java b/micro-event-metrics/src/main/java/com/oath/micro/server/event/metrics/MetricsCatcher.java new file mode 100644 index 000000000..a0ba62dc3 --- /dev/null +++ b/micro-event-metrics/src/main/java/com/oath/micro/server/event/metrics/MetricsCatcher.java @@ -0,0 +1,231 @@ +package com.oath.micro.server.event.metrics; + +import com.oath.micro.server.events.GenericEvent; +import com.oath.micro.server.spring.metrics.InstantGauge; +import com.codahale.metrics.SlidingTimeWindowArrayReservoir; +import com.codahale.metrics.Timer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.errors.ErrorCode; +import com.oath.micro.server.events.JobCompleteEvent; +import com.oath.micro.server.events.JobStartEvent; +import com.oath.micro.server.events.RequestTypes.AddQuery; +import com.oath.micro.server.events.RequestTypes.RemoveQuery; +import com.oath.micro.server.events.RequestTypes.AddLabelledQuery; +import com.oath.micro.server.events.RequestTypes.RemoveLabelledQuery; +import com.oath.micro.server.events.RequestTypes.RequestData; +import com.oath.micro.server.events.SystemData; +import com.oath.micro.server.health.ErrorEvent; +import com.codahale.metrics.MetricRegistry; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +@Component +public class MetricsCatcher { + + private final MetricRegistry registry; + + private final TimerManager queries; + + private final TimerManager jobs; + private final Configuration configuration; + private final String prefix; + + @Autowired + public MetricsCatcher(MetricRegistry registry, EventBus bus, Configuration configuration) { + this.prefix = configuration.getPrefix(); + this.registry = registry; + bus.register(this); + queries = new TimerManager( + configuration.getNumQueries(), configuration.getHoldQueriesForMinutes()); + jobs = new TimerManager( + configuration.getNumJobs(), configuration.getHoldJobsForMinutes()); + this.configuration = configuration; + + } + + @Subscribe + public void requestStart(AddQuery data) { + registry.meter(prefix + ".requests-started") + .mark(); + registry.counter(prefix + ".requests-started-count") + .inc(); + ((InstantGauge) registry.gauge(prefix + ".requests-started-interval-count", () -> new InstantGauge())).increment(); + + if (this.configuration.isQueriesByType()) { + RequestData rd = data.getData(); + + registry.meter(queryStartName(rd) + "-meter") + .mark(); + + queries.start(rd.getCorrelationId(), timer(queryEndName(rd) + "-timer").time()); + registry.counter(prefix + ".requests-active-" + rd.getType() + "-count") + .inc(); + ((InstantGauge) registry.gauge(prefix + ".requests-started-" + rd.getType() + "-interval-count", + () -> new InstantGauge())).increment(); + + } + } + + private String queryStartName(RequestData rd) { + return prefix + ".request-start-" + rd.getType(); + } + + private String queryEndName(RequestData rd) { + return prefix + ".request-end-" + rd.getType(); + } + + @Subscribe + public void requestComplete(RemoveQuery data) { + registry.meter(prefix + ".requests-completed") + .mark(); + registry.counter(prefix + ".requests-completed-count") + .inc(); + ((InstantGauge) registry.gauge(prefix + ".requests-completed-interval-count", () -> new InstantGauge())) + .increment(); + + if (this.configuration.isQueriesByType()) { + RequestData rd = data.getData(); + registry.meter(queryEndName(rd)) + .mark(); + + queries.complete(rd.getCorrelationId()); + + registry.counter(prefix + ".requests-active-" + rd.getType() + "-count") + .dec(); + ((InstantGauge) registry.gauge(prefix + ".requests-completed-" + rd.getType() + "-interval-count", + () -> new InstantGauge())).increment(); + + } + } + + @Subscribe + public void requestStart(AddLabelledQuery data) { + if (this.configuration.isQueriesByType()) { + RequestData rd = data.getData(); + + ((InstantGauge) registry.gauge(prefix + ".requests-started-" + rd.getType() + "-interval-count", () -> new InstantGauge())) + .increment(); + } + } + + @Subscribe + public void requestComplete(RemoveLabelledQuery data) { + if (this.configuration.isQueriesByType()) { + RequestData rd = data.getData(); + ((InstantGauge) registry.gauge(prefix + ".requests-completed-" + rd.getType() + "-interval-count", () -> new InstantGauge())) + .increment(); + } + } + + @Subscribe + public void finished(SystemData data) { + registry.meter(prefix + ".jobs-completed") + .mark(); + registry.counter(prefix + ".jobs-completed-count") + .inc(); + + } + + @Subscribe + public void jobStarted(JobStartEvent data) { + if (this.configuration.isJobsByType()) { + registry.meter(prefix + ".job-meter-" + data.getType()) + .mark(); + + jobs.start(data.getCorrelationId(), timer(prefix + ".job-timer-" + data.getType()).time()); + registry.counter(prefix + ".jobs-active-" + data.getType() + "-count") + .inc(); + } + } + + @Subscribe + public void jobComplete(JobCompleteEvent data) { + if (this.configuration.isJobsByType()) { + jobs.complete(data.getCorrelationId()); + registry.counter(prefix + ".jobs-active-" + data.getType() + "-count") + .dec(); + + registry.counter(prefix + ".jobs-processed-" + data.getType() + "-count-data") + .inc(data.getDataSize()); + registry.meter(prefix + ".jobs-processed-" + data.getType() + "-meter-data") + .mark(data.getDataSize()); + registry.counter(prefix + ".jobs-errors-" + data.getType() + "-count-data") + .inc(data.getErrors()); + registry.meter(prefix + ".jobs-errors-" + data.getType() + "-meter-data") + .mark(data.getErrors()); + + if (data.getErrors() > 0l) { + registry.counter(prefix + ".jobs-succeeded-" + data.getType() + "-count") + .inc(); + registry.meter(prefix + ".jobs-succeeded-" + data.getType() + "-meter") + .mark(); + + } else { + + registry.counter(prefix + ".jobs-failed-" + data.getType() + "-count") + .inc(); + registry.meter(prefix + ".jobs-failed-" + data.getType() + "-meter") + .mark(); + } + } + } + + @Subscribe + public void error(ErrorCode c) { + registry.meter(prefix + ".errors") + .mark(); + registry.counter(prefix + ".errors-count") + .inc(); + if (this.configuration.isErrorsByCode()) { + registry.meter(name(c)) + .mark(); + registry.counter(name(c) + "-count") + .inc(); + } + if (this.configuration.isErrorsByType()) { + registry.meter(prefix + ".error-severity-" + c.getSeverity() + .name()) + .mark(); + + registry.counter(prefix + ".error-severity-" + c.getSeverity() + .name() + + "-count") + .inc(); + } + } + + @Subscribe + public void error(ErrorEvent event) { + ErrorCode c = event.getCode(); + error(c); + + } + + @Subscribe + public void genericEvent(GenericEvent event) { + GenericEvent.GenericEventData eventData = event.getData(); + String name = prefix + ".event-" + eventData.getName(); + registry.counter(name + "-count").inc(); + registry.meter(name + "-meter").mark(); + if (Objects.nonNull(eventData.getSubTypes())) { + for (String subType : eventData.getSubTypes()) { + name = name + "." + subType; + registry.counter(name + "-count").inc(); + registry.meter(name + "-meter").mark(); + } + } + } + + private String name(ErrorCode c) { + return prefix + ".error-" + c.getSeverity() + "-" + c.getErrorId(); + } + + private Timer timer (String name) { + return registry.timer(name, () -> new Timer(new SlidingTimeWindowArrayReservoir(configuration.getTimerIntervalSeconds(), TimeUnit.SECONDS))); + } +} diff --git a/micro-event-metrics/src/main/java/com/oath/micro/server/event/metrics/TimerManager.java b/micro-event-metrics/src/main/java/com/oath/micro/server/event/metrics/TimerManager.java new file mode 100644 index 000000000..31c75cedc --- /dev/null +++ b/micro-event-metrics/src/main/java/com/oath/micro/server/event/metrics/TimerManager.java @@ -0,0 +1,31 @@ +package com.oath.micro.server.event.metrics; + +import java.util.concurrent.TimeUnit; + +import com.codahale.metrics.Timer.Context; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import cyclops.control.Maybe; + +public class TimerManager { + + private final Cache contexts; + + public TimerManager(long maxSize, int minutesUntilExpire) { + contexts = CacheBuilder.newBuilder() + .maximumSize(maxSize) + .expireAfterWrite(minutesUntilExpire, TimeUnit.MINUTES) + .build(); + } + + public void complete(String id) { + Maybe.ofNullable(contexts.getIfPresent(id)) + .forEach(Context::stop); + contexts.invalidate(id); + } + + public void start(String id, Context context) { + contexts.put(id, context); + + } +} diff --git a/micro-event-metrics/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-event-metrics/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..9395b9100 --- /dev/null +++ b/micro-event-metrics/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.event.metrics.MetricEventsPlugin \ No newline at end of file diff --git a/micro-event-metrics/src/test/java/app/event/metrics/com/oath/micro/server/EventRunnerTest.java b/micro-event-metrics/src/test/java/app/event/metrics/com/oath/micro/server/EventRunnerTest.java new file mode 100644 index 000000000..8cc157c42 --- /dev/null +++ b/micro-event-metrics/src/test/java/app/event/metrics/com/oath/micro/server/EventRunnerTest.java @@ -0,0 +1,63 @@ +package app.event.metrics.com.oath.micro.server; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class EventRunnerTest { + + RestAgent rest = new RestAgent(); + MicroserverApp server; + + @Before + public void startServer() { + + server = new MicroserverApp( + () -> "event-app"); + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + assertThat(rest.get("http://localhost:8080/event-app/status/ping"), is("ok")); + + assertThat(rest.getJson("http://localhost:8080/event-app/active/jobs"), containsString("startedAt")); + assertThat(rest.getJson("http://localhost:8080/event-app/active/requests"), containsString("startedAt")); + assertThat(rest.getJson("http://localhost:8080/event-app/manifest"), containsString("Manifest")); + + String json = rest.getJson("http://localhost:8080/event-app/status/counters"); + Map map = JacksonUtil.convertFromJson(json, Map.class); + + assertThat(json, map.get("com.oath.micro.server.event.metrics.MetricsCatcher.jobs-completed-count"), + greaterThan(1)); + + String json2 = rest.getJson("http://localhost:8080/event-app/status/meters"); + Map map2 = JacksonUtil.convertFromJson(json2, Map.class); + + assertThat(json2, map2.get("com.oath.micro.server.event.metrics.MetricsCatcher.request-start-default-meter"), + greaterThan(0)); + + } + +} diff --git a/micro-event-metrics/src/test/java/app/event/metrics/com/oath/micro/server/EventStatusResource.java b/micro-event-metrics/src/test/java/app/event/metrics/com/oath/micro/server/EventStatusResource.java new file mode 100644 index 000000000..d63d91407 --- /dev/null +++ b/micro-event-metrics/src/test/java/app/event/metrics/com/oath/micro/server/EventStatusResource.java @@ -0,0 +1,61 @@ +package app.event.metrics.com.oath.micro.server; + +import java.util.Map; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.codahale.metrics.Counter; +import com.codahale.metrics.Meter; +import cyclops.reactive.collections.mutable.MapX; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.events.RequestEvents; +import com.codahale.metrics.MetricRegistry; +import com.google.common.eventbus.EventBus; + +@Component +@Path("/status") +public class EventStatusResource implements RestResource { + + private final EventBus bus; + private final MetricRegistry metrics; + + @Autowired + public EventStatusResource(EventBus bus, MetricRegistry metrics) { + this.bus = bus; + this.metrics = metrics; + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + bus.post(RequestEvents.start("get", "1")); + try { + return "ok"; + } finally { + bus.post(RequestEvents.finish("get", "1")); + } + } + + @GET + @Produces("application/json") + @Path("/counters") + public Map counters() { + return MapX.fromMap(metrics.getCounters()) + .bimap(k -> k, Counter::getCount); + } + + @GET + @Produces("application/json") + @Path("/meters") + public Map meters() { + return MapX.fromMap(metrics.getMeters()) + .bimap(k -> k, Meter::getCount); + } + +} diff --git a/micro-event-metrics/src/test/java/app/event/metrics/com/oath/micro/server/EventsJob.java b/micro-event-metrics/src/test/java/app/event/metrics/com/oath/micro/server/EventsJob.java new file mode 100644 index 000000000..5394bc0ce --- /dev/null +++ b/micro-event-metrics/src/test/java/app/event/metrics/com/oath/micro/server/EventsJob.java @@ -0,0 +1,19 @@ +package app.event.metrics.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.events.ScheduledJob; +import com.oath.micro.server.events.SystemData; + +@Component +public class EventsJob implements ScheduledJob { + + @Override + public SystemData scheduleAndLog() { + return SystemData. builder() + .errors(0) + .processed(2) + .build(); + } + +} diff --git a/micro-event-metrics/src/test/java/app/event/metrics/com/oath/micro/server/EventsSchedular.java b/micro-event-metrics/src/test/java/app/event/metrics/com/oath/micro/server/EventsSchedular.java new file mode 100644 index 000000000..a1a03312b --- /dev/null +++ b/micro-event-metrics/src/test/java/app/event/metrics/com/oath/micro/server/EventsSchedular.java @@ -0,0 +1,21 @@ +package app.event.metrics.com.oath.micro.server; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +@Component +public class EventsSchedular { + + private final EventsJob job; + + @Autowired + public EventsSchedular(final EventsJob job) { + this.job = job; + } + + @Scheduled(fixedDelay = 1) + public synchronized void scheduleTask() { + job.scheduleAndLog(); + } +} diff --git a/micro-event-metrics/src/test/java/com/oath/micro/server/event/metrics/MetricsCatcherConfigOffTest.java b/micro-event-metrics/src/test/java/com/oath/micro/server/event/metrics/MetricsCatcherConfigOffTest.java new file mode 100644 index 000000000..855105b6d --- /dev/null +++ b/micro-event-metrics/src/test/java/com/oath/micro/server/event/metrics/MetricsCatcherConfigOffTest.java @@ -0,0 +1,163 @@ +package com.oath.micro.server.event.metrics; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.errors.ErrorCode; +import com.oath.micro.server.events.JobCompleteEvent; +import com.oath.micro.server.events.JobStartEvent; +import com.oath.micro.server.events.RequestTypes.AddQuery; +import com.oath.micro.server.events.RequestTypes.RemoveQuery; +import com.oath.micro.server.events.RequestTypes.RequestData; +import com.codahale.metrics.MetricRegistry; +import com.google.common.eventbus.EventBus; + +public class MetricsCatcherConfigOffTest { + + MetricsCatcher catcher; + MetricRegistry registry; + EventBus bus; + Configuration config; + + @Before + public void setup() { + registry = new MetricRegistry(); + bus = new EventBus(); + config = new Configuration( + false, false, false, false, 5, 6, 7, 8, 10, "bob"); + catcher = new MetricsCatcher<>( + registry, bus, config); + } + + @Test + public void queriesStartMeterInc() { + + catcher.requestStart(new AddQuery(RequestData.builder() + .correlationId("10") + .type("test") + .build())); + assertThat(registry.meter(this.config.getPrefix() + ".request-start-test") + .getMeanRate(), + equalTo(0.0)); + } + + @Test + public void queriesEndMeterInc() { + + catcher.requestComplete(new RemoveQuery(RequestData.builder() + .correlationId("10") + .type("test") + .build())); + assertThat(registry.meter(this.config.getPrefix() + ".request-end-test") + .getMeanRate(), + equalTo(0.0)); + } + + @Test + public void queriesCounterInc() { + + catcher.requestStart(new AddQuery(RequestData.builder() + .correlationId("10") + .type("test") + .build())); + assertThat(registry.counter(this.config.getPrefix() + ".requests-active-test-count") + .getCount(), + equalTo(0l)); + } + + @Test + public void queriesCounterDec() { + + catcher.requestComplete(new RemoveQuery(RequestData.builder() + .correlationId("10") + .type("test") + .build())); + assertThat(registry.counter(this.config.getPrefix() + ".requests-active-test-count") + .getCount(), + equalTo(0l)); + } + + @Test + public void jobsCounterDec() { + + catcher.jobComplete(new JobCompleteEvent("10", "test", 10l, 5l)); + assertThat(registry.counter(this.config.getPrefix() + ".jobs-active-test-count") + .getCount(), + equalTo(0l)); + } + + @Test + public void queriesTimer() { + + catcher.requestStart(new AddQuery(RequestData.builder() + .correlationId("10") + .type("test") + .build())); + + catcher.requestComplete(new RemoveQuery(RequestData.builder() + .correlationId("10") + .type("test") + .build())); + assertThat(registry.timer(this.config.getPrefix() + ".request-end-test-timer") + .getMeanRate(), + equalTo(0.0)); + } + + @Test + public void jobsMeterInc() { + + catcher.jobStarted(new JobStartEvent("10", "test")); + assertThat(registry.meter(this.config.getPrefix() + ".job-meter-test") + .getMeanRate(), + equalTo(0.0)); + } + + @Test + public void jobsCounterInc() { + + catcher.jobStarted(new JobStartEvent("10", "test")); + assertThat(registry.counter(this.config.getPrefix() + ".jobs-active-test-count") + .getCount(), + equalTo(0l)); + } + + @Test + public void testErrorCount() { + catcher.error(ErrorCode.medium(10, "hello world")); + assertThat(registry.counter(this.config.getPrefix() + ".error-MEDIUM-10-count") + .getCount(), + equalTo(0l)); + + } + + @Test + public void testErrorMeter() { + catcher.error(ErrorCode.medium(10, "hello world")); + assertThat(registry.meter(this.config.getPrefix() + ".error-MEDIUM-10") + .getMeanRate(), + equalTo(0.00)); + + } + + @Test + public void testSeverityErrorCount() { + catcher.error(ErrorCode.medium(10, "hello world")); + assertThat(registry.counter(this.config.getPrefix() + ".error-severity-MEDIUM-count") + .getCount(), + equalTo(0l)); + + } + + @Test + public void testErrorSeverityMeter() { + catcher.error(ErrorCode.medium(10, "hello world")); + assertThat(registry.meter(this.config.getPrefix() + ".error-severity-MEDIUM") + .getMeanRate(), + equalTo(0.00)); + + } + +} diff --git a/micro-event-metrics/src/test/java/com/oath/micro/server/event/metrics/MetricsCatcherTest.java b/micro-event-metrics/src/test/java/com/oath/micro/server/event/metrics/MetricsCatcherTest.java new file mode 100644 index 000000000..46f027f01 --- /dev/null +++ b/micro-event-metrics/src/test/java/com/oath/micro/server/event/metrics/MetricsCatcherTest.java @@ -0,0 +1,209 @@ +package com.oath.micro.server.event.metrics; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThan; +import static org.junit.Assert.assertThat; + +import com.oath.micro.server.events.GenericEvent; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.errors.ErrorCode; +import com.oath.micro.server.events.JobCompleteEvent; +import com.oath.micro.server.events.JobStartEvent; +import com.oath.micro.server.events.RequestTypes.AddQuery; +import com.oath.micro.server.events.RequestTypes.RemoveQuery; +import com.oath.micro.server.events.RequestTypes.RequestData; +import com.codahale.metrics.MetricRegistry; +import com.google.common.eventbus.EventBus; + +public class MetricsCatcherTest { + + MetricsCatcher catcher; + MetricRegistry registry; + EventBus bus; + Configuration config; + + @Before + public void setup() { + registry = new MetricRegistry(); + bus = new EventBus(); + config = new Configuration( + true, true, true, true, 5, 6, 7, 8, 10,"bob"); + catcher = new MetricsCatcher<>( + registry, bus, config); + } + + @Test + public void queriesStartMeterInc() { + + catcher.requestStart(new AddQuery( + RequestData.builder() + .correlationId("10") + .type("test") + .build())); + assertThat(registry.meter(this.config.getPrefix() + ".request-start-test-meter") + .getMeanRate(), + greaterThan(0.0)); + } + + @Test + public void queriesEndMeterInc() { + + catcher.requestComplete(new RemoveQuery( + RequestData.builder() + .correlationId("10") + .type("test") + .build())); + assertThat(registry.meter(this.config.getPrefix() + ".request-end-test") + .getMeanRate(), + greaterThan(0.0)); + } + + @Test + public void queriesCounterInc() { + + catcher.requestStart(new AddQuery( + RequestData.builder() + .correlationId("10") + .type("test") + .build())); + assertThat(registry.counter(this.config.getPrefix() + ".requests-active-test-count") + .getCount(), + equalTo(1l)); + } + + @Test + public void queriesCounterDec() { + + catcher.requestComplete(new RemoveQuery( + RequestData.builder() + .correlationId("10") + .type("test") + .build())); + assertThat(registry.counter(this.config.getPrefix() + ".requests-active-test-count") + .getCount(), + equalTo(-1l)); + } + + @Test + public void queriesIntervalCounterInc() { + + catcher.requestStart(new AddQuery( + RequestData.builder() + .correlationId("10") + .type("test") + .build())); + assertThat(registry.getGauges().size(), equalTo(2)); + assertThat(registry.getGauges().get(this.config.getPrefix() + ".requests-started-interval-count").getValue(), equalTo(1l)); + assertThat(registry.getGauges().get(this.config.getPrefix() + ".requests-started-test-interval-count").getValue(), equalTo(1l)); + } + + @Test + public void queriesIntervalCounterDec() { + + catcher.requestComplete(new RemoveQuery( + RequestData.builder() + .correlationId("10") + .type("test") + .build())); + assertThat(registry.getGauges().size(), equalTo(2)); + assertThat(registry.getGauges().get(this.config.getPrefix() + ".requests-completed-interval-count").getValue(), + equalTo(1l)); + assertThat(registry.getGauges().get(this.config.getPrefix() + ".requests-completed-test-interval-count").getValue(), + equalTo(1l)); + + } + + @Test + public void jobsCounterDec() { + + catcher.jobComplete(new JobCompleteEvent("10", "test", 10l, 5l)); + assertThat(registry.counter(this.config.getPrefix() + ".jobs-active-test-count") + .getCount(), + equalTo(-1l)); + } + + @Test + public void queriesTimer() { + + catcher.requestStart(new AddQuery(RequestData.builder() + .correlationId("10") + .type("test") + .build())); + + catcher.requestComplete(new RemoveQuery(RequestData.builder() + .correlationId("10") + .type("test") + .build())); + assertThat(registry.timer(this.config.getPrefix() + ".request-end-test-timer") + .getMeanRate(), + greaterThan(0.0)); + } + + @Test + public void jobsMeterInc() { + + catcher.jobStarted(new JobStartEvent("10", "test")); + assertThat(registry.meter(this.config.getPrefix() + ".job-meter-test") + .getMeanRate(), + greaterThan(0.0)); + } + + @Test + public void jobsCounterInc() { + + catcher.jobStarted(new JobStartEvent("10", "test")); + assertThat(registry.counter(this.config.getPrefix() + ".jobs-active-test-count") + .getCount(), + equalTo(1l)); + } + + @Test + public void testErrorCount() { + catcher.error(ErrorCode.medium(10, "hello world")); + assertThat(registry.counter(this.config.getPrefix() + ".error-MEDIUM-10-count") + .getCount(), + equalTo(1l)); + + } + + @Test + public void testErrorMeter() { + catcher.error(ErrorCode.medium(10, "hello world")); + assertThat(registry.meter(this.config.getPrefix() + ".error-MEDIUM-10") + .getMeanRate(), + greaterThan(0.00)); + + } + + @Test + public void testSeverityErrorCount() { + catcher.error(ErrorCode.medium(10, "hello world")); + assertThat(registry.counter(this.config.getPrefix() + ".error-severity-MEDIUM-count") + .getCount(), + equalTo(1l)); + + } + + @Test + public void testErrorSeverityMeter() { + catcher.error(ErrorCode.medium(10, "hello world")); + assertThat(registry.meter(this.config.getPrefix() + ".error-severity-MEDIUM") + .getMeanRate(), + greaterThan(0.00)); + + } + + @Test + public void testGenericEvent() { + GenericEvent.trigger("generic", bus, "data", new String[] {"p1", "p2"}); + assertThat(registry.meter(this.config.getPrefix() + ".event-generic-meter").getCount(), greaterThan(0L)); + assertThat(registry.counter(this.config.getPrefix() + ".event-generic-count").getCount(), greaterThan(0L)); + assertThat(registry.meter(this.config.getPrefix() + ".event-generic.p1-meter").getCount(), greaterThan(0L)); + assertThat(registry.counter(this.config.getPrefix() + ".event-generic.p1-count").getCount(), greaterThan(0L)); + assertThat(registry.meter(this.config.getPrefix() + ".event-generic.p1.p2-meter").getCount(), greaterThan(0L)); + assertThat(registry.counter(this.config.getPrefix() + ".event-generic.p1.p2-count").getCount(), greaterThan(0L)); + } + +} diff --git a/micro-event-metrics/src/test/java/com/oath/micro/server/event/metrics/TimerManagerTest.java b/micro-event-metrics/src/test/java/com/oath/micro/server/event/metrics/TimerManagerTest.java new file mode 100644 index 000000000..176fb5f71 --- /dev/null +++ b/micro-event-metrics/src/test/java/com/oath/micro/server/event/metrics/TimerManagerTest.java @@ -0,0 +1,39 @@ +package com.oath.micro.server.event.metrics; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import com.codahale.metrics.Timer.Context; + +public class TimerManagerTest { + + TimerManager manager; + + @Before + public void setup() { + manager = new TimerManager( + 3, 5); + } + + @Test + public void whenValueNotPresentNoError() { + manager.complete("1"); + } + + @Test + public void whenValueAddedAndRemovedStopCalled() { + Context c = Mockito.mock(Context.class); + manager.start("1", c); + manager.complete("1"); + Mockito.verify(c, Mockito.times(1)) + .stop(); + + } + + @Test + public void when4ValuesAddedFirstIsDropped() { + + } + +} diff --git a/micro-event-metrics/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-event-metrics/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-event-metrics/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-events/README.md b/micro-events/README.md new file mode 100644 index 000000000..4d1460e6b --- /dev/null +++ b/micro-events/README.md @@ -0,0 +1,354 @@ +# Events Plugin + +[micro-events example apps](https://github.com/aol/micro-server/tree/master/micro-events/src/test/java/app) + +This adds a facility to capture events such as requests, request execution and scheduled jobs. + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-events/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-events) + +Simply add to the classpath + +Maven +```xml + + com.oath.microservices + micro-events + x.yz + +``` +Gradle +```groovy + compile 'com.oath.microservices:micro-events:x.yz' +``` +### Depends on + +1. [micro-reactive](https://github.com/aol/micro-server/tree/master/micro-reactive) +2. [micro-guava](https://github.com/aol/micro-server/tree/master/micro-guava) + + +## Properties + +Job names are configurable as either + +* SIMPLE (simple class name) +* PACKAGE (last part of package + simple class name) +* FULL (canononical class name) + +e.g. + + micro.events.job.name.format:SIMPLE + +or + + micro.events.job.name.format:SIMPLE + +## Example resource capturing queries + + ```java +@Component +@Path("/status") +public class EventStatusResource implements RestResource { + + private final EventBus bus; + + @Autowired //micro-events plugin configures a Guava EventBus as a Spring bean + public EventStatusResource(EventBus bus ){ + this.bus = bus; + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + //Post RequestEvents starting + bus.post(RequestEvents.start("get", 1l)); + try{ + return "ok"; + }finally{ + //and RequestEvents finishing + bus.post(RequestEvents.finish("get",1l)); + } + } + +} + ``` + +Active and recently finished events become available at https://hostname::port/context/active/requests + +## Capturing scheduled Jobs + +Any Spring Bean implementing com.aol.micro.server.events.ScheduledJob will have start / completion tracking for the scheduleAndLog() method. +Event details will be added to the eventually consistent ActiveEvents class, and recent & currently active events will be visible via the ActiveResource. + ```java +@Component +public class Job implements ScheduledJob{ + + @Override + public SystemData scheduleAndLog() { + return SystemData.builder().errors(0).processed(2).build(); + } + +} + ``` + +### Job metrics + +Metrics about each job are captured in a SystemData object which will be also posted to a Guava EventBus, to allow custom processors to handle the +completion event, for example, an EventBus listener that posts info to a simple-react Queue or Topic (via the Pipes class in the micro-reactive plugin) +or an RxJava Observable. + + ```java + + public class SystemData { + + private final Integer processed; + private final Integer errors; + private final Map dataMap; + + private SystemData(Integer processed, Integer errors, Map dataMap) { + this.processed = processed; + this.errors = errors; + this.dataMap = dataMap; + } + } +``` +## Subscribing to scheduled job events + +Inject in the micro-events Guava Event Bus to your class as Spring Bean, and implement a method annotated with the Guava @Subscribe annotation that takes SystemData as a single parameter. + + ```java + + public class Subscriber { + @Autowired + public Subsciber(EventBus eventBus){ + bus.register(this); + } + + @Subscribe + public void listenForJobEvents(SystemData data){ + + logsStats(data); + } + + } +``` + +## Capturing Queries + +To capture requests or Queries post a AddQuery event to the configured Guava event bus when the Query starts, and a RemoveQuery event when it finishes. There are static helper methods on the RequestEvents class to help with this. E.g. + ```java + + bus.post(RequestEvents.start("get request", correlationId)); + try{ + return "ok"; + }finally{ + bus.post(RequestEvents.finish("get request",correlationId)); + } +``` +## REST Calls and output + +1. **/active/requests** shows currently active and recently completed requests +2. **/active/jobs** shows currently active and recently completed jobs + +### Active Requests output + ```json + { + "removed": 0, + "added": 1, + "active": { + "1-32": { + "freeMemory": 135573448, + "startedAt": 1438634550597, + "startedAtFormatted": "2015.08.03 at 21:42:30 IST", + "processingThread": 32, + "correlationId": 1, + "query": "get", + "type": "default", + "additionalData": null + } + }, + "events": 1, + "recently-finished": [ + { + "event": { + "freeMemory": 135573448, + "startedAt": 1438634550597, + "startedAtFormatted": "2015.08.03 at 21:42:30 IST", + "processingThread": 32, + "correlationId": 1, + "query": "get", + "type": "default", + "additionalData": null + }, + "completed": 1438634550598, + "completed-formated": "2015.08.03 at 21:42:30 IST", + "time-taken": 1, + "memory-change": 0 + } + ] +} +``` +### Active Jobs output + ```json + { + "removed": 0, + "added": 9304, + "active": { + "id_app.events.com.aol.micro.server.Job-15": { + "freeMemory": 222866800, + "startedAt": 1438634384118, + "startedAtFormatted": "2015.08.03 at 21:39:44 IST", + "processingThread": 15, + "type": "app.events.com.aol.micro.server.Job", + "timesExecuted": 9304 + }, + "id_app.events.com.aol.micro.server.Job-16": { + "freeMemory": 115960832, + "startedAt": 1438634382652, + "startedAtFormatted": "2015.08.03 at 21:39:42 IST", + "processingThread": 16, + "type": "app.events.com.aol.micro.server.Job", + "timesExecuted": 8143 + }, + "id_app.events.com.aol.micro.server.Job-17": { + "freeMemory": 117375880, + "startedAt": 1438634382107, + "startedAtFormatted": "2015.08.03 at 21:39:42 IST", + "processingThread": 17, + "type": "app.events.com.aol.micro.server.Job", + "timesExecuted": 7720 + } + }, + "events": 9304, + "recently-finished": [ + { + "event": { + "freeMemory": 220814872, + "startedAt": 1438634371998, + "startedAtFormatted": "2015.08.03 at 21:39:31 IST", + "processingThread": 16, + "type": "app.events.com.aol.micro.server.Job", + "timesExecuted": 9 + }, + "completed": 1438634371999, + "completed-formated": "2015.08.03 at 21:39:31 IST", + "time-taken": 1, + "memory-change": -447624 + }, + { + "event": { + "freeMemory": 221845600, + "startedAt": 1438634371996, + "startedAtFormatted": "2015.08.03 at 21:39:31 IST", + "processingThread": 16, + "type": "app.events.com.aol.micro.server.Job", + "timesExecuted": 8 + }, + "completed": 1438634371996, + "completed-formated": "2015.08.03 at 21:39:31 IST", + "time-taken": 0, + "memory-change": 0 + }, + { + "event": { + "freeMemory": 222293016, + "startedAt": 1438634371992, + "startedAtFormatted": "2015.08.03 at 21:39:31 IST", + "processingThread": 16, + "type": "app.events.com.aol.micro.server.Job", + "timesExecuted": 7 + }, + "completed": 1438634371992, + "completed-formated": "2015.08.03 at 21:39:31 IST", + "time-taken": 0, + "memory-change": 0 + }, + { + "event": { + "freeMemory": 222740728, + "startedAt": 1438634371988, + "startedAtFormatted": "2015.08.03 at 21:39:31 IST", + "processingThread": 16, + "type": "app.events.com.aol.micro.server.Job", + "timesExecuted": 6 + }, + "completed": 1438634371989, + "completed-formated": "2015.08.03 at 21:39:31 IST", + "time-taken": 1, + "memory-change": 0 + }, + { + "event": { + "freeMemory": 222753672, + "startedAt": 1438634371985, + "startedAtFormatted": "2015.08.03 at 21:39:31 IST", + "processingThread": 16, + "type": "app.events.com.aol.micro.server.Job", + "timesExecuted": 5 + }, + "completed": 1438634371985, + "completed-formated": "2015.08.03 at 21:39:31 IST", + "time-taken": 0, + "memory-change": 0 + }, + { + "event": { + "freeMemory": 222753704, + "startedAt": 1438634371982, + "startedAtFormatted": "2015.08.03 at 21:39:31 IST", + "processingThread": 16, + "type": "app.events.com.aol.micro.server.Job", + "timesExecuted": 4 + }, + "completed": 1438634371982, + "completed-formated": "2015.08.03 at 21:39:31 IST", + "time-taken": 0, + "memory-change": 0 + }, + { + "event": { + "freeMemory": 222753704, + "startedAt": 1438634371979, + "startedAtFormatted": "2015.08.03 at 21:39:31 IST", + "processingThread": 16, + "type": "app.events.com.aol.micro.server.Job", + "timesExecuted": 3 + }, + "completed": 1438634371979, + "completed-formated": "2015.08.03 at 21:39:31 IST", + "time-taken": 0, + "memory-change": 0 + }, + { + "event": { + "freeMemory": 223648616, + "startedAt": 1438634371977, + "startedAtFormatted": "2015.08.03 at 21:39:31 IST", + "processingThread": 15, + "type": "app.events.com.aol.micro.server.Job", + "timesExecuted": 2 + }, + "completed": 1438634371977, + "completed-formated": "2015.08.03 at 21:39:31 IST", + "time-taken": 0, + "memory-change": 0 + }, + { + "event": { + "freeMemory": 226284664, + "startedAt": 1438634371955, + "startedAtFormatted": "2015.08.03 at 21:39:31 IST", + "processingThread": 15, + "type": "app.events.com.aol.micro.server.Job", + "timesExecuted": 1 + }, + "completed": 1438634371965, + "completed-formated": "2015.08.03 at 21:39:31 IST", + "time-taken": 10, + "memory-change": -894784 + } + ] +} +``` diff --git a/micro-events/build.gradle b/micro-events/build.gradle index 49fb8c4ab..4bc98e0db 100644 --- a/micro-events/build.gradle +++ b/micro-events/build.gradle @@ -1,58 +1,59 @@ description = 'micro-events' + dependencies { - compile project(':micro-core') - compile project(':micro-guava') - testCompile group: 'org.hamcrest', name: 'hamcrest-all', version:hamcrestVersion - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') + compile project(':micro-core') + compile project(':micro-guava') + testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: hamcrestVersion + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') } modifyPom { - project { - name 'Microserver events' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-events' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - } - - } + project { + name 'Microserver events' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-events' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-events/readme.md b/micro-events/readme.md deleted file mode 100644 index 084961c54..000000000 --- a/micro-events/readme.md +++ /dev/null @@ -1,337 +0,0 @@ -# Events Plugin - -[micro-events example apps](https://github.com/aol/micro-server/tree/master/micro-events/src/test/java/app) - -This adds a facility to capture events such as requests, request execution and scheduled jobs. - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-events/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-events) - -Simply add to the classpath - -Maven -```xml - - com.aol.microservices - micro-events - x.yz - -``` -Gradle -```groovy - compile 'com.aol.microservices:micro-events:x.yz' -``` -### Depends on - -1. [micro-reactive](https://github.com/aol/micro-server/tree/master/micro-reactive) -2. [micro-guava](https://github.com/aol/micro-server/tree/master/micro-guava) - -## Example resource capturing queries - - ```java -@Component -@Path("/status") -public class EventStatusResource implements RestResource { - - private final EventBus bus; - - @Autowired //micro-events plugin configures a Guava EventBus as a Spring bean - public EventStatusResource(EventBus bus ){ - this.bus = bus; - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - //Post RequestEvents starting - bus.post(RequestEvents.start("get", 1l)); - try{ - return "ok"; - }finally{ - //and RequestEvents finishing - bus.post(RequestEvents.finish("get",1l)); - } - } - -} - ``` - -Active and recently finished events become available at https://hostname::port/context/active/requests - -## Capturing scheduled Jobs - -Any Spring Bean implementing com.aol.micro.server.events.ScheduledJob will have start / completion tracking for the scheduleAndLog() method. -Event details will be added to the eventually consistent ActiveEvents class, and recent & currently active events will be visible via the ActiveResource. - ```java -@Component -public class Job implements ScheduledJob{ - - @Override - public SystemData scheduleAndLog() { - return SystemData.builder().errors(0).processed(2).build(); - } - -} - ``` - -### Job metrics - -Metrics about each job are captured in a SystemData object which will be also posted to a Guava EventBus, to allow custom processors to handle the -completion event, for example, an EventBus listener that posts info to a simple-react Queue or Topic (via the Pipes class in the micro-reactive plugin) -or an RxJava Observable. - - ```java - - public class SystemData { - - private final Integer processed; - private final Integer errors; - private final Map dataMap; - - private SystemData(Integer processed, Integer errors, Map dataMap) { - this.processed = processed; - this.errors = errors; - this.dataMap = dataMap; - } - } -``` -## Subscribing to scheduled job events - -Inject in the micro-events Guava Event Bus to your class as Spring Bean, and implement a method annotated with the Guava @Subscribe annotation that takes SystemData as a single parameter. - - ```java - - public class Subscriber { - @Autowired - public Subsciber(EventBus eventBus){ - bus.register(this); - } - - @Subscribe - public void listenForJobEvents(SystemData data){ - - logsStats(data); - } - - } -``` - -## Capturing Queries - -To capture requests or Queries post a AddQuery event to the configured Guava event bus when the Query starts, and a RemoveQuery event when it finishes. There are static helper methods on the RequestEvents class to help with this. E.g. - ```java - - bus.post(RequestEvents.start("get request", correlationId)); - try{ - return "ok"; - }finally{ - bus.post(RequestEvents.finish("get request",correlationId)); - } -``` -## REST Calls and output - -1. **/active/requests** shows currently active and recently completed requests -2. **/active/jobs** shows currently active and recently completed jobs - -### Active Requests output - ```json - { - "removed": 0, - "added": 1, - "active": { - "1-32": { - "freeMemory": 135573448, - "startedAt": 1438634550597, - "startedAtFormatted": "2015.08.03 at 21:42:30 IST", - "processingThread": 32, - "correlationId": 1, - "query": "get", - "type": "default", - "additionalData": null - } - }, - "events": 1, - "recently-finished": [ - { - "event": { - "freeMemory": 135573448, - "startedAt": 1438634550597, - "startedAtFormatted": "2015.08.03 at 21:42:30 IST", - "processingThread": 32, - "correlationId": 1, - "query": "get", - "type": "default", - "additionalData": null - }, - "completed": 1438634550598, - "completed-formated": "2015.08.03 at 21:42:30 IST", - "time-taken": 1, - "memory-change": 0 - } - ] -} -``` -### Active Jobs output - ```json - { - "removed": 0, - "added": 9304, - "active": { - "id_app.events.com.aol.micro.server.Job-15": { - "freeMemory": 222866800, - "startedAt": 1438634384118, - "startedAtFormatted": "2015.08.03 at 21:39:44 IST", - "processingThread": 15, - "type": "app.events.com.aol.micro.server.Job", - "timesExecuted": 9304 - }, - "id_app.events.com.aol.micro.server.Job-16": { - "freeMemory": 115960832, - "startedAt": 1438634382652, - "startedAtFormatted": "2015.08.03 at 21:39:42 IST", - "processingThread": 16, - "type": "app.events.com.aol.micro.server.Job", - "timesExecuted": 8143 - }, - "id_app.events.com.aol.micro.server.Job-17": { - "freeMemory": 117375880, - "startedAt": 1438634382107, - "startedAtFormatted": "2015.08.03 at 21:39:42 IST", - "processingThread": 17, - "type": "app.events.com.aol.micro.server.Job", - "timesExecuted": 7720 - } - }, - "events": 9304, - "recently-finished": [ - { - "event": { - "freeMemory": 220814872, - "startedAt": 1438634371998, - "startedAtFormatted": "2015.08.03 at 21:39:31 IST", - "processingThread": 16, - "type": "app.events.com.aol.micro.server.Job", - "timesExecuted": 9 - }, - "completed": 1438634371999, - "completed-formated": "2015.08.03 at 21:39:31 IST", - "time-taken": 1, - "memory-change": -447624 - }, - { - "event": { - "freeMemory": 221845600, - "startedAt": 1438634371996, - "startedAtFormatted": "2015.08.03 at 21:39:31 IST", - "processingThread": 16, - "type": "app.events.com.aol.micro.server.Job", - "timesExecuted": 8 - }, - "completed": 1438634371996, - "completed-formated": "2015.08.03 at 21:39:31 IST", - "time-taken": 0, - "memory-change": 0 - }, - { - "event": { - "freeMemory": 222293016, - "startedAt": 1438634371992, - "startedAtFormatted": "2015.08.03 at 21:39:31 IST", - "processingThread": 16, - "type": "app.events.com.aol.micro.server.Job", - "timesExecuted": 7 - }, - "completed": 1438634371992, - "completed-formated": "2015.08.03 at 21:39:31 IST", - "time-taken": 0, - "memory-change": 0 - }, - { - "event": { - "freeMemory": 222740728, - "startedAt": 1438634371988, - "startedAtFormatted": "2015.08.03 at 21:39:31 IST", - "processingThread": 16, - "type": "app.events.com.aol.micro.server.Job", - "timesExecuted": 6 - }, - "completed": 1438634371989, - "completed-formated": "2015.08.03 at 21:39:31 IST", - "time-taken": 1, - "memory-change": 0 - }, - { - "event": { - "freeMemory": 222753672, - "startedAt": 1438634371985, - "startedAtFormatted": "2015.08.03 at 21:39:31 IST", - "processingThread": 16, - "type": "app.events.com.aol.micro.server.Job", - "timesExecuted": 5 - }, - "completed": 1438634371985, - "completed-formated": "2015.08.03 at 21:39:31 IST", - "time-taken": 0, - "memory-change": 0 - }, - { - "event": { - "freeMemory": 222753704, - "startedAt": 1438634371982, - "startedAtFormatted": "2015.08.03 at 21:39:31 IST", - "processingThread": 16, - "type": "app.events.com.aol.micro.server.Job", - "timesExecuted": 4 - }, - "completed": 1438634371982, - "completed-formated": "2015.08.03 at 21:39:31 IST", - "time-taken": 0, - "memory-change": 0 - }, - { - "event": { - "freeMemory": 222753704, - "startedAt": 1438634371979, - "startedAtFormatted": "2015.08.03 at 21:39:31 IST", - "processingThread": 16, - "type": "app.events.com.aol.micro.server.Job", - "timesExecuted": 3 - }, - "completed": 1438634371979, - "completed-formated": "2015.08.03 at 21:39:31 IST", - "time-taken": 0, - "memory-change": 0 - }, - { - "event": { - "freeMemory": 223648616, - "startedAt": 1438634371977, - "startedAtFormatted": "2015.08.03 at 21:39:31 IST", - "processingThread": 15, - "type": "app.events.com.aol.micro.server.Job", - "timesExecuted": 2 - }, - "completed": 1438634371977, - "completed-formated": "2015.08.03 at 21:39:31 IST", - "time-taken": 0, - "memory-change": 0 - }, - { - "event": { - "freeMemory": 226284664, - "startedAt": 1438634371955, - "startedAtFormatted": "2015.08.03 at 21:39:31 IST", - "processingThread": 15, - "type": "app.events.com.aol.micro.server.Job", - "timesExecuted": 1 - }, - "completed": 1438634371965, - "completed-formated": "2015.08.03 at 21:39:31 IST", - "time-taken": 10, - "memory-change": -894784 - } - ] -} -``` diff --git a/micro-events/src/main/java/com/aol/micro/server/events/ActiveEvents.java b/micro-events/src/main/java/com/aol/micro/server/events/ActiveEvents.java deleted file mode 100644 index bc697b9d2..000000000 --- a/micro-events/src/main/java/com/aol/micro/server/events/ActiveEvents.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.aol.micro.server.events; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Deque; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.concurrent.atomic.AtomicInteger; - -import com.aol.micro.server.rest.jackson.JacksonUtil; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; - -public class ActiveEvents { - - private final Map active = new ConcurrentHashMap<>(); - private final Deque recentlyFinished= new ConcurrentLinkedDeque<>(); - private final AtomicInteger events = new AtomicInteger(0); - private final AtomicInteger added = new AtomicInteger(0); - private final AtomicInteger removed = new AtomicInteger(0); - - public void active(String key, T data) { - active.put(key, data); - events.incrementAndGet(); - added.incrementAndGet(); - } - public void finished(String key) { - finished(key,ImmutableMap.of()); - } - public void finished(String key, ImmutableMap data) { - recentlyFinished.push(wrapInMap(active.get(key), data)); - active.remove(key); - removed.incrementAndGet(); - - if(recentlyFinished.size()>10) - synchronized (this) { - if(recentlyFinished.size()>10) - recentlyFinished.pollFirst(); - } - } - - private Map wrapInMap(T event, ImmutableMap data){ - Long time = System.currentTimeMillis(); - DateFormat format = new SimpleDateFormat("yyyy.MM.dd 'at' HH:mm:ss z"); - String formatted = format.format(time); - String change = Optional.ofNullable(event).map(e -> - Long.toString(Runtime.getRuntime().freeMemory() - e.getFreeMemory())).orElse("unknown"); - - return ImmutableMap.builder().putAll(data) - .putAll(ImmutableMap.of("event",event,"completed",time,"completed-formated",formatted,"time-taken",time-event.getStartedAt() - ,"memory-change",change )).build(); - } - /* - * We don't want to expose the active map externally as access would not be thread safe - * - * */ - public String toString(){ - Map result = toMap(); - return JacksonUtil.serializeToJson(result); - } - - private Map toMap() { - Map result = Maps.newHashMap(); - result.put("events", events.get()); - result.put("active", active); - result.put("added",added.get()); - result.put("removed",removed.get()); - result.put("recently-finished", recentlyFinished); - return result; - } - - public int events(){ - return events.get(); - } - - public int size() { - return active.size(); - } -} diff --git a/micro-events/src/main/java/com/aol/micro/server/events/ConfigureActiveJobsAspect.java b/micro-events/src/main/java/com/aol/micro/server/events/ConfigureActiveJobsAspect.java deleted file mode 100644 index 522d460fb..000000000 --- a/micro-events/src/main/java/com/aol/micro/server/events/ConfigureActiveJobsAspect.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.aol.micro.server.events; - -import javax.annotation.Resource; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import com.google.common.eventbus.EventBus; - -@Configuration -public class ConfigureActiveJobsAspect { - @Resource(name="microserverEventBus") - private EventBus bus; - private @Value("${system.logging.max.per.hour:10}") int maxLoggingCapacity; - private @Value("${system.request.capture:true}") boolean requestCapture; - - - @Bean - public JobsBeingExecuted jobsBeingExecuted(){ - return new JobsBeingExecuted(bus, maxLoggingCapacity); - } - - @Bean - public RequestsBeingExecuted requestsBeingExecuted(){ - return new RequestsBeingExecuted(bus,requestCapture); - } - - -} diff --git a/micro-events/src/main/java/com/aol/micro/server/events/JobsBeingExecuted.java b/micro-events/src/main/java/com/aol/micro/server/events/JobsBeingExecuted.java deleted file mode 100644 index f8dfe9b0d..000000000 --- a/micro-events/src/main/java/com/aol/micro/server/events/JobsBeingExecuted.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.aol.micro.server.events; - -import java.util.Optional; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; - -import com.google.common.collect.ConcurrentHashMultiset; -import com.google.common.eventbus.EventBus; - -@Aspect -public class JobsBeingExecuted { - - private final ActiveEvents events = new ActiveEvents(); - @Getter(AccessLevel.PACKAGE) - private final ConcurrentHashMultiset statCounter = ConcurrentHashMultiset.create(); - private final EventBus eventBus; - - private final LoggingRateLimiter loggingRateLimiter; - - private final int maxLoggingCapacity; - - - public JobsBeingExecuted(@Qualifier("microserverEventBus") EventBus bus, - @Value("${system.logging.max.per.hour:10}") int maxLoggingCapacity) { - this.eventBus = bus; - this.loggingRateLimiter = new LoggingRateLimiter<>(); - this.maxLoggingCapacity = maxLoggingCapacity; - } - public JobsBeingExecuted(EventBus bus){ - this(bus,10); - } - - @Around("execution(* com.aol.micro.server.events.ScheduledJob.scheduleAndLog(..))") - public Object aroundScheduledJob(ProceedingJoinPoint pjp) throws Throwable { - String type = pjp.getSignature().getDeclaringType().getName(); - - return executeScheduledJob(pjp, type); - - } - - public int size() { - return events.size(); - } - - public int events() { - return events.events(); - } - - public String toString() { - return events.toString(); - } - - - private Object executeScheduledJob(final ProceedingJoinPoint pjp, final String type) throws Throwable { - addTypeToStatCounter(type); - JobExecutingData data = new JobExecutingData(type, statCounter.count(type)); - String id = buildId(type, data.getProcessingThread()); - events.active(id, data); - - - SystemData retVal = null; - try { - retVal = Optional.ofNullable(((SystemData) pjp.proceed())) - .map(sd ->sd.withCorrelationId(id)) - .orElse(null); - return retVal; - } finally { - logSystemEvent(pjp, type, data, retVal); - } - } - private void logSystemEvent(final ProceedingJoinPoint pjp, final String type, JobExecutingData data, - SystemData retVal) { - final SystemData active = retVal; - loggingRateLimiter.addAndEnsureFrequency(pjp.getTarget().getClass()); - loggingRateLimiter.capacityAvailable((Class)pjp.getTarget().getClass(),10, new Runnable() { - public void run(){ - postEvent(pjp, type, data, active); - }}); - } - - private void postEvent(ProceedingJoinPoint pjp, String type, JobExecutingData data, SystemData retVal) { - if (retVal != null) { - - eventBus.post(retVal); - } - events.finished(buildId(type, data.getProcessingThread())); - } - - private void addTypeToStatCounter(String type) { - try { - statCounter.add(type); - } catch (Exception e) { - statCounter.clear(); - statCounter.add(type); - } - } - - private String buildId(String type, long threadId) { - return "id_" + type + "-" + threadId; - } - - @AllArgsConstructor - @XmlAccessorType(XmlAccessType.FIELD) - static class JobExecutingData extends BaseEventInfo { - private final String type; - private final int timesExecuted; - } -} diff --git a/micro-events/src/main/java/com/aol/micro/server/events/LoggingRateLimiter.java b/micro-events/src/main/java/com/aol/micro/server/events/LoggingRateLimiter.java deleted file mode 100644 index e1ad29fa8..000000000 --- a/micro-events/src/main/java/com/aol/micro/server/events/LoggingRateLimiter.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.aol.micro.server.events; - -import java.util.Date; - -import lombok.AccessLevel; -import lombok.Getter; - -import com.google.common.collect.ConcurrentHashMultiset; - - -public class LoggingRateLimiter { - - @Getter(AccessLevel.PACKAGE) - private volatile ConcurrentHashMultiset frequency = ConcurrentHashMultiset.create(); - private volatile Date lastCleared = new Date(0); - private final int limit; - - public LoggingRateLimiter(int limit){ - this.limit = limit; - } - - public LoggingRateLimiter(){ - this.limit=(60 *1000*60); - } - - public void addAndEnsureFrequency(T clazz){ - resetAfterLimit(); - frequency.add(clazz); - } - public void resetAfterLimit(){ - if (System.currentTimeMillis() - limit > lastCleared.getTime()){ - frequency = ConcurrentHashMultiset.create(); - lastCleared = new Date(System.currentTimeMillis()); - } - - } - - public void capacityAvailable(T t, int max, Runnable run){ - if(frequency.count(t) < max) - run.run(); - - } - -} diff --git a/micro-events/src/main/java/com/aol/micro/server/events/RequestEvents.java b/micro-events/src/main/java/com/aol/micro/server/events/RequestEvents.java deleted file mode 100644 index 1bd546fce..000000000 --- a/micro-events/src/main/java/com/aol/micro/server/events/RequestEvents.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.aol.micro.server.events; - -import com.aol.micro.server.events.RequestsBeingExecuted.AddQuery; -import com.aol.micro.server.events.RequestsBeingExecuted.RemoveQuery; -import com.aol.micro.server.events.RequestsBeingExecuted.RequestData; - -/** - * Factory class for creating Start and End events - * - * @author johnmcclean - * - */ -public class RequestEvents { - - /** - * Marks the start of a query identified by the provided correlationId - * - * @param query - Query data - * @param correlationId - Identifier - * @return Start event to pass to the Events systems EventBus - */ - public static AddQuery start(T query, long correlationId){ - return start(query, correlationId,"default",null); - } - /** - * Marks the start of a query identified by the provided correlationId, with additional query type and data parameters - * - * @param query - Query data - * @param correlationId - Identifier - * @param type - allows queries to be grouped by type - * @param additionalData - Any additional info about the reques to be rendered in the JSON view / rest endpoint - * @return Start event to pass to the Events systems EventBus - */ - public static AddQuery start(T query, long correlationId, String type, Object additionalData){ - - return new AddQuery(RequestData.builder().query(query).correlationId(correlationId) - .type(type).additionalData(additionalData).build()); - } - /** - * Marks the end of a query identified by the provided correlationId - * - * @param query - Query data - * @param correlationId - Identifier - * @return Finish event to pass to the Events systems EventBus - */ - public static RemoveQuery finish(T query, long correlationId){ - return finish(query,correlationId,"default"); - } - /** - * Marks the end of a query identified by the provided correlationId - * - * @param query - Query data - * @param correlationId - Identifier - * @param type - allows queries to be grouped by type - * @return - */ - public static RemoveQuery finish(T query, long correlationId, String type){ - - return new RemoveQuery<>(RequestData.builder().query(query).correlationId(correlationId) - .type(type).build()); - } - -} diff --git a/micro-events/src/main/java/com/aol/micro/server/events/RequestsBeingExecuted.java b/micro-events/src/main/java/com/aol/micro/server/events/RequestsBeingExecuted.java deleted file mode 100644 index f73d73159..000000000 --- a/micro-events/src/main/java/com/aol/micro/server/events/RequestsBeingExecuted.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.aol.micro.server.events; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -import org.springframework.beans.factory.annotation.Qualifier; - -import com.google.common.eventbus.EventBus; -import com.google.common.eventbus.Subscribe; - - -public class RequestsBeingExecuted { - - private final EventBus bus; - private final ActiveEvents> events = new ActiveEvents(); - @Getter - private final String type; - - - public RequestsBeingExecuted(@Qualifier("microserverEventBus") EventBus bus, boolean queryCapture){ - this.bus = bus; - this.type = "default"; - if(queryCapture) - bus.register(this); - - } - - public RequestsBeingExecuted(EventBus bus, String type){ - this.bus = bus; - this.type = type; - bus.register(this); - - } - - public int events(){ - return events.events(); - } - - public int size(){ - return events.size(); - } - - public String toString(){ - return events.toString(); - } - @Subscribe - public void finished(RemoveQuery data) { - if(type.equals(data.getData().type)) - events.finished(buildId(data.getData())); - - } - @Subscribe - public void processing(AddQuery data) { - if(type.equals(data.getData().type)){ - String id = buildId(data.getData()); - events.active(id, data.getData()); - } - - } - - - private String buildId(RequestData data) { - String id = ""+data.correlationId; - return id; - } - - - public static class AddQuery extends AddEvent>{ - - public AddQuery(RequestData data) { - super(data); - } - - } - - public static class RemoveQuery extends RemoveEvent>{ - - public RemoveQuery(RequestData data) { - super(data); - } - - } - - - @AllArgsConstructor - @Builder - @XmlAccessorType(XmlAccessType.FIELD) - static class RequestData extends BaseEventInfo { - - private final long correlationId; - - private final T query; - - private final String type; - private final Object additionalData; - } - -} diff --git a/micro-events/src/main/java/com/aol/micro/server/events/ScheduledJob.java b/micro-events/src/main/java/com/aol/micro/server/events/ScheduledJob.java deleted file mode 100644 index 3c96f7e59..000000000 --- a/micro-events/src/main/java/com/aol/micro/server/events/ScheduledJob.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.aol.micro.server.events; - - - -public interface ScheduledJob { - SystemData scheduleAndLog(); -} diff --git a/micro-events/src/main/java/com/aol/micro/server/events/StartedAt.java b/micro-events/src/main/java/com/aol/micro/server/events/StartedAt.java deleted file mode 100644 index 5ee00c046..000000000 --- a/micro-events/src/main/java/com/aol/micro/server/events/StartedAt.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.aol.micro.server.events; - -public interface StartedAt { - - public long getStartedAt(); -} diff --git a/micro-events/src/main/java/com/aol/micro/server/events/SystemData.java b/micro-events/src/main/java/com/aol/micro/server/events/SystemData.java deleted file mode 100644 index 404a3ac13..000000000 --- a/micro-events/src/main/java/com/aol/micro/server/events/SystemData.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aol.micro.server.events; - - - -import java.util.Map; -import java.util.Random; - -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.ToString; -import lombok.experimental.Builder; -import lombok.experimental.Wither; - -@Builder -@Wither -@AllArgsConstructor -@Getter -@ToString -@EqualsAndHashCode(of={"correlationId"}) -public class SystemData { - - private static final Random r = new Random(); - private final Integer processed; - private final Integer errors; - private final Map dataMap; - private String correlationId; - - private SystemData(Integer processed, Integer errors, Map dataMap) { - this.processed = processed; - this.errors = errors; - this.dataMap = dataMap; - this.correlationId="" + r.nextLong(); - } -} diff --git a/micro-events/src/main/java/com/aol/micro/server/events/plugin/EventsPlugin.java b/micro-events/src/main/java/com/aol/micro/server/events/plugin/EventsPlugin.java deleted file mode 100644 index 901ba2210..000000000 --- a/micro-events/src/main/java/com/aol/micro/server/events/plugin/EventsPlugin.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.aol.micro.server.events.plugin; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.events.ConfigureActiveJobsAspect; -import com.aol.micro.server.rest.resources.ConfigureResources; - - -/** - * - * Collections of Spring configuration classes (Classes annotated with @Configuration) - * that configure various useful pieces of functionality - such as property file loading, - * datasources, scheduling etc - * - * @author johnmcclean - * - */ -public class EventsPlugin implements Plugin{ - - @Override - public PSetX springClasses() { - return PSetX.of( - ConfigureActiveJobsAspect.class, - ConfigureResources.class); - } - - - -} diff --git a/micro-events/src/main/java/com/aol/micro/server/rest/resources/ActiveResource.java b/micro-events/src/main/java/com/aol/micro/server/rest/resources/ActiveResource.java deleted file mode 100644 index 88a906846..000000000 --- a/micro-events/src/main/java/com/aol/micro/server/rest/resources/ActiveResource.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.aol.micro.server.rest.resources; - -import java.util.List; -import java.util.Map; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.container.Suspended; - -import org.springframework.beans.factory.annotation.Autowired; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.micro.server.WorkerThreads; -import com.aol.micro.server.auto.discovery.CommonRestResource; -import com.aol.micro.server.auto.discovery.SingletonRestResource; -import com.aol.micro.server.events.JobsBeingExecuted; -import com.aol.micro.server.events.RequestsBeingExecuted; -import com.google.common.collect.Maps; - - - -@Path("/active") -public class ActiveResource implements CommonRestResource, SingletonRestResource { - - private static final Object LOG_LEVEL = null; - private final Map activeQueries; - private final JobsBeingExecuted activeJobs; - private Long entityIds; - - @Autowired - public ActiveResource(List activeQueries,JobsBeingExecuted activeJobs) { - Map map = Maps.newHashMap(); - for(RequestsBeingExecuted next: activeQueries){ - map.put(next.getType(),next); - } - this.activeQueries = map; - this.activeJobs = activeJobs; - } - - - @GET - @Produces("application/json") - @Path("/requests") - public void activeRequests(@Suspended AsyncResponse asyncResponse,@QueryParam("type") final String type) { - - ReactiveSeq.of((type == null ? "default" : type)) - .map(typeToUse->activeQueries.get(typeToUse).toString()) - .futureOperations(WorkerThreads.ioExecutor.get()) - .forEach(result->asyncResponse.resume(result)); - - } - - - - @GET - @Produces("application/json") - @Path("/jobs") - public void activeJobs(@Suspended AsyncResponse asyncResponse) { - - ReactiveSeq.of(this.activeJobs) - .map(JobsBeingExecuted::toString) - .futureOperations(WorkerThreads.ioExecutor.get()) - .forEach(str->asyncResponse.resume(str)); - - - } - - - - -} diff --git a/micro-events/src/main/java/com/aol/micro/server/rest/resources/ConfigureResources.java b/micro-events/src/main/java/com/aol/micro/server/rest/resources/ConfigureResources.java deleted file mode 100644 index db8c501c7..000000000 --- a/micro-events/src/main/java/com/aol/micro/server/rest/resources/ConfigureResources.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.aol.micro.server.rest.resources; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import com.aol.micro.server.events.JobsBeingExecuted; -import com.aol.micro.server.events.RequestsBeingExecuted; - -@Configuration -public class ConfigureResources { - - @Autowired - private List activeQueries; - - @Bean - public ActiveResource activeResource(@Qualifier("jobsBeingExecuted") JobsBeingExecuted jobsBeingExecuted) { - return new ActiveResource(activeQueries, jobsBeingExecuted); - } - - @Bean - public ManifestResource manifest() { - return new ManifestResource(); - } -} diff --git a/micro-events/src/main/java/com/aol/micro/server/rest/resources/ManifestResource.java b/micro-events/src/main/java/com/aol/micro/server/rest/resources/ManifestResource.java deleted file mode 100644 index 56869045b..000000000 --- a/micro-events/src/main/java/com/aol/micro/server/rest/resources/ManifestResource.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.aol.micro.server.rest.resources; - -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.jar.Attributes; -import java.util.jar.Manifest; - -import javax.servlet.ServletContext; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.container.Suspended; -import javax.ws.rs.core.Context; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.micro.server.WorkerThreads; -import com.aol.micro.server.auto.discovery.CommonRestResource; -import com.aol.micro.server.auto.discovery.SingletonRestResource; - -@Path("/manifest") -@Component -public class ManifestResource implements CommonRestResource, SingletonRestResource{ - - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - - - @GET - @Produces("application/json") - public void mainfest(@Suspended AsyncResponse asyncResponse, @Context ServletContext context) { - - ReactiveSeq.of("/META-INF/MANIFEST.MF") - .map(url->context.getResourceAsStream(url)) - .map(this::getManifest) - .futureOperations(WorkerThreads.ioExecutor.get()) - .forEach(result->asyncResponse.resume(result)); - - - } - - - public Map getManifest(final InputStream input) { - - final Map retMap = new HashMap(); - try { - Manifest manifest = new Manifest(); - manifest.read(input); - final Attributes attributes = manifest.getMainAttributes(); - for (final Map.Entry attribute : attributes.entrySet()) { - retMap.put(attribute.getKey().toString(), attribute.getValue().toString()); - } - } catch (final Exception ex) { - logger.error( "Failed to load manifest ", ex); - } - - return retMap; - } - -} \ No newline at end of file diff --git a/micro-events/src/main/java/com/oath/micro/server/events/ActiveEvents.java b/micro-events/src/main/java/com/oath/micro/server/events/ActiveEvents.java new file mode 100644 index 000000000..86b0adfc4 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/ActiveEvents.java @@ -0,0 +1,92 @@ +package com.oath.micro.server.events; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Deque; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.atomic.AtomicInteger; + +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; + +public class ActiveEvents { + + private final Map active = new ConcurrentHashMap<>(); + private final Deque recentlyFinished = new ConcurrentLinkedDeque<>(); + private final AtomicInteger events = new AtomicInteger(0); + private final AtomicInteger added = new AtomicInteger(0); + private final AtomicInteger removed = new AtomicInteger(0); + + public void active(String key, T data) { + active.put(key, data); + events.incrementAndGet(); + added.incrementAndGet(); + } + + public void finished(String key) { + finished(key, ImmutableMap.of()); + } + + public void finished(String key, ImmutableMap data) { + recentlyFinished.push(wrapInMap(active.get(key), data)); + active.remove(key); + removed.incrementAndGet(); + + if (recentlyFinished.size() > 10) + synchronized (this) { + if (recentlyFinished.size() > 10) + recentlyFinished.pollFirst(); + } + } + + private Map wrapInMap(T event, ImmutableMap data) { + Long time = System.currentTimeMillis(); + DateFormat format = new SimpleDateFormat("yyyy.MM.dd 'at' HH:mm:ss z"); + String formatted = format.format(time); + String change = Optional.ofNullable(event) + .map(e -> Long.toString(Runtime.getRuntime().freeMemory() - e.getFreeMemory())).orElse("unknown"); + + ImmutableMap map = ImmutableMap.of("completed", time, "completed-formated", formatted, "memory-change", change); + + ImmutableMap.Builder builder = ImmutableMap.builder().putAll(data).putAll(map); + + if (event != null) { + builder.put("event", event); + builder.put("time-taken", time - event.getStartedAt()); + } + return builder.build(); + } + + /* + * We don't want to expose the active map externally as access would not be + * thread safe + * + */ + @Override + public String toString() { + Map result = toMap(); + return JacksonUtil.serializeToJson(result); + } + + Map toMap() { + Map result = Maps.newHashMap(); + result.put("events", events.get()); + result.put("active", active); + result.put("added", added.get()); + result.put("removed", removed.get()); + result.put("recently-finished", recentlyFinished); + return result; + } + + public int events() { + return events.get(); + } + + public int size() { + return active.size(); + } +} diff --git a/micro-events/src/main/java/com/aol/micro/server/events/AddEvent.java b/micro-events/src/main/java/com/oath/micro/server/events/AddEvent.java similarity index 79% rename from micro-events/src/main/java/com/aol/micro/server/events/AddEvent.java rename to micro-events/src/main/java/com/oath/micro/server/events/AddEvent.java index 5405351ec..b4d6f8bf6 100644 --- a/micro-events/src/main/java/com/aol/micro/server/events/AddEvent.java +++ b/micro-events/src/main/java/com/oath/micro/server/events/AddEvent.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.events; +package com.oath.micro.server.events; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/micro-events/src/main/java/com/aol/micro/server/events/BaseEventInfo.java b/micro-events/src/main/java/com/oath/micro/server/events/BaseEventInfo.java similarity index 93% rename from micro-events/src/main/java/com/aol/micro/server/events/BaseEventInfo.java rename to micro-events/src/main/java/com/oath/micro/server/events/BaseEventInfo.java index 6d8a5a329..065e140df 100644 --- a/micro-events/src/main/java/com/aol/micro/server/events/BaseEventInfo.java +++ b/micro-events/src/main/java/com/oath/micro/server/events/BaseEventInfo.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.events; +package com.oath.micro.server.events; import java.text.DateFormat; import java.text.SimpleDateFormat; diff --git a/micro-events/src/main/java/com/oath/micro/server/events/ConfigureActiveJobsAspect.java b/micro-events/src/main/java/com/oath/micro/server/events/ConfigureActiveJobsAspect.java new file mode 100644 index 000000000..e5b87e019 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/ConfigureActiveJobsAspect.java @@ -0,0 +1,40 @@ +package com.oath.micro.server.events; + +import javax.annotation.Resource; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.google.common.eventbus.EventBus; + +@Configuration +public class ConfigureActiveJobsAspect { + @Resource(name = "microserverEventBus") + private EventBus bus; + private @Value("${system.logging.max.per.hour:10}") int maxLoggingCapacity; + private @Value("${system.request.capture:true}") boolean requestCapture; + + @Bean + public JobsBeingExecuted microEventJobsBeingExecuted() { + return new JobsBeingExecuted( + bus, maxLoggingCapacity, JobName.Types.SIMPLE); + } + + @Bean + public RequestTypes microEventRequestTypes() { + RequestsBeingExecuted def = this.microEventRequestsBeingExecuted(); + RequestTypes types = new RequestTypes( + bus, requestCapture); + types.getMap() + .put(def.getType(), def); + return types; + } + + @Bean + public RequestsBeingExecuted microEventRequestsBeingExecuted() { + return new RequestsBeingExecuted( + bus); + } + +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/GenericEvent.java b/micro-events/src/main/java/com/oath/micro/server/events/GenericEvent.java new file mode 100644 index 000000000..bf3fbc893 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/GenericEvent.java @@ -0,0 +1,40 @@ +package com.oath.micro.server.events; + +import com.google.common.eventbus.EventBus; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class GenericEvent { + + private GenericEventData data; + + public static GenericEvent trigger(String name, EventBus bus) { + return trigger(name, bus, null, new String[]{}); + } + + public static GenericEvent trigger(String name, EventBus bus, String[] subTypes) { + return trigger(name, bus, null, subTypes); + } + + public static GenericEvent trigger(String name, EventBus bus, T data, String[] subTypes) { + GenericEvent event = new GenericEvent<>(GenericEventData.builder() + .name(name) + .data(data) + .subTypes(subTypes) + .build()); + bus.post(event); + return event; + } + + @AllArgsConstructor + @Builder + @Getter + public static class GenericEventData extends BaseEventInfo { + private final String name; + private final String[] subTypes; + private final T data; + } +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/JobCompleteEvent.java b/micro-events/src/main/java/com/oath/micro/server/events/JobCompleteEvent.java new file mode 100644 index 000000000..3bedd3dce --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/JobCompleteEvent.java @@ -0,0 +1,18 @@ +package com.oath.micro.server.events; + +import java.util.Date; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class JobCompleteEvent { + + private final Date date = new Date(); + private final String correlationId; + private final String type; + private final long errors; + private final long dataSize; + +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/JobName.java b/micro-events/src/main/java/com/oath/micro/server/events/JobName.java new file mode 100644 index 000000000..26b244372 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/JobName.java @@ -0,0 +1,63 @@ +package com.oath.micro.server.events; + +import java.util.stream.Stream; + + +import cyclops.control.Maybe; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +public interface JobName { + + public static enum Types { + + SIMPLE(new SimpleJobName()), PACKAGE(new PackageJobName()), FULL(new FullJobName()); + + @Getter + private final JobName creator; + + private Types(JobName job) { + this.creator = job; + } + + } + + public String getType(Class c); + + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public static class SimpleJobName implements JobName { + + @Override + public String getType(Class c) { + return c.getSimpleName(); + } + } + + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public static class FullJobName implements JobName { + + @Override + public String getType(Class c) { + return c.getCanonicalName(); + } + } + + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public static class PackageJobName implements JobName { + + @Override + public String getType(Class c) { + return Maybe.ofNullable(c.getPackage()) + .map(Package::getName) + .map(packageName -> packageName.split("\\.")) + .stream() + .flatMap(Stream::of) + .takeRight(1) + .single() + .map(i -> i + ".") + .orElse("") + + c.getSimpleName(); + } + } +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/JobStartEvent.java b/micro-events/src/main/java/com/oath/micro/server/events/JobStartEvent.java new file mode 100644 index 000000000..21603f2ba --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/JobStartEvent.java @@ -0,0 +1,16 @@ +package com.oath.micro.server.events; + +import java.util.Date; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class JobStartEvent { + + private final Date date = new Date(); + private final String correlationId; + private final String type; + +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/JobsBeingExecuted.java b/micro-events/src/main/java/com/oath/micro/server/events/JobsBeingExecuted.java new file mode 100644 index 000000000..2cc5ca271 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/JobsBeingExecuted.java @@ -0,0 +1,139 @@ +package com.oath.micro.server.events; + +import java.util.Optional; +import java.util.Random; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; + +import com.google.common.collect.ConcurrentHashMultiset; +import com.google.common.eventbus.EventBus; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Aspect +public class JobsBeingExecuted { + + private static final Random r = new Random(); + private final ActiveEvents events = new ActiveEvents(); + @Getter(AccessLevel.PACKAGE) + private final ConcurrentHashMultiset statCounter = ConcurrentHashMultiset.create(); + private final EventBus eventBus; + private final JobName.Types jobNameType; + + private final LoggingRateLimiter loggingRateLimiter; + + private final long maxLoggingCapacity; + + public JobsBeingExecuted(@Qualifier("microserverEventBus") EventBus bus, + @Value("${system.logging.max.per.hour:10}") long maxLoggingCapacity, + @Value("${micro.events.job.name.format:SIMPLE}") JobName.Types jobNameType) { + this.eventBus = bus; + this.jobNameType = jobNameType; + this.loggingRateLimiter = new LoggingRateLimiter<>(); + this.maxLoggingCapacity = maxLoggingCapacity; + } + + public JobsBeingExecuted(EventBus bus) { + this( + bus, 10, JobName.Types.SIMPLE); + } + + @Around("execution(* com.oath.micro.server.events.ScheduledJob.scheduleAndLog(..))") + public Object aroundScheduledJob(ProceedingJoinPoint pjp) throws Throwable { + + String type = jobNameType.getCreator() + .getType(pjp.getSignature() + .getDeclaringType()); + + return executeScheduledJob(pjp, type); + + } + + public int size() { + return events.size(); + } + + public int events() { + return events.events(); + } + + @Override + public String toString() { + return events.toString(); + } + + private Object executeScheduledJob(final ProceedingJoinPoint pjp, final String type) throws Throwable { + addTypeToStatCounter(type); + JobExecutingData data = new JobExecutingData( + type, statCounter.count(type)); + String id = buildId(type, data.getProcessingThread()); + events.active(id, data); + + SystemData retVal = null; + String correlationId = String.valueOf(r.nextLong()); + eventBus.post(new JobStartEvent(correlationId, type)); + try { + + retVal = Optional.ofNullable(((SystemData) pjp.proceed())) + .map(sd -> sd.withCorrelationId(id)) + .orElse(null); + return retVal; + } finally { + logSystemEvent(pjp, type, data, retVal); + retVal = Optional.ofNullable(retVal) + .orElse(SystemData.builder() + .correlationId(correlationId) + .errors(0l) + .processed(0l) + .build()); + eventBus.post(new JobCompleteEvent(correlationId, type, retVal.getErrors(), retVal.getProcessed())); + } + } + + private void logSystemEvent(final ProceedingJoinPoint pjp, final String type, JobExecutingData data, + SystemData retVal) { + final SystemData active = retVal; + loggingRateLimiter.addAndEnsureFrequency(pjp.getTarget() + .getClass()); + loggingRateLimiter.capacityAvailable(pjp.getTarget() + .getClass(), + this.maxLoggingCapacity, () -> postEvent(pjp, type, data, active)); + } + + private void postEvent(ProceedingJoinPoint pjp, String type, JobExecutingData data, SystemData retVal) { + if (retVal != null) { + + eventBus.post(retVal); + } + events.finished(buildId(type, data.getProcessingThread())); + } + + private void addTypeToStatCounter(String type) { + try { + statCounter.add(type); + } catch (Exception e) { + statCounter.clear(); + statCounter.add(type); + } + } + + private String buildId(String type, long threadId) { + return "id_" + type + "-" + threadId; + } + + @AllArgsConstructor + @XmlAccessorType(XmlAccessType.FIELD) + static class JobExecutingData extends BaseEventInfo { + private final String type; + private final int timesExecuted; + } +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/LabelledEvents.java b/micro-events/src/main/java/com/oath/micro/server/events/LabelledEvents.java new file mode 100644 index 000000000..3ca1f8f42 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/LabelledEvents.java @@ -0,0 +1,119 @@ +package com.oath.micro.server.events; + +import com.oath.micro.server.events.RequestTypes.AddLabelledQuery; +import com.oath.micro.server.events.RequestTypes.RemoveLabelledQuery; +import com.oath.micro.server.events.RequestTypes.RequestData; + +import com.google.common.eventbus.EventBus; + +/** + * Factory class for creating Start and End events which are identified by a custom label + * + */ +public class LabelledEvents { + + /** + * Publish start events for each of the specified query types + * + *
+     * {@code
+        LabelledEvents.start("get", 1l, bus, "typeA", "custom");
+        try {
+            return "ok";
+        } finally {
+            RequestEvents.finish("get", 1l, bus, "typeA", "custom");
+        }
+     * }
+     * 
+ * + * @param query Completed query + * @param correlationId Identifier + * @param bus EventBus to post events to + * @param labels Query labels to post to event bus + */ + public static void start(T query, String correlationId, EventBus bus, String... labels) { + + for (String label : labels) { + AddLabelledQuery next = start(query, correlationId, label, null); + bus.post(next); + } + + } + + /** + * Marks the start of a query identified by the provided correlationId, with additional query type and data parameters + * + * @param query - Query data + * @param correlationId - Identifier + * @param label - allows queries to be grouped by label + * @return Start event to pass to the Events systems EventBus + */ + public static AddLabelledQuery start(T query, String correlationId, String label) { + return start(query, correlationId, label, null); + } + + /** + * Marks the start of a query identified by the provided correlationId, with additional query type and data parameters + * + * @param query - Query data + * @param correlationId - Identifier + * @param label - allows queries to be grouped by label + * @param additionalData - Any additional info about the request to be rendered in the JSON view / rest endpoint + * @return Start event to pass to the Events systems EventBus + */ + public static AddLabelledQuery start(T query, String correlationId, String label, Object additionalData) { + + return new AddLabelledQuery( + RequestData.builder() + .query(query) + .correlationId(correlationId) + .type(label) + .additionalData(additionalData) + .build()); + } + + /** + * Publish finish events for each of the specified query labels + * + *
+     * {@code
+     * LabelledEvents.start("get", 1l, bus, "typeA", "custom");
+       try {
+            return "ok";
+        } finally {
+            RequestEvents.finish("get", 1l, bus, "typeA", "custom");
+        }
+     *
+     * }
+     * 
+ * + * + * @param query Completed query + * @param correlationId Identifier + * @param bus EventBus to post events to + * @param labels Query types to post to event bus + */ + public static void finish(T query, String correlationId, EventBus bus, String... labels) { + for (String type : labels) { + RemoveLabelledQuery next = finish(query, correlationId, type); + bus.post(next); + } + } + /** + * Marks the end of a query identified by the provided correlationId + * + * @param query - Query data + * @param correlationId - Identifier + * @param label - allows queries to be grouped by type + * @return RemoveLabelledQuery event to pass to the Events systems EventBus + */ + public static RemoveLabelledQuery finish(T query, String correlationId, String label) { + + return new RemoveLabelledQuery<>( + RequestData.builder() + .query(query) + .correlationId(correlationId) + .type(label) + .build()); + } +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/LoggingRateLimiter.java b/micro-events/src/main/java/com/oath/micro/server/events/LoggingRateLimiter.java new file mode 100644 index 000000000..622c22883 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/LoggingRateLimiter.java @@ -0,0 +1,46 @@ +package com.oath.micro.server.events; + +import java.util.Date; + +import com.google.common.collect.ConcurrentHashMultiset; + +import lombok.AccessLevel; +import lombok.Getter; + +public class LoggingRateLimiter { + + @Getter(AccessLevel.PACKAGE) + private volatile ConcurrentHashMultiset frequency = ConcurrentHashMultiset.create(); + private volatile Date lastCleared = new Date( + 0); + private final int limit; + + public LoggingRateLimiter(int limit) { + this.limit = limit; + } + + public LoggingRateLimiter() { + this.limit = (60 * 1000 * 60); + } + + public void addAndEnsureFrequency(T clazz) { + resetAfterLimit(); + frequency.add(clazz); + } + + public void resetAfterLimit() { + if (System.currentTimeMillis() - limit > lastCleared.getTime()) { + frequency = ConcurrentHashMultiset.create(); + lastCleared = new Date( + System.currentTimeMillis()); + } + + } + + public void capacityAvailable(T t, long max, Runnable run) { + if (frequency.count(t) < max) + run.run(); + + } + +} diff --git a/micro-events/src/main/java/com/aol/micro/server/events/RemoveEvent.java b/micro-events/src/main/java/com/oath/micro/server/events/RemoveEvent.java similarity index 79% rename from micro-events/src/main/java/com/aol/micro/server/events/RemoveEvent.java rename to micro-events/src/main/java/com/oath/micro/server/events/RemoveEvent.java index 966219f84..da74e3ad0 100644 --- a/micro-events/src/main/java/com/aol/micro/server/events/RemoveEvent.java +++ b/micro-events/src/main/java/com/oath/micro/server/events/RemoveEvent.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.events; +package com.oath.micro.server.events; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/micro-events/src/main/java/com/oath/micro/server/events/RequestEvents.java b/micro-events/src/main/java/com/oath/micro/server/events/RequestEvents.java new file mode 100644 index 000000000..b218fc7c4 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/RequestEvents.java @@ -0,0 +1,142 @@ +package com.oath.micro.server.events; + +import com.oath.micro.server.events.RequestTypes.AddQuery; +import com.oath.micro.server.events.RequestTypes.RemoveQuery; +import com.oath.micro.server.events.RequestTypes.RequestData; +import com.google.common.eventbus.EventBus; + +/** + * Factory class for creating Start and End events + * + * @author johnmcclean + * + */ +public class RequestEvents { + + /** + * Marks the start of a query identified by the provided correlationId + * + * @param query - Query data + * @param correlationId - Identifier + * @return Start event to pass to the Events systems EventBus + */ + public static AddQuery start(T query, String correlationId) { + return start(query, correlationId, "default", null); + } + + /** + * Marks the start of a query identified by the provided correlationId, with additional query type and data parameters + * + * @param query - Query data + * @param correlationId - Identifier + * @param type - allows queries to be grouped by type + * @return Start event to pass to the Events systems EventBus + */ + public static AddQuery start(T query, String correlationId, String type) { + return start(query, correlationId, type, null); + } + + /** + * Publish start events for each of the specified query types + * + *
+     * {@code 
+        RequestEvents.start("get", 1l, bus, "typeA", "custom");
+        try {
+            return "ok";
+        } finally {
+            RequestEvents.finish("get", 1l, bus, "typeA", "custom");
+        }     
+     * }
+     * 
+ * + * @param query Completed query + * @param correlationId Identifier + * @param bus EventBus to post events to + * @param types Query types to post to event bus + */ + public static void start(T query, String correlationId, EventBus bus, String... types) { + + for (String type : types) { + AddQuery next = start(query, correlationId, type, null); + bus.post(next); + } + + } + + /** + * Marks the start of a query identified by the provided correlationId, with additional query type and data parameters + * + * @param query - Query data + * @param correlationId - Identifier + * @param type - allows queries to be grouped by type + * @param additionalData - Any additional info about the request to be rendered in the JSON view / rest endpoint + * @return Start event to pass to the Events systems EventBus + */ + public static AddQuery start(T query, String correlationId, String type, Object additionalData) { + + return new AddQuery(RequestData.builder() + .query(query) + .correlationId(correlationId) + .type(type) + .additionalData(additionalData) + .build()); + } + + /** + * Marks the end of a query identified by the provided correlationId + * + * @param query - Query data + * @param correlationId - Identifier + * @return Finish event to pass to the Events systems EventBus + */ + public static RemoveQuery finish(T query, String correlationId) { + return finish(query, correlationId, "default"); + } + + /** + * Publish finish events for each of the specified query types + * + *
+     * {@code 
+     * RequestEvents.start("get", 1l, bus, "typeA", "custom");
+        try {
+            return "ok";
+        } finally {
+            RequestEvents.finish("get", 1l, bus, "typeA", "custom");
+        }
+     * 
+     * }
+     * 
+ * + * + * @param query Completed query + * @param correlationId Identifier + * @param bus EventBus to post events to + * @param types Query types to post to event bus + */ + public static void finish(T query, String correlationId, EventBus bus, String... types) { + for (String type : types) { + RemoveQuery next = finish(query, correlationId, type); + bus.post(next); + } + } + + /** + * Marks the end of a query identified by the provided correlationId + * + * @param query - Query data + * @param correlationId - Identifier + * @param type - allows queries to be grouped by type + * @return + */ + public static RemoveQuery finish(T query, String correlationId, String type) { + + return new RemoveQuery<>(RequestData.builder() + .query(query) + .correlationId(correlationId) + .type(type) + .build()); + } + +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/RequestTypes.java b/micro-events/src/main/java/com/oath/micro/server/events/RequestTypes.java new file mode 100644 index 000000000..0554fe91a --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/RequestTypes.java @@ -0,0 +1,105 @@ +package com.oath.micro.server.events; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +import cyclops.reactive.collections.mutable.MapX; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +public class RequestTypes { + @Getter + private final Map map = new ConcurrentHashMap<>();; + + private final EventBus bus; + + public RequestTypes(EventBus bus, boolean queryCapture) { + this.bus = bus; + if (queryCapture) + bus.register(this); + + } + + @Override + public String toString() { + return JacksonUtil.serializeToJson(toMap()); + } + + public Map toMap() { + return MapX.fromMap(map) + .bimap(k -> k, v -> v.toMap()); + } + + @Subscribe + public void finished(RemoveQuery data) { + String key = data.getData().type; + map.computeIfAbsent(key, k -> new RequestsBeingExecuted(bus, k)).events.finished(buildId(data.getData())); + + } + + @Subscribe + public void processing(AddQuery data) { + String id = buildId(data.getData()); + String key = data.getData().type; + map.computeIfAbsent(key, k -> new RequestsBeingExecuted(bus, k)).events.active(id, data.getData()); + + } + + private String buildId(RequestData data) { + return data.correlationId; + } + + public static class AddQuery extends AddEvent> { + + public AddQuery(RequestData data) { + super(data); + } + + } + + public static class RemoveQuery extends RemoveEvent> { + + public RemoveQuery(RequestData data) { + super(data); + } + + } + + public static class AddLabelledQuery extends AddEvent> { + + public AddLabelledQuery(RequestData data) { + super(data); + } + + } + + public static class RemoveLabelledQuery extends RemoveEvent> { + + public RemoveLabelledQuery(RequestData data) { + super(data); + } + + } + + @AllArgsConstructor + @Builder + @XmlAccessorType(XmlAccessType.FIELD) + @Getter + public static class RequestData extends BaseEventInfo { + + private final String correlationId; + + private final T query; + + private final String type; + private final Object additionalData; + } +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/RequestsBeingExecuted.java b/micro-events/src/main/java/com/oath/micro/server/events/RequestsBeingExecuted.java new file mode 100644 index 000000000..55cf76a9e --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/RequestsBeingExecuted.java @@ -0,0 +1,48 @@ +package com.oath.micro.server.events; + +import java.util.Map; + +import org.springframework.beans.factory.annotation.Qualifier; + +import com.oath.micro.server.events.RequestTypes.RequestData; +import com.google.common.eventbus.EventBus; + +import lombok.Getter; + +public class RequestsBeingExecuted { + + private final EventBus bus; + final ActiveEvents> events = new ActiveEvents<>(); + @Getter + private final String type; + + public RequestsBeingExecuted(@Qualifier("microserverEventBus") EventBus bus) { + this.bus = bus; + this.type = "default"; + + } + + public RequestsBeingExecuted(EventBus bus, String type) { + this.bus = bus; + this.type = type; + bus.register(this); + + } + + public int events() { + return events.events(); + } + + public int size() { + return events.size(); + } + + @Override + public String toString() { + return events.toString(); + } + + Map toMap() { + return events.toMap(); + } +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/SchedulableJob.java b/micro-events/src/main/java/com/oath/micro/server/events/SchedulableJob.java new file mode 100644 index 000000000..19712af3d --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/SchedulableJob.java @@ -0,0 +1,5 @@ +package com.oath.micro.server.events; + +public interface SchedulableJob extends ScheduledJob { + boolean isScheduled(); +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/ScheduledJob.java b/micro-events/src/main/java/com/oath/micro/server/events/ScheduledJob.java new file mode 100644 index 000000000..f6e308116 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/ScheduledJob.java @@ -0,0 +1,7 @@ +package com.oath.micro.server.events; + + + +public interface ScheduledJob { + SystemData scheduleAndLog(); +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/StartedAt.java b/micro-events/src/main/java/com/oath/micro/server/events/StartedAt.java new file mode 100644 index 000000000..97618c833 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/StartedAt.java @@ -0,0 +1,6 @@ +package com.oath.micro.server.events; + +public interface StartedAt { + + public long getStartedAt(); +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/SystemData.java b/micro-events/src/main/java/com/oath/micro/server/events/SystemData.java new file mode 100644 index 000000000..3a2055187 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/SystemData.java @@ -0,0 +1,33 @@ +package com.oath.micro.server.events; + +import java.util.Map; +import java.util.Random; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.Builder; +import lombok.experimental.Wither; + +@Builder +@Wither +@AllArgsConstructor +@Getter +@ToString +@EqualsAndHashCode(of = { "correlationId" }) +public class SystemData { + + private static final Random r = new Random(); + private final long processed; + private final long errors; + private final Map dataMap; + private String correlationId; + + private SystemData(long processed, long errors, Map dataMap) { + this.processed = processed; + this.errors = errors; + this.dataMap = dataMap; + this.correlationId = String.valueOf(r.nextLong()); + } +} diff --git a/micro-events/src/main/java/com/oath/micro/server/events/plugin/EventsPlugin.java b/micro-events/src/main/java/com/oath/micro/server/events/plugin/EventsPlugin.java new file mode 100644 index 000000000..8abf7822e --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/events/plugin/EventsPlugin.java @@ -0,0 +1,32 @@ +package com.oath.micro.server.events.plugin; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.events.ConfigureActiveJobsAspect; +import com.oath.micro.server.rest.resources.ConfigureResources; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + + +/** + * + * Collections of Spring configuration classes (Classes annotated with @Configuration) + * that configure various useful pieces of functionality - such as property file loading, + * datasources, scheduling etc + * + * @author johnmcclean + * + */ +public class EventsPlugin implements Plugin{ + + @Override + public Set springClasses() { + return SetX.of( + ConfigureActiveJobsAspect.class, + ConfigureResources.class); + } + + + +} diff --git a/micro-events/src/main/java/com/oath/micro/server/rest/resources/ActiveResource.java b/micro-events/src/main/java/com/oath/micro/server/rest/resources/ActiveResource.java new file mode 100644 index 000000000..3eaf46023 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/rest/resources/ActiveResource.java @@ -0,0 +1,76 @@ +package com.oath.micro.server.rest.resources; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; + +import cyclops.reactive.ReactiveSeq; +import org.springframework.beans.factory.annotation.Autowired; + + +import com.oath.micro.server.WorkerThreads; +import com.oath.micro.server.auto.discovery.CommonRestResource; +import com.oath.micro.server.auto.discovery.SingletonRestResource; +import com.oath.micro.server.events.JobsBeingExecuted; +import com.oath.micro.server.events.RequestTypes; + +@Path("/active") +public class ActiveResource implements CommonRestResource, SingletonRestResource { + + private static final Object LOG_LEVEL = null; + private final RequestTypes activeQueries; + private final JobsBeingExecuted activeJobs; + private Long entityIds; + + @Autowired + public ActiveResource(RequestTypes activeQueries, JobsBeingExecuted activeJobs) { + + this.activeQueries = activeQueries; + this.activeJobs = activeJobs; + } + + @GET + @Produces("application/json") + @Path("/requests") + public void activeRequests(@Suspended AsyncResponse asyncResponse, @QueryParam("type") final String type) { + + ReactiveSeq.of((type == null ? "default" : type)) + .map(typeToUse -> activeQueries.getMap() + .get(typeToUse) + .toString()) + .foldFuture(WorkerThreads.ioExecutor.get(), + s->s.forEach(Long.MAX_VALUE,result -> asyncResponse.resume(result))); + + } + + @GET + @Produces("application/json") + @Path("/all-requests") + public void allActiveRequests(@Suspended AsyncResponse asyncResponse) { + + ReactiveSeq.of(activeQueries.toString()) + .foldFuture(WorkerThreads.ioExecutor.get(), + s->s.forEach(Long.MAX_VALUE,result -> asyncResponse.resume(result))); + + } + + @GET + @Produces("application/json") + @Path("/jobs") + public void activeJobs(@Suspended AsyncResponse asyncResponse) { + try { + ReactiveSeq.of(this.activeJobs) + .map(JobsBeingExecuted::toString) + .foldFuture(WorkerThreads.ioExecutor.get(), + s -> s.forEach(Long.MAX_VALUE, str -> asyncResponse.resume(str))); + + } catch (Exception e) { + e.printStackTrace(); + + } + } + +} diff --git a/micro-events/src/main/java/com/oath/micro/server/rest/resources/ConfigureResources.java b/micro-events/src/main/java/com/oath/micro/server/rest/resources/ConfigureResources.java new file mode 100644 index 000000000..c1b9211d9 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/rest/resources/ConfigureResources.java @@ -0,0 +1,28 @@ +package com.oath.micro.server.rest.resources; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.events.JobsBeingExecuted; +import com.oath.micro.server.events.RequestTypes; + +@Configuration +public class ConfigureResources { + + @Autowired + private RequestTypes activeQueries; + + @Bean + public ActiveResource activeResource( + @Qualifier("microEventJobsBeingExecuted") JobsBeingExecuted jobsBeingExecuted) { + return new ActiveResource( + activeQueries, jobsBeingExecuted); + } + + @Bean + public ManifestResource manifest() { + return new ManifestResource(); + } +} diff --git a/micro-events/src/main/java/com/oath/micro/server/rest/resources/ManifestResource.java b/micro-events/src/main/java/com/oath/micro/server/rest/resources/ManifestResource.java new file mode 100644 index 000000000..4ea6e3d09 --- /dev/null +++ b/micro-events/src/main/java/com/oath/micro/server/rest/resources/ManifestResource.java @@ -0,0 +1,61 @@ +package com.oath.micro.server.rest.resources; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import javax.servlet.ServletContext; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; +import javax.ws.rs.core.Context; + +import cyclops.reactive.ReactiveSeq; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.WorkerThreads; +import com.oath.micro.server.auto.discovery.CommonRestResource; +import com.oath.micro.server.auto.discovery.SingletonRestResource; + +@Path("/manifest") +@Component +public class ManifestResource implements CommonRestResource, SingletonRestResource{ + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @GET + @Produces("application/json") + public void mainfest(@Suspended AsyncResponse asyncResponse, @Context ServletContext context) { + + ReactiveSeq.of("/META-INF/MANIFEST.MF") + .map(url -> context.getResourceAsStream(url)) + .map(this::getManifest) + .foldFuture(WorkerThreads.ioExecutor.get(), + s -> s.forEach(Long.MAX_VALUE, result -> asyncResponse.resume(result))); + } + + public Map getManifest(final InputStream input) { + + final Map retMap = new HashMap(); + try { + Manifest manifest = new Manifest(); + manifest.read(input); + final Attributes attributes = manifest.getMainAttributes(); + for (final Map.Entry attribute : attributes.entrySet()) { + retMap.put(attribute.getKey().toString(), attribute.getValue().toString()); + } + } catch (final Exception ex) { + logger.error( "Failed to load manifest ", ex); + } + + return retMap; + } + +} diff --git a/micro-events/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-events/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 8857f9e9a..000000000 --- a/micro-events/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.events.plugin.EventsPlugin \ No newline at end of file diff --git a/micro-events/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-events/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..1fe2ea907 --- /dev/null +++ b/micro-events/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.events.plugin.EventsPlugin \ No newline at end of file diff --git a/micro-events/src/test/java/NoPackageTest.java b/micro-events/src/test/java/NoPackageTest.java new file mode 100644 index 000000000..e608c44a0 --- /dev/null +++ b/micro-events/src/test/java/NoPackageTest.java @@ -0,0 +1,16 @@ +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +import org.junit.Test; + +import com.oath.micro.server.events.JobName; +import com.oath.micro.server.events.JobName.Types; + +public class NoPackageTest { + JobName one = Types.PACKAGE.getCreator(); + + @Test + public void testPackageNone() { + assertThat(one.getType(NoPackageTest.class), equalTo("NoPackageTest")); + } +} diff --git a/micro-events/src/test/java/app/events/com/aol/micro/server/EventRunnerTest.java b/micro-events/src/test/java/app/events/com/aol/micro/server/EventRunnerTest.java deleted file mode 100644 index 9f76802d6..000000000 --- a/micro-events/src/test/java/app/events/com/aol/micro/server/EventRunnerTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package app.events.com.aol.micro.server; - - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class EventRunnerTest { - - RestAgent rest = new RestAgent(); - MicroserverApp server; - - - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "event-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/event-app/status/ping"),is("ok")); - - assertThat(rest.getJson("http://localhost:8080/event-app/active/jobs"), - containsString("startedAt")); - assertThat(rest.getJson("http://localhost:8080/event-app/active/requests"), - containsString("startedAt")); - assertThat(rest.getJson("http://localhost:8080/event-app/manifest"), - containsString("Manifest")); - - } - - - -} diff --git a/micro-events/src/test/java/app/events/com/aol/micro/server/EventStatusResource.java b/micro-events/src/test/java/app/events/com/aol/micro/server/EventStatusResource.java deleted file mode 100644 index 7f5bc184b..000000000 --- a/micro-events/src/test/java/app/events/com/aol/micro/server/EventStatusResource.java +++ /dev/null @@ -1,40 +0,0 @@ -package app.events.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.events.RequestEvents; -import com.google.common.eventbus.EventBus; - -@Component -@Path("/status") -public class EventStatusResource implements RestResource { - - - - - private final EventBus bus; - - @Autowired - public EventStatusResource(EventBus bus ){ - this.bus = bus; - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - bus.post(RequestEvents.start("get", 1l)); - try{ - return "ok"; - }finally{ - bus.post(RequestEvents.finish("get",1l)); - } - } - -} \ No newline at end of file diff --git a/micro-events/src/test/java/app/events/com/aol/micro/server/Job.java b/micro-events/src/test/java/app/events/com/aol/micro/server/Job.java deleted file mode 100644 index 39f9f6222..000000000 --- a/micro-events/src/test/java/app/events/com/aol/micro/server/Job.java +++ /dev/null @@ -1,16 +0,0 @@ -package app.events.com.aol.micro.server; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.events.ScheduledJob; -import com.aol.micro.server.events.SystemData; - -@Component -public class Job implements ScheduledJob{ - - @Override - public SystemData scheduleAndLog() { - return SystemData.builder().errors(0).processed(2).build(); - } - -} diff --git a/micro-events/src/test/java/app/events/com/aol/micro/server/Schedular.java b/micro-events/src/test/java/app/events/com/aol/micro/server/Schedular.java deleted file mode 100644 index 8b99c6930..000000000 --- a/micro-events/src/test/java/app/events/com/aol/micro/server/Schedular.java +++ /dev/null @@ -1,21 +0,0 @@ -package app.events.com.aol.micro.server; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -@Component -public class Schedular { - - private final Job job; - - @Autowired - public Schedular(final Job job){ - this.job=job; - } - - @Scheduled(fixedDelay=1) - public synchronized void scheduleTask(){ - job.scheduleAndLog(); - } -} diff --git a/micro-events/src/test/java/app/events/com/oath/micro/server/EventRunnerTest.java b/micro-events/src/test/java/app/events/com/oath/micro/server/EventRunnerTest.java new file mode 100644 index 000000000..4b69955d3 --- /dev/null +++ b/micro-events/src/test/java/app/events/com/oath/micro/server/EventRunnerTest.java @@ -0,0 +1,66 @@ +package app.events.com.oath.micro.server; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class EventRunnerTest { + + RestAgent rest = new RestAgent(); + MicroserverApp server; + + @Before + public void startServer() { + + server = new MicroserverApp( + () -> "event-app"); + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + assertThat(rest.get("http://localhost:8080/event-app/status/ping"), is("ok")); + + assertThat(rest.getJson("http://localhost:8080/event-app/active/jobs"), containsString("startedAt")); + assertThat(rest.getJson("http://localhost:8080/event-app/active/requests"), containsString("startedAt")); + assertThat(rest.getJson("http://localhost:8080/event-app/manifest"), containsString("Manifest")); + assertThat(rest.getJson("http://localhost:8080/event-app/manifest"), containsString("Manifest-Version")); + + System.out.println(rest.getJson("http://localhost:8080/event-app/manifest")); + + } + + @Test + public void runAppAndBasicTestCustom() throws InterruptedException, ExecutionException { + + assertThat(rest.get("http://localhost:8080/event-app/status/ping-custom"), is("ok")); + + assertThat(rest.getJson("http://localhost:8080/event-app/active/jobs?type=custom"), + containsString("startedAt")); + assertThat(rest.getJson("http://localhost:8080/event-app/active/all-requests"), containsString("startedAt")); + assertThat(rest.getJson("http://localhost:8080/event-app/manifest"), containsString("Manifest")); + assertThat(rest.getJson("http://localhost:8080/event-app/manifest"), containsString("Manifest-Version")); + + System.out.println(rest.getJson("http://localhost:8080/event-app/manifest")); + + } + +} diff --git a/micro-events/src/test/java/app/events/com/oath/micro/server/EventStatusResource.java b/micro-events/src/test/java/app/events/com/oath/micro/server/EventStatusResource.java new file mode 100644 index 000000000..9c7a2fddf --- /dev/null +++ b/micro-events/src/test/java/app/events/com/oath/micro/server/EventStatusResource.java @@ -0,0 +1,49 @@ +package app.events.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.events.RequestEvents; +import com.google.common.eventbus.EventBus; + +@Component +@Path("/status") +public class EventStatusResource implements RestResource { + + private final EventBus bus; + + @Autowired + public EventStatusResource(EventBus bus) { + this.bus = bus; + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + bus.post(RequestEvents.start("get", "1")); + try { + return "ok"; + } finally { + bus.post(RequestEvents.finish("get", "1")); + } + } + + @GET + @Produces("text/plain") + @Path("/ping-custom") + public String pingCustom() { + bus.post(RequestEvents.start("get", "1", "custom")); + try { + return "ok"; + } finally { + bus.post(RequestEvents.finish("get", "1", "custom")); + } + } + +} diff --git a/micro-events/src/test/java/app/events/com/oath/micro/server/Job.java b/micro-events/src/test/java/app/events/com/oath/micro/server/Job.java new file mode 100644 index 000000000..b39b7cff8 --- /dev/null +++ b/micro-events/src/test/java/app/events/com/oath/micro/server/Job.java @@ -0,0 +1,16 @@ +package app.events.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.events.ScheduledJob; +import com.oath.micro.server.events.SystemData; + +@Component +public class Job implements ScheduledJob{ + + @Override + public SystemData scheduleAndLog() { + return SystemData.builder().errors(0).processed(2).build(); + } + +} diff --git a/micro-events/src/test/java/app/events/com/oath/micro/server/Schedular.java b/micro-events/src/test/java/app/events/com/oath/micro/server/Schedular.java new file mode 100644 index 000000000..c93a9c537 --- /dev/null +++ b/micro-events/src/test/java/app/events/com/oath/micro/server/Schedular.java @@ -0,0 +1,21 @@ +package app.events.com.oath.micro.server; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +@Component +public class Schedular { + + private final Job job; + + @Autowired + public Schedular(final Job job){ + this.job=job; + } + + @Scheduled(fixedDelay=1) + public synchronized void scheduleTask(){ + job.scheduleAndLog(); + } +} diff --git a/micro-events/src/test/java/app/groovy/StatusGroovy.groovy b/micro-events/src/test/java/app/groovy/StatusGroovy.groovy deleted file mode 100644 index c78d4f87f..000000000 --- a/micro-events/src/test/java/app/groovy/StatusGroovy.groovy +++ /dev/null @@ -1,31 +0,0 @@ -package app.groovy - -import javax.ws.rs.GET -import javax.ws.rs.Path -import javax.ws.rs.Produces - -import app.groovy.StatusGroovy; - -import com.aol.micro.server.MicroserverApp -import com.aol.micro.server.auto.discovery.Rest -import com.aol.micro.server.config.Microserver -import com.aol.micro.server.module.Module - -@Rest -@Path("/status") -@Microserver -class StatusGroovy { - - static void main(String[] args){ - - def app = new MicroserverApp(StatusGroovy,{ -> "status-app"} as Module).start() - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String respondToPing() { - return "pong!" - } -} diff --git a/micro-events/src/test/java/app/groovy/StatusGroovy.java b/micro-events/src/test/java/app/groovy/StatusGroovy.java new file mode 100644 index 000000000..414710ca0 --- /dev/null +++ b/micro-events/src/test/java/app/groovy/StatusGroovy.java @@ -0,0 +1,38 @@ +package app.groovy; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.Module; +//import groovy.lang.Closure; +//import org.codehaus.groovy.runtime.DefaultGroovyMethods; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import java.util.List; + +@Rest +@Path("/status") +@Microserver +public class StatusGroovy { + public static void main(String[] args) { +/** + List app = new MicroserverApp(StatusGroovy.class, DefaultGroovyMethods.asType(new Closure(null, null) { + public String doCall() { + return "status-app"; + } + + }, Module.class)).start(); + **/ + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String respondToPing() { + return "pong!"; + } + +} diff --git a/micro-events/src/test/java/app/multi/events/com/oath/micro/server/Job.java b/micro-events/src/test/java/app/multi/events/com/oath/micro/server/Job.java new file mode 100644 index 000000000..5b76af49a --- /dev/null +++ b/micro-events/src/test/java/app/multi/events/com/oath/micro/server/Job.java @@ -0,0 +1,16 @@ +package app.multi.events.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.events.ScheduledJob; +import com.oath.micro.server.events.SystemData; + +@Component +public class Job implements ScheduledJob{ + + @Override + public SystemData scheduleAndLog() { + return SystemData.builder().errors(0).processed(2).build(); + } + +} diff --git a/micro-events/src/test/java/app/multi/events/com/oath/micro/server/MulitEventRunnerTest.java b/micro-events/src/test/java/app/multi/events/com/oath/micro/server/MulitEventRunnerTest.java new file mode 100644 index 000000000..3ac4f5dc5 --- /dev/null +++ b/micro-events/src/test/java/app/multi/events/com/oath/micro/server/MulitEventRunnerTest.java @@ -0,0 +1,67 @@ +package app.multi.events.com.oath.micro.server; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class MulitEventRunnerTest { + + RestAgent rest = new RestAgent(); + MicroserverApp server; + + @Before + public void startServer() { + + server = new MicroserverApp( + () -> "event-app"); + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + assertThat(rest.get("http://localhost:8080/event-app/status/ping"), is("ok")); + + assertThat(rest.getJson("http://localhost:8080/event-app/active/jobs"), containsString("startedAt")); + assertThat(rest.getJson("http://localhost:8080/event-app/active/all-requests"), containsString("startedAt")); + assertThat(rest.getJson("http://localhost:8080/event-app/manifest"), containsString("Manifest")); + assertThat(rest.getJson("http://localhost:8080/event-app/manifest"), containsString("Manifest-Version")); + + System.out.println(rest.getJson("http://localhost:8080/event-app/manifest")); + + } + + @Test + public void runAppAndBasicTestCustom() throws InterruptedException, ExecutionException { + + assertThat(rest.get("http://localhost:8080/event-app/status/ping-custom"), is("ok")); + + assertThat(rest.getJson("http://localhost:8080/event-app/active/jobs?type=custom"), + containsString("startedAt")); + assertThat(rest.getJson("http://localhost:8080/event-app/active/jobs?type=typeA"), containsString("startedAt")); + assertThat(rest.getJson("http://localhost:8080/event-app/active/all-requests"), containsString("startedAt")); + assertThat(rest.getJson("http://localhost:8080/event-app/manifest"), containsString("Manifest")); + assertThat(rest.getJson("http://localhost:8080/event-app/manifest"), containsString("Manifest-Version")); + + System.out.println(rest.getJson("http://localhost:8080/event-app/manifest")); + + } + +} diff --git a/micro-events/src/test/java/app/multi/events/com/oath/micro/server/MultiEventStatusResource.java b/micro-events/src/test/java/app/multi/events/com/oath/micro/server/MultiEventStatusResource.java new file mode 100644 index 000000000..483ce2e90 --- /dev/null +++ b/micro-events/src/test/java/app/multi/events/com/oath/micro/server/MultiEventStatusResource.java @@ -0,0 +1,49 @@ +package app.multi.events.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.events.RequestEvents; +import com.google.common.eventbus.EventBus; + +@Component +@Path("/status") +public class MultiEventStatusResource implements RestResource { + + private final EventBus bus; + + @Autowired + public MultiEventStatusResource(EventBus bus) { + this.bus = bus; + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + RequestEvents.start("get", "1", bus, "typeA", "custom"); + try { + return "ok"; + } finally { + RequestEvents.finish("get", "1", bus, "typeA", "custom"); + } + } + + @GET + @Produces("text/plain") + @Path("/ping-custom") + public String pingCustom() { + RequestEvents.start("get", "1", bus, "typeA", "custom"); + try { + return "ok"; + } finally { + RequestEvents.finish("get", "1", bus, "typeA", "custom"); + } + } + +} diff --git a/micro-events/src/test/java/app/multi/events/com/oath/micro/server/Schedular.java b/micro-events/src/test/java/app/multi/events/com/oath/micro/server/Schedular.java new file mode 100644 index 000000000..357becbef --- /dev/null +++ b/micro-events/src/test/java/app/multi/events/com/oath/micro/server/Schedular.java @@ -0,0 +1,21 @@ +package app.multi.events.com.oath.micro.server; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +@Component +public class Schedular { + + private final Job job; + + @Autowired + public Schedular(final Job job){ + this.job=job; + } + + @Scheduled(fixedDelay=1) + public synchronized void scheduleTask(){ + job.scheduleAndLog(); + } +} diff --git a/micro-events/src/test/java/com/aol/micro/server/events/ActiveEventsTest.java b/micro-events/src/test/java/com/aol/micro/server/events/ActiveEventsTest.java deleted file mode 100644 index a853a0b7c..000000000 --- a/micro-events/src/test/java/com/aol/micro/server/events/ActiveEventsTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.aol.micro.server.events; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; - -import org.junit.Before; -import org.junit.Test; - -import com.google.common.collect.ImmutableMap; - -public class ActiveEventsTest { - - ActiveEvents activeEvents; - @Before - public void setup(){ - activeEvents = new ActiveEvents(); - } - @Test - public void testOneEvent() { - activeEvents.active("hello", new BaseEventInfo()); - assertThat(activeEvents.events(),is(1)); - } - @Test - public void testTwoEvents() { - activeEvents.active("hello", new BaseEventInfo()); - activeEvents.active("hello2", new BaseEventInfo()); - assertThat(activeEvents.events(),is(2)); - assertThat(activeEvents.size(),is(2)); - } - @Test - public void testTwoIdenticalEvents() { - activeEvents.active("hello", new BaseEventInfo()); - activeEvents.active("hello", new BaseEventInfo()); - assertThat(activeEvents.events(),is(2)); - assertThat(activeEvents.size(),is(1)); - } - - @Test - public void testFinishedString() { - activeEvents.active("hello", new BaseEventInfo()); - activeEvents.finished("hello"); - assertThat(activeEvents.events(),is(1)); - assertThat(activeEvents.size(),is(0)); - } - - @Test - public void testFinishedStringImmutableMap() { - activeEvents.active("hello", new BaseEventInfo()); - activeEvents.finished("hello",ImmutableMap.of("hello","world")); - assertThat(activeEvents.events(),is(1)); - assertThat(activeEvents.size(),is(0)); - assertThat(activeEvents.toString(),containsString("world")); - } - - - -} diff --git a/micro-events/src/test/java/com/aol/micro/server/events/JobsBeingExecutedTest.java b/micro-events/src/test/java/com/aol/micro/server/events/JobsBeingExecutedTest.java deleted file mode 100644 index 555a76ad8..000000000 --- a/micro-events/src/test/java/com/aol/micro/server/events/JobsBeingExecutedTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.aol.micro.server.events; - -import static org.hamcrest.Matchers.*; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.springframework.util.ReflectionUtils.findField; -import static org.springframework.util.ReflectionUtils.getField; -import static org.springframework.util.ReflectionUtils.makeAccessible; - -import java.lang.reflect.Field; -import java.util.concurrent.ConcurrentMap; - -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.Signature; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; -import org.springframework.util.ReflectionUtils; - -import com.google.common.collect.ConcurrentHashMultiset; -import com.google.common.collect.Maps; -import com.google.common.eventbus.EventBus; -import com.google.common.eventbus.Subscribe; - - -public class JobsBeingExecutedTest { - - JobsBeingExecuted jobs; - - ProceedingJoinPoint pjp; - EventBus bus; - SystemData data; - SystemData incoming; - - - @Before - public void setUp() throws Exception { - data = SystemData.builder().dataMap(Maps.newHashMap()).errors(1).processed(100).build(); - bus = new EventBus(); - bus.register(this); - jobs = new JobsBeingExecuted(bus,10); - pjp = Mockito.mock(ProceedingJoinPoint.class); - } - - @Subscribe public void event(SystemData info){ - this.incoming = info; - } - - - @Test - public void testExecute() throws Throwable { - Signature sig = Mockito.mock( Signature.class); - Mockito.when(pjp.getSignature()).thenReturn(sig); - when(pjp.getTarget()).thenReturn(this); - Mockito.when(sig.getDeclaringType()).thenReturn(String.class); - jobs.aroundScheduledJob(pjp); - verify(pjp,times(1)).proceed(); - } - - @Test - public void testExecuteWithEvent() throws Throwable { - Signature sig = Mockito.mock( Signature.class); - when(pjp.getSignature()).thenReturn(sig); - when(sig.getDeclaringType()).thenReturn(String.class); - when(pjp.proceed()).thenReturn(data); - when(pjp.getTarget()).thenReturn(this); - jobs.aroundScheduledJob(pjp); - verify(pjp,times(1)).proceed(); - assertThat( incoming,is(notNullValue())); - - - } - @Test - public void testExecuteId() throws Throwable { - Signature sig = Mockito.mock( Signature.class); - when(pjp.getSignature()).thenReturn(sig); - when(sig.getDeclaringType()).thenReturn(String.class); - when(pjp.proceed()).thenReturn(data); - when(pjp.getTarget()).thenReturn(this); - jobs.aroundScheduledJob(pjp); - verify(pjp,times(1)).proceed(); - - - assertThat(incoming.getCorrelationId(),containsString("id_java.lang.String")); - } - @Test - public void testOverflow() throws Throwable { - when(pjp.getTarget()).thenReturn(this); - Field field = findField(ConcurrentHashMultiset.class,"countMap"); - makeAccessible(field); - ConcurrentMap map = (ConcurrentMap) getField(field, jobs.getStatCounter()); - map.put("java.lang.String",Integer.MAX_VALUE); - testExecute(); - } - -} diff --git a/micro-events/src/test/java/com/aol/micro/server/events/RequestsBeingExecutedTest.java b/micro-events/src/test/java/com/aol/micro/server/events/RequestsBeingExecutedTest.java deleted file mode 100644 index 548ebe39e..000000000 --- a/micro-events/src/test/java/com/aol/micro/server/events/RequestsBeingExecutedTest.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.aol.micro.server.events; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import org.junit.Before; -import org.junit.Test; - -import com.google.common.eventbus.EventBus; - -public class RequestsBeingExecutedTest { - - RequestsBeingExecuted requests; - EventBus bus; - @Before - public void setup(){ - bus = new EventBus(); - requests = new RequestsBeingExecuted(bus,true); - } - @Test - public void oneEvent() { - bus.post(RequestEvents.start("data", 100l)); - assertThat(requests.events(),is(1)); - } - @Test - public void twoEvents() { - bus.post(RequestEvents.start("data", 100l)); - bus.post(RequestEvents.start("data", 120l)); - assertThat(requests.events(),is(2)); - } - @Test - public void twoIdenticalEvents() { - bus.post(RequestEvents.start("data", 100l)); - bus.post(RequestEvents.start("data", 100l)); - assertThat(requests.events(),is(2)); - } - - @Test - public void oneEventSize() { - bus.post(RequestEvents.start("data", 100l)); - assertThat(requests.size(),is(1)); - } - @Test - public void twoEventsSize() { - bus.post(RequestEvents.start("data", 100l)); - bus.post(RequestEvents.start("data", 120l)); - assertThat(requests.size(),is(2)); - } - @Test - public void twoIdenticalEventsSize() { - bus.post(RequestEvents.start("data", 100l)); - bus.post(RequestEvents.start("data", 100l)); - assertThat(requests.size(),is(1)); - } - @Test - public void twoEventsOneFinished() { - bus.post(RequestEvents.start("data", 100l)); - bus.post(RequestEvents.start("data", 120l)); - bus.post(RequestEvents.finish("data",120l)); - assertThat(requests.events(),is(2)); - assertThat(requests.size(),is(1)); - } - @Test - public void twoEventsDifferentTypesOneFinishedDefaultTypeIsIgnored() { - requests = new RequestsBeingExecuted(bus,"typeA"); - bus.post(RequestEvents.start("data", 130l)); - bus.post(RequestEvents.start("data", 120l,"typeA","data2")); - bus.post(RequestEvents.finish("data",120l,"typeA")); - assertThat(requests.events(),is(1)); - assertThat(requests.size(),is(0)); - } - @Test - public void testToString() { - bus.post(RequestEvents.start("data", 100l)); - bus.post(RequestEvents.start("data", 120l)); - bus.post(RequestEvents.finish("data",120l)); - - System.out.println(requests.toString()); - assertThat(requests.toString(),containsString("\"removed\":1")); - assertThat(requests.toString(),containsString("\"added\":2")); - - } - - - -} diff --git a/micro-events/src/test/java/com/aol/micro/server/rest/resources/ActiveResourceTest.java b/micro-events/src/test/java/com/aol/micro/server/rest/resources/ActiveResourceTest.java deleted file mode 100644 index fda00e98e..000000000 --- a/micro-events/src/test/java/com/aol/micro/server/rest/resources/ActiveResourceTest.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.aol.micro.server.rest.resources; - -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.Arrays; -import java.util.Map; - -import javax.ws.rs.container.AsyncResponse; - -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.Signature; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.events.JobsBeingExecuted; -import com.aol.micro.server.events.RequestEvents; -import com.aol.micro.server.events.RequestsBeingExecuted; -import com.aol.micro.server.events.ScheduledJob; -import com.aol.micro.server.rest.jackson.JacksonUtil; -import com.google.common.collect.ImmutableMap; -import com.google.common.eventbus.EventBus; - - -public class ActiveResourceTest { - - ActiveResource active; - RequestsBeingExecuted queries1; - RequestsBeingExecuted queries2; - JobsBeingExecuted jobs; - EventBus bus; - @Before - public void setUp() throws Exception { - bus = new EventBus(); - queries1 = new RequestsBeingExecuted(bus,true); - queries2 = new RequestsBeingExecuted(bus,"partition"); - jobs = new JobsBeingExecuted(new EventBus(),10); - active = new ActiveResource(Arrays.asList(queries1, queries2),jobs); - } - - @Test - public void testactiveRequests() { - bus.post(RequestEvents.start("query",1l)); - bus.post(RequestEvents.start("query",2l,"partition",ImmutableMap.of())); - MockAsyncResponse response = new MockAsyncResponse<>(); - active.activeRequests(response,null); - assertThat( convert(response.response()).get("events"),is( 1)); - active.activeRequests(response,"partition"); - assertThat( convert( response.response()).get("events"), is( 1 )); - } - - @Test - public void whenQueriesWithTheSameIdToDifferentTypesEventsIs1ForBoth(){ - bus.post(RequestEvents.start("query",1l)); - bus.post(RequestEvents.start("query",1l,"partition",ImmutableMap.of())); - MockAsyncResponse response = new MockAsyncResponse<>(); - active.activeRequests(response,null); - assertThat( convert( response.response()).get("events"),is( 1)); - active.activeRequests(response,"partition"); - assertThat( convert(response.response() ).get("events"), is( 1 )); - } - @Test - public void whenQueriesWithTheSameIdButSameTypesEventsIs2ButSizeIs1(){ - bus.post(RequestEvents.start("query",1l)); - bus.post(RequestEvents.start("query",1l)); - MockAsyncResponse response = new MockAsyncResponse<>(); - active.activeRequests(response,null); - assertThat( convert( response.response() ).get("events"),is( 2)); - active.activeRequests(response,null); - Map map = convert( response.response()); - assertThat( ((Map)map.get("active") ).size() , is( 1 )); - } - - - @Test - public void testActiveJobs() throws Throwable { - ProceedingJoinPoint pjp = mock(ProceedingJoinPoint.class); - Signature signature = mock(Signature.class); - when(pjp.getSignature()).thenReturn(signature); - when(pjp.getTarget()).thenReturn(this); - when(signature.getDeclaringType()).thenReturn(ScheduledJob.class); - jobs.aroundScheduledJob(pjp); - MockAsyncResponse response = new MockAsyncResponse<>(); - active.activeJobs(response); - assertThat( convert(response.response() ).get("events"),is( 1)); - - } - - private Map convert(String str){ - return JacksonUtil.convertFromJson( str, Map.class); - } -} diff --git a/micro-events/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-events/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-events/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-events/src/test/java/com/oath/micro/server/events/ActiveEventsTest.java b/micro-events/src/test/java/com/oath/micro/server/events/ActiveEventsTest.java new file mode 100644 index 000000000..7e35406ee --- /dev/null +++ b/micro-events/src/test/java/com/oath/micro/server/events/ActiveEventsTest.java @@ -0,0 +1,71 @@ +package com.oath.micro.server.events; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.ImmutableMap; + +public class ActiveEventsTest { + + ActiveEvents activeEvents; + + @Before + public void setup() { + activeEvents = new ActiveEvents(); + } + + @Test + public void namingClasses() { + System.out.println(ActiveEventsTest.class.getCanonicalName()); + System.out.println(ActiveEventsTest.class.getName()); + System.out.println(ActiveEventsTest.class.getSimpleName()); + System.out.println(ActiveEventsTest.class.getPackage() + .getName()); + System.out.println(ActiveEventsTest.class.getTypeName()); + + } + + @Test + public void testOneEvent() { + activeEvents.active("hello", new BaseEventInfo()); + assertThat(activeEvents.events(), is(1)); + } + + @Test + public void testTwoEvents() { + activeEvents.active("hello", new BaseEventInfo()); + activeEvents.active("hello2", new BaseEventInfo()); + assertThat(activeEvents.events(), is(2)); + assertThat(activeEvents.size(), is(2)); + } + + @Test + public void testTwoIdenticalEvents() { + activeEvents.active("hello", new BaseEventInfo()); + activeEvents.active("hello", new BaseEventInfo()); + assertThat(activeEvents.events(), is(2)); + assertThat(activeEvents.size(), is(1)); + } + + @Test + public void testFinishedString() { + activeEvents.active("hello", new BaseEventInfo()); + activeEvents.finished("hello"); + assertThat(activeEvents.events(), is(1)); + assertThat(activeEvents.size(), is(0)); + } + + @Test + public void testFinishedStringImmutableMap() { + activeEvents.active("hello", new BaseEventInfo()); + activeEvents.finished("hello", ImmutableMap.of("hello", "world")); + assertThat(activeEvents.events(), is(1)); + assertThat(activeEvents.size(), is(0)); + assertThat(activeEvents.toString(), containsString("world")); + } + +} diff --git a/micro-events/src/test/java/com/oath/micro/server/events/GenericEventTest.java b/micro-events/src/test/java/com/oath/micro/server/events/GenericEventTest.java new file mode 100644 index 000000000..d2e3e63e1 --- /dev/null +++ b/micro-events/src/test/java/com/oath/micro/server/events/GenericEventTest.java @@ -0,0 +1,47 @@ +package com.oath.micro.server.events; + +import com.google.common.eventbus.EventBus; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.junit.Assert.*; + +@RunWith(MockitoJUnitRunner.class) +public class GenericEventTest { + + @Mock + EventBus bus; + + @Test + public void trigger() throws Exception { + GenericEvent event = GenericEvent.trigger("some-event", bus); + Mockito.verify(bus).post(event); + } + + @Test + public void trigger1() throws Exception { + GenericEvent event = GenericEvent.trigger("some-event", bus, new String[] {"start", "phase1"}); + Mockito.verify(bus).post(event); + } + + @Test + public void trigger2() throws Exception { + GenericEvent event = GenericEvent.trigger("some-event", bus, "data", new String[]{"finish", "terminate"}); + Mockito.verify(bus).post(event); + } + + @Test + public void getData() throws Exception { + GenericEvent event = GenericEvent.trigger("some-event", bus, 10, new String[]{"finish", "terminate"}); + GenericEvent.GenericEventData eventData = event.getData(); + assertEquals("some-event", eventData.getName()); + assertEquals(Integer.valueOf(10), eventData.getData()); + assertNotNull(eventData.getSubTypes()); + assertEquals(eventData.getSubTypes()[0], "finish"); + assertEquals(eventData.getSubTypes()[1], "terminate"); + } + +} \ No newline at end of file diff --git a/micro-events/src/test/java/com/oath/micro/server/events/JobNameTest.java b/micro-events/src/test/java/com/oath/micro/server/events/JobNameTest.java new file mode 100644 index 000000000..87e3ffb9e --- /dev/null +++ b/micro-events/src/test/java/com/oath/micro/server/events/JobNameTest.java @@ -0,0 +1,30 @@ +package com.oath.micro.server.events; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +import org.junit.Test; + +import com.oath.micro.server.events.JobName.Types; + +public class JobNameTest { + JobName simple = Types.SIMPLE.getCreator(); + JobName full = Types.FULL.getCreator(); + JobName one = Types.PACKAGE.getCreator(); + + @Test + public void testSimple() { + assertThat(simple.getType(JobNameTest.class), equalTo("JobNameTest")); + } + + @Test + public void testFull() { + assertThat(full.getType(JobNameTest.class), equalTo("com.oath.micro.server.events.JobNameTest")); + } + + @Test + public void testPackage() { + assertThat(one.getType(JobNameTest.class), equalTo("events.JobNameTest")); + } + +} diff --git a/micro-events/src/test/java/com/oath/micro/server/events/JobsBeingExecutedTest.java b/micro-events/src/test/java/com/oath/micro/server/events/JobsBeingExecutedTest.java new file mode 100644 index 000000000..5f79d9d34 --- /dev/null +++ b/micro-events/src/test/java/com/oath/micro/server/events/JobsBeingExecutedTest.java @@ -0,0 +1,125 @@ +package com.oath.micro.server.events; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.springframework.util.ReflectionUtils.findField; +import static org.springframework.util.ReflectionUtils.getField; +import static org.springframework.util.ReflectionUtils.makeAccessible; + +import java.lang.reflect.Field; +import java.util.concurrent.ConcurrentMap; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import com.google.common.collect.ConcurrentHashMultiset; +import com.google.common.collect.Maps; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +public class JobsBeingExecutedTest { + + JobsBeingExecuted jobs; + + ProceedingJoinPoint pjp; + EventBus bus; + SystemData data; + SystemData incoming; + JobStartEvent start; + JobCompleteEvent complete; + + @Before + public void setUp() throws Exception { + data = SystemData.builder() + .dataMap(Maps.newHashMap()) + .errors(1) + .processed(100) + .build(); + bus = new EventBus(); + bus.register(this); + jobs = new JobsBeingExecuted( + bus, 10, JobName.Types.SIMPLE); + pjp = Mockito.mock(ProceedingJoinPoint.class); + } + + @Subscribe + public void event(SystemData info) { + this.incoming = info; + } + + @Subscribe + public void event(JobStartEvent start) { + this.start = start; + } + + @Subscribe + public void event(JobCompleteEvent complete) { + this.complete = complete; + } + + @Test + public void testExecute() throws Throwable { + Signature sig = Mockito.mock(Signature.class); + Mockito.when(pjp.getSignature()) + .thenReturn(sig); + when(pjp.getTarget()).thenReturn(this); + Mockito.when(sig.getDeclaringType()) + .thenReturn(String.class); + jobs.aroundScheduledJob(pjp); + verify(pjp, times(1)).proceed(); + } + + @Test + public void testExecuteWithEvent() throws Throwable { + scheduleAround(); + verify(pjp, times(1)).proceed(); + assertThat(incoming, is(notNullValue())); + + } + + @Test + public void testExecuteId() throws Throwable { + scheduleAround(); + verify(pjp, times(1)).proceed(); + + assertThat(incoming.getCorrelationId(), containsString("id_String")); + assertThat(start.getCorrelationId(), equalTo(complete.getCorrelationId())); + assertThat(start.getType(), equalTo(complete.getType())); + } + + @Test + public void testStartAndCompleteEventId() throws Throwable { + scheduleAround(); + + assertThat(start.getCorrelationId(), equalTo(complete.getCorrelationId())); + assertThat(start.getType(), equalTo(complete.getType())); + } + + @Test + public void testOverflow() throws Throwable { + when(pjp.getTarget()).thenReturn(this); + Field field = findField(ConcurrentHashMultiset.class, "countMap"); + makeAccessible(field); + ConcurrentMap map = (ConcurrentMap) getField(field, jobs.getStatCounter()); + map.put("java.lang.String", Integer.MAX_VALUE); + testExecute(); + } + + private void scheduleAround() throws Throwable { + Signature sig = Mockito.mock(Signature.class); + when(pjp.getSignature()).thenReturn(sig); + when(sig.getDeclaringType()).thenReturn(String.class); + when(pjp.proceed()).thenReturn(data); + when(pjp.getTarget()).thenReturn(this); + jobs.aroundScheduledJob(pjp); + } +} diff --git a/micro-events/src/test/java/com/oath/micro/server/events/LabelledEventsTest.java b/micro-events/src/test/java/com/oath/micro/server/events/LabelledEventsTest.java new file mode 100644 index 000000000..9bf0a6ad6 --- /dev/null +++ b/micro-events/src/test/java/com/oath/micro/server/events/LabelledEventsTest.java @@ -0,0 +1,62 @@ +package com.oath.micro.server.events; + +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.events.RequestTypes.AddLabelledQuery; +import com.oath.micro.server.events.RequestTypes.RemoveLabelledQuery; +import com.oath.micro.server.events.RequestTypes.RequestData; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + + +public class LabelledEventsTest { + + String query; + String corrId; + String label; + String addData; + + @Before + public void setUp() { + query = "query as string"; + corrId = "1234"; + label = "label"; + addData = "additional data"; + } + + @Test + public void createAddLabelledQuery() { + + AddLabelledQuery userQuery = LabelledEvents.start(query, corrId, label); + RequestData rd = userQuery.getData(); + + assertThat(rd.getQuery(), is(query)); + assertThat(rd.getType(), is(label)); + assertThat(rd.getCorrelationId(), is(corrId)); + } + + @Test + public void createAddLabelledQueryWithAdditionalData() { + + AddLabelledQuery userQuery = LabelledEvents.start(query, corrId, label, addData); + RequestData rd = userQuery.getData(); + + assertThat(rd.getQuery(), is(query)); + assertThat(rd.getType(), is(label)); + assertThat(rd.getCorrelationId(), is(corrId)); + assertThat(rd.getAdditionalData(), is(addData)); + } + + @Test + public void createRemoveLabelledQuery() { + + RemoveLabelledQuery userQuery = LabelledEvents.finish(query, corrId, label); + RequestData rd = userQuery.getData(); + + assertThat(rd.getQuery(), is(query)); + assertThat(rd.getType(), is(label)); + assertThat(rd.getCorrelationId(), is(corrId)); + } +} diff --git a/micro-events/src/test/java/com/aol/micro/server/events/LoggingRateLimiterTest.java b/micro-events/src/test/java/com/oath/micro/server/events/LoggingRateLimiterTest.java similarity index 97% rename from micro-events/src/test/java/com/aol/micro/server/events/LoggingRateLimiterTest.java rename to micro-events/src/test/java/com/oath/micro/server/events/LoggingRateLimiterTest.java index 1dadcd6c1..d5dc14f91 100644 --- a/micro-events/src/test/java/com/aol/micro/server/events/LoggingRateLimiterTest.java +++ b/micro-events/src/test/java/com/oath/micro/server/events/LoggingRateLimiterTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.events; +package com.oath.micro.server.events; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; diff --git a/micro-events/src/test/java/com/oath/micro/server/events/RequestsBeingExecutedTest.java b/micro-events/src/test/java/com/oath/micro/server/events/RequestsBeingExecutedTest.java new file mode 100644 index 000000000..08cd008cf --- /dev/null +++ b/micro-events/src/test/java/com/oath/micro/server/events/RequestsBeingExecutedTest.java @@ -0,0 +1,101 @@ +package com.oath.micro.server.events; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; + +import com.google.common.eventbus.EventBus; + +public class RequestsBeingExecutedTest { + + RequestsBeingExecuted requests; + EventBus bus; + RequestTypes types; + + @Before + public void setup() { + bus = new EventBus(); + requests = new RequestsBeingExecuted(bus); + types = new RequestTypes(bus, true); + types.getMap() + .put("default", requests); + } + + @Test + public void oneEvent() { + bus.post(RequestEvents.start("data", "100")); + assertThat(requests.events(), is(1)); + } + + @Test + public void twoEvents() { + bus.post(RequestEvents.start("data", "100")); + bus.post(RequestEvents.start("data", "120")); + assertThat(requests.events(), is(2)); + } + + @Test + public void twoIdenticalEvents() { + bus.post(RequestEvents.start("data", "100")); + bus.post(RequestEvents.start("data", "100")); + assertThat(requests.events(), is(2)); + } + + @Test + public void oneEventSize() { + bus.post(RequestEvents.start("data", "100")); + assertThat(requests.size(), is(1)); + } + + @Test + public void twoEventsSize() { + bus.post(RequestEvents.start("data", "100")); + bus.post(RequestEvents.start("data", "120")); + assertThat(requests.size(), is(2)); + } + + @Test + public void twoIdenticalEventsSize() { + bus.post(RequestEvents.start("data", "100")); + bus.post(RequestEvents.start("data", "100")); + assertThat(requests.size(), is(1)); + } + + @Test + public void twoEventsOneFinished() { + bus.post(RequestEvents.start("data", "100")); + bus.post(RequestEvents.start("data", "120")); + bus.post(RequestEvents.finish("data", "120")); + assertThat(requests.events(), is(2)); + assertThat(requests.size(), is(1)); + } + + @Test + public void twoEventsDifferentTypesOneFinishedDefaultTypeIsIgnored() { + requests = new RequestsBeingExecuted( + bus, "typeA"); + + types.getMap() + .put("typeA", requests); + bus.post(RequestEvents.start("data", "130")); + bus.post(RequestEvents.start("data", "120", "typeA", "data2")); + bus.post(RequestEvents.finish("data", "120", "typeA")); + assertThat(requests.events(), is(1)); + assertThat(requests.size(), is(0)); + } + + @Test + public void testToString() { + bus.post(RequestEvents.start("data", "100")); + bus.post(RequestEvents.start("data", "120")); + bus.post(RequestEvents.finish("data", "120")); + + assertThat(requests.toString(), containsString("\"removed\":1")); + assertThat(requests.toString(), containsString("\"added\":2")); + + } + +} diff --git a/micro-events/src/test/java/com/oath/micro/server/rest/resources/ActiveResourceTest.java b/micro-events/src/test/java/com/oath/micro/server/rest/resources/ActiveResourceTest.java new file mode 100644 index 000000000..6adfee8fb --- /dev/null +++ b/micro-events/src/test/java/com/oath/micro/server/rest/resources/ActiveResourceTest.java @@ -0,0 +1,103 @@ +package com.oath.micro.server.rest.resources; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Map; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.events.JobName; +import com.oath.micro.server.events.JobsBeingExecuted; +import com.oath.micro.server.events.RequestEvents; +import com.oath.micro.server.events.RequestTypes; +import com.oath.micro.server.events.RequestsBeingExecuted; +import com.oath.micro.server.events.ScheduledJob; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.google.common.collect.ImmutableMap; +import com.google.common.eventbus.EventBus; + +public class ActiveResourceTest { + + ActiveResource active; + RequestsBeingExecuted queries1; + RequestsBeingExecuted queries2; + JobsBeingExecuted jobs; + EventBus bus; + + @Before + public void setUp() throws Exception { + bus = new EventBus(); + queries1 = new RequestsBeingExecuted( + bus); + queries2 = new RequestsBeingExecuted( + bus, "partition"); + jobs = new JobsBeingExecuted( + new EventBus(), 10, JobName.Types.SIMPLE); + RequestTypes types = new RequestTypes( + bus, true); + types.getMap() + .put(queries1.getType(), queries1); + types.getMap() + .put(queries2.getType(), queries2); + active = new ActiveResource( + types, jobs); + } + + @Test + public void testactiveRequests() { + bus.post(RequestEvents.start("query", "1")); + bus.post(RequestEvents.start("query", "2", "partition", ImmutableMap.of())); + MockAsyncResponse response = new MockAsyncResponse<>(); + active.activeRequests(response, null); + assertThat(convert(response.response()).get("events"), is(1)); + active.activeRequests(response, "partition"); + assertThat(convert(response.response()).get("events"), is(1)); + } + + @Test + public void whenQueriesWithTheSameIdToDifferentTypesEventsIs1ForBoth() { + bus.post(RequestEvents.start("query", "1")); + bus.post(RequestEvents.start("query", "1", "partition", ImmutableMap.of())); + MockAsyncResponse response = new MockAsyncResponse<>(); + active.activeRequests(response, null); + assertThat(convert(response.response()).get("events"), is(1)); + active.activeRequests(response, "partition"); + assertThat(convert(response.response()).get("events"), is(1)); + } + + @Test + public void whenQueriesWithTheSameIdButSameTypesEventsIs2ButSizeIs1() { + bus.post(RequestEvents.start("query", "1")); + bus.post(RequestEvents.start("query", "1")); + MockAsyncResponse response = new MockAsyncResponse<>(); + active.activeRequests(response, null); + assertThat(convert(response.response()).get("events"), is(2)); + active.activeRequests(response, null); + Map map = convert(response.response()); + assertThat(((Map) map.get("active")).size(), is(1)); + } + + @Test + public void testActiveJobs() throws Throwable { + ProceedingJoinPoint pjp = mock(ProceedingJoinPoint.class); + Signature signature = mock(Signature.class); + when(pjp.getSignature()).thenReturn(signature); + when(pjp.getTarget()).thenReturn(this); + when(signature.getDeclaringType()).thenReturn(ScheduledJob.class); + jobs.aroundScheduledJob(pjp); + MockAsyncResponse response = new MockAsyncResponse<>(); + active.activeJobs(response); + assertThat(convert(response.response()).get("events"), is(1)); + + } + + private Map convert(String str) { + return JacksonUtil.convertFromJson(str, Map.class); + } +} diff --git a/micro-events/src/test/java/com/aol/micro/server/rest/resources/ManifestResourceTest.java b/micro-events/src/test/java/com/oath/micro/server/rest/resources/ManifestResourceTest.java similarity index 96% rename from micro-events/src/test/java/com/aol/micro/server/rest/resources/ManifestResourceTest.java rename to micro-events/src/test/java/com/oath/micro/server/rest/resources/ManifestResourceTest.java index 67c564b57..af1f6af4d 100644 --- a/micro-events/src/test/java/com/aol/micro/server/rest/resources/ManifestResourceTest.java +++ b/micro-events/src/test/java/com/oath/micro/server/rest/resources/ManifestResourceTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.rest.resources; +package com.oath.micro.server.rest.resources; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; diff --git a/micro-events/src/test/java/com/aol/micro/server/rest/resources/MockAsyncResponse.java b/micro-events/src/test/java/com/oath/micro/server/rest/resources/MockAsyncResponse.java similarity index 96% rename from micro-events/src/test/java/com/aol/micro/server/rest/resources/MockAsyncResponse.java rename to micro-events/src/test/java/com/oath/micro/server/rest/resources/MockAsyncResponse.java index 9412f05d4..4b0f63f42 100644 --- a/micro-events/src/test/java/com/aol/micro/server/rest/resources/MockAsyncResponse.java +++ b/micro-events/src/test/java/com/oath/micro/server/rest/resources/MockAsyncResponse.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.rest.resources; +package com.oath.micro.server.rest.resources; import java.util.Collection; import java.util.Date; @@ -9,8 +9,6 @@ import javax.ws.rs.container.AsyncResponse; import javax.ws.rs.container.TimeoutHandler; -import lombok.Getter; - public class MockAsyncResponse implements AsyncResponse { volatile Object response; diff --git a/micro-events/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-events/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-events/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-general-exception-mapper/README.md b/micro-general-exception-mapper/README.md new file mode 100644 index 000000000..f1679b64a --- /dev/null +++ b/micro-general-exception-mapper/README.md @@ -0,0 +1,53 @@ +# General Exception Mapper Plugin Plugin + +[Example General Exception Mapper Apps](https://github.com/aol/micro-server/tree/master/micro-general-exception-mapper/src/test/java/app) + +Plugin that adds general exception mapping capability + +## The default mappings + +```java +EOFException.class -> Status.BAD_REQUEST +JsonProcessingException.class -> Status.BAD_REQUEST +``` + +## Custom Extensions + +Implement the interface com.aol.micro.server.general.exception.mapper.ExtensionMapOfExceptionsToErrorCodes in one of your Spring Beans. + +### Example custom extension + +```java +@Component +public class MappingExtension implements ExtensionMapOfExceptionsToErrorCodes { + + @Override + public LinkedHashMap, Tuple2> getErrorMappings() { + LinkedHashMap, Tuple2> map = new LinkedHashMap<>(); + map.put(MyException.class, Tuple.tuple("my-error",Status.BAD_GATEWAY)); + return map; + } + +} +``` + + + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-general-exception-mapper/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-general-exception-mapper) + +Simply add to the classpath + +Maven +```xml + + com.oath.microservices + micro-general-exception-mapper + x.yz + +``` +Gradle +```groovy + compile 'com.oath.microservices:micro-general-exception-mapper:x.yz' +``` diff --git a/micro-general-exception-mapper/build.gradle b/micro-general-exception-mapper/build.gradle index a286b2fed..da30fb0ef 100644 --- a/micro-general-exception-mapper/build.gradle +++ b/micro-general-exception-mapper/build.gradle @@ -1,68 +1,64 @@ description = 'micro-general-exception-mapper' -dependencies { - - compile project(':micro-jersey') - compile project(':micro-jackson-configuration') - testCompile group: 'org.hamcrest', name: 'hamcrest-all', version:hamcrestVersion - testCompile project(':micro-grizzly-with-jersey') - - testCompile group: 'org.glassfish.jersey.core', name: 'jersey-client', version:"$jerseyVersion" - - +dependencies { + compile project(':micro-jersey') + compile project(':micro-jackson-configuration') + testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: hamcrestVersion + testCompile project(':micro-grizzly-with-jersey') + testCompile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: "$jerseyVersion" } modifyPom { - project { - name 'Microserver Jersey general exception mapper' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver Jersey general exception mapper' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-general-exception-mapper' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } - groupId 'com.aol.microservices' - artifactId 'micro-general-exception-mapper' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - } - - } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-general-exception-mapper/readme.md b/micro-general-exception-mapper/readme.md deleted file mode 100644 index 7fab6f1c7..000000000 --- a/micro-general-exception-mapper/readme.md +++ /dev/null @@ -1,53 +0,0 @@ -# General Exception Mapper Plugin Plugin - -[Example General Exception Mapper Apps](https://github.com/aol/micro-server/tree/master/micro-general-exception-mapper/src/test/java/app) - -Plugin that adds general exception mapping capability - -## The default mappings - -```java -EOFException.class -> Status.BAD_REQUEST -JsonProcessingException.class -> Status.BAD_REQUEST -``` - -## Custom Extensions - -Implement the interface com.aol.micro.server.general.exception.mapper.ExtensionMapOfExceptionsToErrorCodes in one of your Spring Beans. - -### Example custom extension - -```java -@Component -public class MappingExtension implements ExtensionMapOfExceptionsToErrorCodes { - - @Override - public LinkedHashMap, Tuple2> getErrorMappings() { - LinkedHashMap, Tuple2> map = new LinkedHashMap<>(); - map.put(MyException.class, Tuple.tuple("my-error",Status.BAD_GATEWAY)); - return map; - } - -} -``` - - - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-general-exception-mapper/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-general-exception-mapper) - -Simply add to the classpath - -Maven -```xml - - com.aol.microservices - micro-general-exception-mapper - x.yz - -``` -Gradle -```groovy - compile 'com.aol.microservices:micro-general-exception-mapper:x.yz' -``` diff --git a/micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/ExceptionMapperPlugin.java b/micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/ExceptionMapperPlugin.java deleted file mode 100644 index 532472870..000000000 --- a/micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/ExceptionMapperPlugin.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.aol.micro.server.general.exception.mapper; - -import java.util.HashSet; -import java.util.Set; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; - -/** - * - * Collections of Spring configuration classes (Classes annotated with @Configuration) - * that configure various useful pieces of functionality - such as property file loading, - * datasources, scheduling etc - * - * @author johnmcclean - * - */ -public class ExceptionMapperPlugin implements Plugin{ - - @Override - public PSetX jaxRsPackages() { - return PSetX.of("com.aol.micro.server.general.exception.mapper"); - - } - - @Override - public PSetX springClasses() { - return PSetX.of(MapOfExceptionsToErrorCodes.class); - } - - - - - - -} diff --git a/micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/GeneralExceptionMapper.java b/micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/GeneralExceptionMapper.java deleted file mode 100644 index bb855464f..000000000 --- a/micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/GeneralExceptionMapper.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.aol.micro.server.general.exception.mapper; - - -import static org.jooq.lambda.tuple.Tuple.tuple; - -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; -import javax.ws.rs.ext.ExceptionMapper; -import javax.ws.rs.ext.Provider; - -import org.jooq.lambda.tuple.Tuple; -import org.jooq.lambda.tuple.Tuple2; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Provider -public class GeneralExceptionMapper implements ExceptionMapper { - - final Logger logger; - - GeneralExceptionMapper(Logger logger){ - this.logger = logger; - } - - public GeneralExceptionMapper(){ - this.logger = LoggerFactory.getLogger(GeneralExceptionMapper.class);; - } - - - Map, Tuple2> mapOfExceptionsToErrorCodes = MapOfExceptionsToErrorCodes.getMergedMappings(); - - private Optional> find(Class c) { - for (Map.Entry, Tuple2> entry : this.mapOfExceptionsToErrorCodes.entrySet()) { - if (entry.getKey().isAssignableFrom(c)) { - return Optional.ofNullable(entry.getValue()); - } - } - return Optional.empty(); - } - - @Override - public Response toResponse(final Exception ex) { - - final String errorTrackingId = UUID.randomUUID().toString(); - - Tuple2 error = new Tuple2(MapOfExceptionsToErrorCodes.INTERNAL_SERVER_ERROR, Status.INTERNAL_SERVER_ERROR); - - Optional> errorFromLookup = find(ex.getClass()); - - if (errorFromLookup.isPresent()) { - error = errorFromLookup.get(); - - } else { - if(ex instanceof javax.ws.rs.WebApplicationException){ - javax.ws.rs.WebApplicationException rsEx = ((javax.ws.rs.WebApplicationException)ex); - error = tuple(rsEx.getResponse().getStatusInfo().getReasonPhrase(),Status.fromStatusCode(rsEx.getResponse().getStatus())); - - } - logger.error( String.format("%s Error id: %s", error.v1(), errorTrackingId) + ex.getMessage(), ex); - } - logger.warn( String.format("%s Error id: %s", error.v1(), errorTrackingId)); - - return Response.status(error.v2()) - .entity(new ExceptionWrapper(error.v1(), String.format("Error id: %s %s", errorTrackingId, ex.getMessage()))) - .type(MediaType.APPLICATION_JSON_TYPE).build(); - } -} diff --git a/micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/ExceptionMapperPlugin.java b/micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/ExceptionMapperPlugin.java new file mode 100644 index 000000000..48909dbc5 --- /dev/null +++ b/micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/ExceptionMapperPlugin.java @@ -0,0 +1,31 @@ +package com.oath.micro.server.general.exception.mapper; + +import java.util.Set; + + +import com.oath.micro.server.Plugin; +import cyclops.reactive.collections.mutable.SetX; + +/** + * + * Collections of Spring configuration classes (Classes annotated with @Configuration) + * that configure various useful pieces of functionality - such as property file loading, + * datasources, scheduling etc + * + * @author johnmcclean + * + */ +public class ExceptionMapperPlugin implements Plugin{ + + @Override + public Set jaxRsPackages() { + return SetX.of("com.oath.micro.server.general.exception.mapper"); + + } + + @Override + public Set springClasses() { + return SetX.of(MapOfExceptionsToErrorCodes.class); + } + +} diff --git a/micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/ExceptionWrapper.java b/micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/ExceptionWrapper.java similarity index 92% rename from micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/ExceptionWrapper.java rename to micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/ExceptionWrapper.java index 01fdd75b4..4dfde149c 100644 --- a/micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/ExceptionWrapper.java +++ b/micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/ExceptionWrapper.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.general.exception.mapper; +package com.oath.micro.server.general.exception.mapper; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/ExtensionMapOfExceptionsToErrorCodes.java b/micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/ExtensionMapOfExceptionsToErrorCodes.java similarity index 90% rename from micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/ExtensionMapOfExceptionsToErrorCodes.java rename to micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/ExtensionMapOfExceptionsToErrorCodes.java index e7b00f23f..416034f45 100644 --- a/micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/ExtensionMapOfExceptionsToErrorCodes.java +++ b/micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/ExtensionMapOfExceptionsToErrorCodes.java @@ -1,10 +1,10 @@ -package com.aol.micro.server.general.exception.mapper; +package com.oath.micro.server.general.exception.mapper; import java.util.LinkedHashMap; import javax.ws.rs.core.Response.Status; -import org.jooq.lambda.tuple.Tuple2; +import cyclops.data.tuple.Tuple2; /** * Create a Spring that implements this interface to define your own mappings between diff --git a/micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/GeneralExceptionMapper.java b/micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/GeneralExceptionMapper.java new file mode 100644 index 000000000..e312faf28 --- /dev/null +++ b/micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/GeneralExceptionMapper.java @@ -0,0 +1,79 @@ +package com.oath.micro.server.general.exception.mapper; + +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + +import cyclops.data.tuple.Tuple2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import static cyclops.data.tuple.Tuple.tuple; + +@Service +@Provider +public class GeneralExceptionMapper implements ExceptionMapper { + + final Logger logger; + private Boolean showDetails; + + GeneralExceptionMapper(Logger logger, boolean showDetails){ + this.logger = logger; + this.showDetails = showDetails; + } + + @Autowired + GeneralExceptionMapper(@Value("${micro.general.exception.mapper.details:true}") Boolean showDetails){ + this(LoggerFactory.getLogger(GeneralExceptionMapper.class), showDetails); + } + + Map, Tuple2> mapOfExceptionsToErrorCodes = MapOfExceptionsToErrorCodes.getMergedMappings(); + + private Optional> find(Class c) { + for (Map.Entry, Tuple2> entry : this.mapOfExceptionsToErrorCodes.entrySet()) { + if (entry.getKey().isAssignableFrom(c)) { + return Optional.ofNullable(entry.getValue()); + } + } + return Optional.empty(); + } + + @Override + public Response toResponse(final Exception ex) { + + final String errorTrackingId = UUID.randomUUID().toString(); + + Tuple2 error = new Tuple2<>(MapOfExceptionsToErrorCodes.INTERNAL_SERVER_ERROR, Status.INTERNAL_SERVER_ERROR); + + Optional> errorFromLookup = find(ex.getClass()); + + if (errorFromLookup.isPresent()) { + error = errorFromLookup.get(); + } else { + if(ex instanceof javax.ws.rs.WebApplicationException){ + javax.ws.rs.WebApplicationException rsEx = ((javax.ws.rs.WebApplicationException)ex); + error = tuple(rsEx.getResponse().getStatusInfo().getReasonPhrase(),Status.fromStatusCode(rsEx.getResponse().getStatus())); + } + } + logger.error(String.format("%s Error id: %s, %s", error._1(), errorTrackingId, ex.getMessage()), ex); + + Response.ResponseBuilder responseBuilder = Response.status(error._2()).type(MediaType.APPLICATION_JSON_TYPE); + + if (showDetails) { + responseBuilder.entity(new ExceptionWrapper(error._1(), String.format("Error id: %s %s", errorTrackingId, ex.getMessage()))); + } else { + responseBuilder.entity(new ExceptionWrapper(MapOfExceptionsToErrorCodes.INTERNAL_SERVER_ERROR, errorTrackingId)); + } + + return responseBuilder.build(); + } +} diff --git a/micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/MapOfExceptionsToErrorCodes.java b/micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/MapOfExceptionsToErrorCodes.java similarity index 89% rename from micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/MapOfExceptionsToErrorCodes.java rename to micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/MapOfExceptionsToErrorCodes.java index b96ca98e3..4dc0ca766 100644 --- a/micro-general-exception-mapper/src/main/java/com/aol/micro/server/general/exception/mapper/MapOfExceptionsToErrorCodes.java +++ b/micro-general-exception-mapper/src/main/java/com/oath/micro/server/general/exception/mapper/MapOfExceptionsToErrorCodes.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.general.exception.mapper; +package com.oath.micro.server.general.exception.mapper; import java.io.EOFException; import java.util.LinkedHashMap; @@ -7,7 +7,7 @@ import javax.ws.rs.core.Response.Status; -import org.jooq.lambda.tuple.Tuple2; +import cyclops.data.tuple.Tuple2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -27,8 +27,8 @@ public class MapOfExceptionsToErrorCodes { private static LinkedHashMap, Tuple2> createMap(){ LinkedHashMap, Tuple2> mapOfExceptionsToErrorCodes = new LinkedHashMap<>(); - mapOfExceptionsToErrorCodes.put(EOFException.class, new Tuple2(EMPTY_REQUEST, Status.BAD_REQUEST)); - mapOfExceptionsToErrorCodes.put(JsonProcessingException.class, new Tuple2(JSON_PROCESSING_EXCEPTION, Status.BAD_REQUEST)); + mapOfExceptionsToErrorCodes.put(EOFException.class, new Tuple2<>(EMPTY_REQUEST, Status.BAD_REQUEST)); + mapOfExceptionsToErrorCodes.put(JsonProcessingException.class, new Tuple2<>(JSON_PROCESSING_EXCEPTION, Status.BAD_REQUEST)); return mapOfExceptionsToErrorCodes; } diff --git a/micro-general-exception-mapper/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-general-exception-mapper/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 90ea5c83c..000000000 --- a/micro-general-exception-mapper/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.general.exception.mapper.ExceptionMapperPlugin \ No newline at end of file diff --git a/micro-general-exception-mapper/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-general-exception-mapper/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..7d03f9d74 --- /dev/null +++ b/micro-general-exception-mapper/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.general.exception.mapper.ExceptionMapperPlugin \ No newline at end of file diff --git a/micro-general-exception-mapper/src/test/java/app/custom/com/aol/micro/server/copy/CustomRunnerTest.java b/micro-general-exception-mapper/src/test/java/app/custom/com/aol/micro/server/copy/CustomRunnerTest.java deleted file mode 100644 index 28d1a7705..000000000 --- a/micro-general-exception-mapper/src/test/java/app/custom/com/aol/micro/server/copy/CustomRunnerTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package app.custom.com.aol.micro.server.copy; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class CustomRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping").getStatus(),is(502)); - - - } - - - -} diff --git a/micro-general-exception-mapper/src/test/java/app/custom/com/aol/micro/server/copy/CustomStatusResource.java b/micro-general-exception-mapper/src/test/java/app/custom/com/aol/micro/server/copy/CustomStatusResource.java deleted file mode 100644 index 770f84495..000000000 --- a/micro-general-exception-mapper/src/test/java/app/custom/com/aol/micro/server/copy/CustomStatusResource.java +++ /dev/null @@ -1,21 +0,0 @@ -package app.custom.com.aol.micro.server.copy; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import com.aol.cyclops.util.ExceptionSoftener; -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class CustomStatusResource { - - @GET - @Path("/ping") - public String ping() { - throw ExceptionSoftener.throwSoftenedException( new MyException()); - - } - - -} \ No newline at end of file diff --git a/micro-general-exception-mapper/src/test/java/app/custom/com/aol/micro/server/copy/MappingExtension.java b/micro-general-exception-mapper/src/test/java/app/custom/com/aol/micro/server/copy/MappingExtension.java deleted file mode 100644 index b68ab467d..000000000 --- a/micro-general-exception-mapper/src/test/java/app/custom/com/aol/micro/server/copy/MappingExtension.java +++ /dev/null @@ -1,23 +0,0 @@ -package app.custom.com.aol.micro.server.copy; - -import java.util.LinkedHashMap; - -import javax.ws.rs.core.Response.Status; - -import org.jooq.lambda.tuple.Tuple; -import org.jooq.lambda.tuple.Tuple2; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.general.exception.mapper.ExtensionMapOfExceptionsToErrorCodes; - -@Component -public class MappingExtension implements ExtensionMapOfExceptionsToErrorCodes { - - @Override - public LinkedHashMap, Tuple2> getErrorMappings() { - LinkedHashMap, Tuple2> map = new LinkedHashMap<>(); - map.put(MyException.class, Tuple.tuple("my-error",Status.BAD_GATEWAY)); - return map; - } - -} diff --git a/micro-general-exception-mapper/src/test/java/app/custom/com/aol/micro/server/copy/MyException.java b/micro-general-exception-mapper/src/test/java/app/custom/com/aol/micro/server/copy/MyException.java deleted file mode 100644 index 137bf5086..000000000 --- a/micro-general-exception-mapper/src/test/java/app/custom/com/aol/micro/server/copy/MyException.java +++ /dev/null @@ -1,5 +0,0 @@ -package app.custom.com.aol.micro.server.copy; - -public class MyException extends Exception { - -} diff --git a/micro-general-exception-mapper/src/test/java/app/custom/com/oath/micro/server/copy/CustomRunnerTest.java b/micro-general-exception-mapper/src/test/java/app/custom/com/oath/micro/server/copy/CustomRunnerTest.java new file mode 100644 index 000000000..011fa581b --- /dev/null +++ b/micro-general-exception-mapper/src/test/java/app/custom/com/oath/micro/server/copy/CustomRunnerTest.java @@ -0,0 +1,54 @@ +package app.custom.com.oath.micro.server.copy; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class CustomRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping").getStatus(),is(502)); + + + } + + + +} diff --git a/micro-general-exception-mapper/src/test/java/app/custom/com/oath/micro/server/copy/CustomStatusResource.java b/micro-general-exception-mapper/src/test/java/app/custom/com/oath/micro/server/copy/CustomStatusResource.java new file mode 100644 index 000000000..d21b897ef --- /dev/null +++ b/micro-general-exception-mapper/src/test/java/app/custom/com/oath/micro/server/copy/CustomStatusResource.java @@ -0,0 +1,22 @@ +package app.custom.com.oath.micro.server.copy; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + + +import com.oath.cyclops.util.ExceptionSoftener; +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class CustomStatusResource { + + @GET + @Path("/ping") + public String ping() { + throw ExceptionSoftener.throwSoftenedException( new MyException()); + + } + + +} \ No newline at end of file diff --git a/micro-general-exception-mapper/src/test/java/app/custom/com/oath/micro/server/copy/MappingExtension.java b/micro-general-exception-mapper/src/test/java/app/custom/com/oath/micro/server/copy/MappingExtension.java new file mode 100644 index 000000000..9b7d152ac --- /dev/null +++ b/micro-general-exception-mapper/src/test/java/app/custom/com/oath/micro/server/copy/MappingExtension.java @@ -0,0 +1,23 @@ +package app.custom.com.oath.micro.server.copy; + +import java.util.LinkedHashMap; + +import javax.ws.rs.core.Response.Status; + +import cyclops.data.tuple.Tuple; +import cyclops.data.tuple.Tuple2; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.general.exception.mapper.ExtensionMapOfExceptionsToErrorCodes; + +@Component +public class MappingExtension implements ExtensionMapOfExceptionsToErrorCodes { + + @Override + public LinkedHashMap, Tuple2> getErrorMappings() { + LinkedHashMap, Tuple2> map = new LinkedHashMap<>(); + map.put(MyException.class, Tuple.tuple("my-error",Status.BAD_GATEWAY)); + return map; + } + +} diff --git a/micro-general-exception-mapper/src/test/java/app/custom/com/oath/micro/server/copy/MyException.java b/micro-general-exception-mapper/src/test/java/app/custom/com/oath/micro/server/copy/MyException.java new file mode 100644 index 000000000..18bd13624 --- /dev/null +++ b/micro-general-exception-mapper/src/test/java/app/custom/com/oath/micro/server/copy/MyException.java @@ -0,0 +1,5 @@ +package app.custom.com.oath.micro.server.copy; + +public class MyException extends Exception { + +} diff --git a/micro-general-exception-mapper/src/test/java/app/error/com/aol/micro/server/ErrorRunnerTest.java b/micro-general-exception-mapper/src/test/java/app/error/com/aol/micro/server/ErrorRunnerTest.java deleted file mode 100644 index bc2e8da7d..000000000 --- a/micro-general-exception-mapper/src/test/java/app/error/com/aol/micro/server/ErrorRunnerTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package app.error.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class ErrorRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping").getStatus(),is(400)); - - - } - - - -} diff --git a/micro-general-exception-mapper/src/test/java/app/error/com/aol/micro/server/ErrorStatusResource.java b/micro-general-exception-mapper/src/test/java/app/error/com/aol/micro/server/ErrorStatusResource.java deleted file mode 100644 index 726badba6..000000000 --- a/micro-general-exception-mapper/src/test/java/app/error/com/aol/micro/server/ErrorStatusResource.java +++ /dev/null @@ -1,23 +0,0 @@ -package app.error.com.aol.micro.server; - -import java.io.EOFException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import com.aol.cyclops.util.ExceptionSoftener; -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class ErrorStatusResource { - - @GET - @Path("/ping") - public String ping() { - throw ExceptionSoftener.throwSoftenedException( new EOFException("hello world")); - - } - - -} \ No newline at end of file diff --git a/micro-general-exception-mapper/src/test/java/app/error/com/oath/micro/server/ErrorDetailsRunnerTest.java b/micro-general-exception-mapper/src/test/java/app/error/com/oath/micro/server/ErrorDetailsRunnerTest.java new file mode 100644 index 000000000..4d370b920 --- /dev/null +++ b/micro-general-exception-mapper/src/test/java/app/error/com/oath/micro/server/ErrorDetailsRunnerTest.java @@ -0,0 +1,53 @@ +package app.error.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +import javax.ws.rs.core.Response; + +@Microserver +public class ErrorDetailsRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + Response response = rest.get("http://localhost:8080/simple-app/status/ping"); + assertThat(response.getStatus(),is(400)); + assertThat(response.readEntity(String.class), containsString("{\"errorCode\":\"EMPTY_REQUEST\",\"message\":\"Error id:")); + } +} diff --git a/micro-general-exception-mapper/src/test/java/app/error/com/oath/micro/server/ErrorNoDetailsRunnerTest.java b/micro-general-exception-mapper/src/test/java/app/error/com/oath/micro/server/ErrorNoDetailsRunnerTest.java new file mode 100644 index 000000000..8c6861618 --- /dev/null +++ b/micro-general-exception-mapper/src/test/java/app/error/com/oath/micro/server/ErrorNoDetailsRunnerTest.java @@ -0,0 +1,49 @@ +package app.error.com.oath.micro.server; + + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.ws.rs.core.Response; +import java.util.Arrays; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +@Microserver(properties = {"micro.general.exception.mapper.details", "false"}) +public class ErrorNoDetailsRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest(){ + Response response = rest.get("http://localhost:8080/simple-app/status/ping"); + assertThat(response.getStatus(),is(400)); + assertThat(response.readEntity(String.class), containsString("{\"errorCode\":\"INTERNAL_SERVER_ERROR\",\"message\":")); + } +} diff --git a/micro-general-exception-mapper/src/test/java/app/error/com/oath/micro/server/ErrorStatusResource.java b/micro-general-exception-mapper/src/test/java/app/error/com/oath/micro/server/ErrorStatusResource.java new file mode 100644 index 000000000..b32359827 --- /dev/null +++ b/micro-general-exception-mapper/src/test/java/app/error/com/oath/micro/server/ErrorStatusResource.java @@ -0,0 +1,24 @@ +package app.error.com.oath.micro.server; + +import java.io.EOFException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + + +import com.oath.cyclops.util.ExceptionSoftener; +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class ErrorStatusResource { + + @GET + @Path("/ping") + public String ping() { + throw ExceptionSoftener.throwSoftenedException( new EOFException("hello world")); + + } + + +} \ No newline at end of file diff --git a/micro-general-exception-mapper/src/test/java/com/aol/micro/server/general/exception/mapper/MyLocalException.java b/micro-general-exception-mapper/src/test/java/com/aol/micro/server/general/exception/mapper/MyLocalException.java deleted file mode 100644 index 95984f518..000000000 --- a/micro-general-exception-mapper/src/test/java/com/aol/micro/server/general/exception/mapper/MyLocalException.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.aol.micro.server.general.exception.mapper; - -public class MyLocalException extends Exception { - -} diff --git a/micro-general-exception-mapper/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-general-exception-mapper/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index eeaab558c..000000000 --- a/micro-general-exception-mapper/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public Response get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(); - - } - - - - -} diff --git a/micro-general-exception-mapper/src/test/java/com/aol/micro/server/general/exception/mapper/GeneralExceptionMapperTest.java b/micro-general-exception-mapper/src/test/java/com/oath/micro/server/general/exception/mapper/GeneralExceptionMapperTest.java similarity index 91% rename from micro-general-exception-mapper/src/test/java/com/aol/micro/server/general/exception/mapper/GeneralExceptionMapperTest.java rename to micro-general-exception-mapper/src/test/java/com/oath/micro/server/general/exception/mapper/GeneralExceptionMapperTest.java index d230bf54f..080ab3f29 100644 --- a/micro-general-exception-mapper/src/test/java/com/aol/micro/server/general/exception/mapper/GeneralExceptionMapperTest.java +++ b/micro-general-exception-mapper/src/test/java/com/oath/micro/server/general/exception/mapper/GeneralExceptionMapperTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.general.exception.mapper; +package com.oath.micro.server.general.exception.mapper; import static org.hamcrest.Matchers.is; @@ -19,8 +19,6 @@ import org.junit.Test; import org.slf4j.Logger; -import app.custom.com.aol.micro.server.copy.MyException; - import com.fasterxml.jackson.core.JsonProcessingException; public class GeneralExceptionMapperTest { @@ -30,8 +28,8 @@ public class GeneralExceptionMapperTest { @Before public void setUp() throws Exception { - mapper = new GeneralExceptionMapper(); mockLogger = mock(Logger.class); + mapper = new GeneralExceptionMapper(mockLogger, true); } @Test @@ -65,7 +63,7 @@ public void whenRuntimeException_thenInternalServerError() { @Test public void whenJacksonException_thenNotInternalServerError_NoErrorsLogged() { - mapper= new GeneralExceptionMapper(mockLogger); + mapper= new GeneralExceptionMapper(mockLogger, true); assertThat(mapper.toResponse(new MyLocalException()).getStatus(), is((Status.INTERNAL_SERVER_ERROR.getStatusCode()))); verify(mockLogger, times(0)).error(any(String.class), any(Object[].class)); verify(mockLogger, times(0)).error(any(String.class), any(Throwable.class), any(Object[].class)); diff --git a/micro-general-exception-mapper/src/test/java/com/oath/micro/server/general/exception/mapper/MyLocalException.java b/micro-general-exception-mapper/src/test/java/com/oath/micro/server/general/exception/mapper/MyLocalException.java new file mode 100644 index 000000000..c4622989c --- /dev/null +++ b/micro-general-exception-mapper/src/test/java/com/oath/micro/server/general/exception/mapper/MyLocalException.java @@ -0,0 +1,5 @@ +package com.oath.micro.server.general.exception.mapper; + +public class MyLocalException extends Exception { + +} diff --git a/micro-general-exception-mapper/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-general-exception-mapper/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..3749ecb41 --- /dev/null +++ b/micro-general-exception-mapper/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,29 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +public class RestAgent { + + + public Response get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(); + + } + + + + +} diff --git a/micro-grizzly-with-jersey/README.md b/micro-grizzly-with-jersey/README.md new file mode 100644 index 000000000..85639341f --- /dev/null +++ b/micro-grizzly-with-jersey/README.md @@ -0,0 +1,23 @@ +# Grizzly, Jersey and Microserver together + +[Example Grizzly & Jersey Apps](https://github.com/aol/micro-server/tree/master/micro-grizzly/src/test/java/app) + +Convenience module that packages Grizzly, Jersey, Jackson and Microserver together + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-grizzly-with-jersey/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-grizzly-with-jersey) + +Simply add to the classpath + +Maven + + + com.oath.microservices + micro-grizzly-with-jersey + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-grizzly-with-jersey:x.yz' diff --git a/micro-grizzly-with-jersey/build.gradle b/micro-grizzly-with-jersey/build.gradle index 667e9d86d..a796317f5 100644 --- a/micro-grizzly-with-jersey/build.gradle +++ b/micro-grizzly-with-jersey/build.gradle @@ -1,67 +1,65 @@ description = 'micro-grizzly-with-jersey' -dependencies { - - compile project(':micro-core') - compile project(':micro-grizzly') - compile project(':micro-jersey') - compile project(':micro-jackson-configuration') - testCompile group: 'org.hamcrest', name: 'hamcrest-all', version:hamcrestVersion - - +dependencies { + compile project(':micro-core') + compile project(':micro-grizzly') + compile project(':micro-jersey') + compile project(':micro-jackson-configuration') + testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: hamcrestVersion + testCompile "com.oath.cyclops:cyclops-futurestream:$cyclopsVersion" } modifyPom { - project { - name 'Microserver Grizzly With Jersey' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver Grizzly With Jersey' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-grizzly-with-jersey' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } - groupId 'com.aol.microservices' - artifactId 'micro-grizzly-with-jersey' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - } - - } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-grizzly-with-jersey/readme.md b/micro-grizzly-with-jersey/readme.md deleted file mode 100644 index 9a0475638..000000000 --- a/micro-grizzly-with-jersey/readme.md +++ /dev/null @@ -1,23 +0,0 @@ -# Grizzly, Jersey and Microserver together - -[Example Grizzly & Jersey Apps](https://github.com/aol/micro-server/tree/master/micro-grizzly/src/test/java/app) - -Convenience module that packages Grizzly, Jersey, Jackson and Microserver together - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-grizzly-with-jersey/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-grizzly-with-jersey) - -Simply add to the classpath - -Maven - - - com.aol.microservices - micro-grizzly-with-jersey - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-grizzly-with-jersey:x.yz' \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java b/micro-grizzly-with-jersey/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java deleted file mode 100644 index 979b5fbf5..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java +++ /dev/null @@ -1,57 +0,0 @@ -package app.async.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.io.IOException; -import java.util.Properties; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.spring.properties.PropertyFileConfig; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class AsyncAppRunner { - - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( ()-> "async-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - Thread.sleep(2000); - - assertThat(rest.get("http://localhost:8080/async-app/async/expensive"),is(";test!;test!;test!")); - - } - - @Test - public void loadProperties() throws IOException{ - - Properties props = new PropertyFileConfig(true).propertyFactory() ; - assertThat(props.getProperty("test"),is("hello world")); - } - - - -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/async/com/aol/micro/server/AsyncResource.java b/micro-grizzly-with-jersey/src/test/java/app/async/com/aol/micro/server/AsyncResource.java deleted file mode 100644 index d87c018d6..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/async/com/aol/micro/server/AsyncResource.java +++ /dev/null @@ -1,56 +0,0 @@ -package app.async.com.aol.micro.server; - -import java.util.Arrays; -import java.util.List; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.container.Suspended; - -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.testing.RestAgent; - -@Path("/async") -@Component -public class AsyncResource implements RestResource{ - - private final SimpleReact simpleReact =new SimpleReact(); - private final List urls = Arrays.asList("http://localhost:8080/async-app/async/ping2", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping"); - - private final RestAgent client = new RestAgent(); - - @GET - @Path("/expensive") - @Produces("text/plain") - public void expensive(@Suspended AsyncResponse asyncResponse){ - - LazyFutureStream.lazyFutureStreamFromIterable(urls) - .then(it->client.get(it)) - .onFail(it -> "") - .peek(it -> - System.out.println(it)) - .convertToSimpleReact() - .allOf(data -> { - System.out.println(data); - return asyncResponse.resume(ReactiveSeq.fromIterable(data).join(";")); }); - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/async/com/aol/micro/server/Simple.java b/micro-grizzly-with-jersey/src/test/java/app/async/com/aol/micro/server/Simple.java deleted file mode 100644 index edefa80ef..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/async/com/aol/micro/server/Simple.java +++ /dev/null @@ -1,16 +0,0 @@ -package app.async.com.aol.micro.server; - -import java.io.IOException; -import java.util.Properties; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.spring.properties.PropertyFileConfig; - -public class Simple { - - public static void main(String[] args) throws IOException{ - - new MicroserverApp(()->"test-app").run(); - } -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/async/com/aol/micro/server/SimpleApp.java b/micro-grizzly-with-jersey/src/test/java/app/async/com/aol/micro/server/SimpleApp.java deleted file mode 100644 index 919b7c6b0..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/async/com/aol/micro/server/SimpleApp.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.async.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; - - - -@Rest -@Path("/test") -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()->"test-app").run(); - } - @GET - public String myEndPoint(){ - return "hello world!"; - } - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java b/micro-grizzly-with-jersey/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java new file mode 100644 index 000000000..c71dd8184 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java @@ -0,0 +1,57 @@ +package app.async.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.Properties; +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.spring.properties.PropertyFileConfig; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class AsyncAppRunner { + + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( ()-> "async-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + Thread.sleep(2000); + + assertThat(rest.get("http://localhost:8080/async-app/async/expensive"),is(";test!;test!;test!")); + + } + + @Test + public void loadProperties() throws IOException{ + + Properties props = new PropertyFileConfig(true).propertyFactory() ; + assertThat(props.getProperty("test"),is("hello world")); + } + + + +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/async/com/oath/micro/server/AsyncResource.java b/micro-grizzly-with-jersey/src/test/java/app/async/com/oath/micro/server/AsyncResource.java new file mode 100644 index 000000000..cb2193ce4 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/async/com/oath/micro/server/AsyncResource.java @@ -0,0 +1,57 @@ +package app.async.com.oath.micro.server; + +import java.util.Arrays; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; + +import cyclops.futurestream.SimpleReact; +import cyclops.futurestream.FutureStream; +import cyclops.reactive.ReactiveSeq; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.testing.RestAgent; + +@Path("/async") +@Component +public class AsyncResource implements RestResource{ + + private final SimpleReact simpleReact =new SimpleReact(); + private final List urls = Arrays.asList("http://localhost:8080/async-app/async/ping2", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping"); + + private final RestAgent client = new RestAgent(); + + @GET + @Path("/expensive") + @Produces("text/plain") + public void expensive(@Suspended AsyncResponse asyncResponse){ + + FutureStream.builder().fromIterable(urls) + .then(it->client.get(it)) + .onFail(it -> "") + .peek(it -> + System.out.println(it)) + .convertToSimpleReact() + .allOf(data -> { + System.out.println(data); + return asyncResponse.resume(ReactiveSeq.fromIterable(data).join(";")); }); + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "test!"; + } + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/async/com/oath/micro/server/Simple.java b/micro-grizzly-with-jersey/src/test/java/app/async/com/oath/micro/server/Simple.java new file mode 100644 index 000000000..3eb3e7504 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/async/com/oath/micro/server/Simple.java @@ -0,0 +1,13 @@ +package app.async.com.oath.micro.server; + +import java.io.IOException; + +import com.oath.micro.server.MicroserverApp; + +public class Simple { + + public static void main(String[] args) throws IOException{ + + new MicroserverApp(()->"test-app").run(); + } +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/async/com/oath/micro/server/SimpleApp.java b/micro-grizzly-with-jersey/src/test/java/app/async/com/oath/micro/server/SimpleApp.java new file mode 100644 index 000000000..916d0330e --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/async/com/oath/micro/server/SimpleApp.java @@ -0,0 +1,24 @@ +package app.async.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; + + + +@Rest +@Path("/test") +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()->"test-app").run(); + } + @GET + public String myEndPoint(){ + return "hello world!"; + } + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleApp.java b/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleApp.java deleted file mode 100644 index 37a92de67..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleApp.java +++ /dev/null @@ -1,18 +0,0 @@ -package app.blacklisted.com.aol.micro.server.copy; - -import java.util.Arrays; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; - -public class SimpleApp { - - public static void main(String[] args){ - - new MicroserverApp(()-> "simple-app").run(); - } - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleRunnerTest.java deleted file mode 100644 index 8f677b7fd..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleRunnerTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package app.blacklisted.com.aol.micro.server.copy; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import nonautoscan.com.aol.micro.server.ScheduleAndAsyncConfig; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(blacklistedClasses={ScheduleAndAsyncConfig.class}) -public class SimpleRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); - - - } - - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleStatusResource.java b/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleStatusResource.java deleted file mode 100644 index 3ad8426ad..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleStatusResource.java +++ /dev/null @@ -1,53 +0,0 @@ -package app.blacklisted.com.aol.micro.server.copy; - -import java.io.InputStream; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -import nonautoscan.com.aol.micro.server.ScheduleAndAsyncConfig; - -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; -import org.glassfish.jersey.media.multipart.FormDataParam; -import org.junit.Assert; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class SimpleStatusResource { - - @Autowired - ApplicationContext context; - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - try{ - context.getBean(ScheduleAndAsyncConfig.class); - Assert.fail("failed to remove ScheduleAndAsyncConfig bean!"); - }catch(NoSuchBeanDefinitionException e){ - - } - return "ok"; - } - - @POST - @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces(MediaType.TEXT_PLAIN) - @Path("/file") - public String create( - @FormDataParam("file") InputStream fileInputStream, - @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { - - return "done"; - } -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleApp.java b/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleApp.java new file mode 100644 index 000000000..f73582b0c --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleApp.java @@ -0,0 +1,13 @@ +package app.blacklisted.com.oath.micro.server.copy; + +import com.oath.micro.server.MicroserverApp; + +public class SimpleApp { + + public static void main(String[] args){ + + new MicroserverApp(()-> "simple-app").run(); + } + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleRunnerTest.java new file mode 100644 index 000000000..ebdee84f1 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleRunnerTest.java @@ -0,0 +1,57 @@ +package app.blacklisted.com.oath.micro.server.copy; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import nonautoscan.com.oath.micro.server.ScheduleAndAsyncConfig; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(blacklistedClasses={ScheduleAndAsyncConfig.class}) +public class SimpleRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); + + + } + + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleStatusResource.java b/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleStatusResource.java new file mode 100644 index 000000000..4370e7e9a --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleStatusResource.java @@ -0,0 +1,53 @@ +package app.blacklisted.com.oath.micro.server.copy; + +import java.io.InputStream; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import nonautoscan.com.oath.micro.server.ScheduleAndAsyncConfig; + +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; +import org.junit.Assert; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class SimpleStatusResource { + + @Autowired + ApplicationContext context; + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + try{ + context.getBean(ScheduleAndAsyncConfig.class); + Assert.fail("failed to remove ScheduleAndAsyncConfig bean!"); + }catch(NoSuchBeanDefinitionException e){ + + } + return "ok"; + } + + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.TEXT_PLAIN) + @Path("/file") + public String create( + @FormDataParam("file") InputStream fileInputStream, + @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { + + return "done"; + } +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/direct/BinderDirectTest.java b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/direct/BinderDirectTest.java index d478fd88c..192708053 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/direct/BinderDirectTest.java +++ b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/direct/BinderDirectTest.java @@ -11,12 +11,11 @@ import org.junit.Before; import org.junit.Test; -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.module.Module; -import com.aol.micro.server.testing.RestAgent; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; @Microserver public class BinderDirectTest { diff --git a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/direct/CustomBinder4.java b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/direct/CustomBinder4.java index 9c2b15310..1cd4458e0 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/direct/CustomBinder4.java +++ b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/direct/CustomBinder4.java @@ -2,8 +2,6 @@ import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.server.spi.internal.ResourceMethodInvocationHandlerProvider; -import com.aol.micro.server.auto.discovery.JaxRsResource; - public class CustomBinder4 extends AbstractBinder { @Override diff --git a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/direct/SimpleApp.java b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/direct/SimpleApp.java index 95150b9e9..b909890af 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/direct/SimpleApp.java +++ b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/direct/SimpleApp.java @@ -3,12 +3,7 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; -import org.glassfish.jersey.server.ResourceConfig; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.module.ConfigurableModule; - +import com.oath.micro.server.auto.discovery.Rest; @Rest diff --git a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/BinderTest.java b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/BinderTest.java index 9b8648497..0f57e40ab 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/BinderTest.java +++ b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/BinderTest.java @@ -10,9 +10,9 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; @Microserver public class BinderTest { diff --git a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/Config.java b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/Config.java index 024b965a7..3bafd3e1b 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/Config.java +++ b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/Config.java @@ -3,7 +3,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import com.aol.micro.server.auto.discovery.JaxRsResourceWrapper; +import com.oath.micro.server.auto.discovery.JaxRsResourceWrapper; @Configuration public class Config { diff --git a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/CustomBinder2.java b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/CustomBinder2.java index e42284b21..706ab300e 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/CustomBinder2.java +++ b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/CustomBinder2.java @@ -2,8 +2,6 @@ import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.server.spi.internal.ResourceMethodInvocationHandlerProvider; -import com.aol.micro.server.auto.discovery.JaxRsResource; - public class CustomBinder2 extends AbstractBinder { @Override diff --git a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/SimpleApp.java b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/SimpleApp.java index bfa784520..62668fa46 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/SimpleApp.java +++ b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/noanno/SimpleApp.java @@ -3,12 +3,7 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; -import org.glassfish.jersey.server.ResourceConfig; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.module.ConfigurableModule; - +import com.oath.micro.server.auto.discovery.Rest; @Rest diff --git a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/resource/objects/BinderTest.java b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/resource/objects/BinderTest.java index 2805ba356..20e4e0ba5 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/resource/objects/BinderTest.java +++ b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/resource/objects/BinderTest.java @@ -6,16 +6,16 @@ import java.util.concurrent.ExecutionException; +import cyclops.reactive.collections.mutable.SetX; import org.junit.After; import org.junit.Before; import org.junit.Test; -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.module.Module; -import com.aol.micro.server.testing.RestAgent; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; @Microserver public class BinderTest { @@ -25,7 +25,7 @@ public class BinderTest { public void startServer(){ - server = new MicroserverApp(ConfigurableModule.builder().context("binder").jaxRsResourceObjects(PSetX.of(new CustomBinder3())).build()); + server = new MicroserverApp(ConfigurableModule.builder().context("binder").jaxRsResourceObjects(SetX.of(new CustomBinder3())).build()); server.start(); diff --git a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/resource/objects/CustomBinder3.java b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/resource/objects/CustomBinder3.java index b10bf9ce1..c08aed638 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/resource/objects/CustomBinder3.java +++ b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/resource/objects/CustomBinder3.java @@ -2,8 +2,6 @@ import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.server.spi.internal.ResourceMethodInvocationHandlerProvider; -import com.aol.micro.server.auto.discovery.JaxRsResource; - public class CustomBinder3 extends AbstractBinder { @Override diff --git a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/resource/objects/SimpleApp.java b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/resource/objects/SimpleApp.java index 84728cf63..36a9da879 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/resource/objects/SimpleApp.java +++ b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/resource/objects/SimpleApp.java @@ -3,12 +3,7 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; -import org.glassfish.jersey.server.ResourceConfig; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.module.ConfigurableModule; - +import com.oath.micro.server.auto.discovery.Rest; @Rest diff --git a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/test/BinderTest.java b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/test/BinderTest.java index 76c4d7950..5fcb95fc1 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/test/BinderTest.java +++ b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/test/BinderTest.java @@ -3,18 +3,15 @@ import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; -import java.util.Arrays; import java.util.concurrent.ExecutionException; -import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.junit.After; import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; @Microserver public class BinderTest { diff --git a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/test/CustomBinder.java b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/test/CustomBinder.java index 0e23b79a7..299a46bf4 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/test/CustomBinder.java +++ b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/test/CustomBinder.java @@ -2,7 +2,7 @@ import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.server.spi.internal.ResourceMethodInvocationHandlerProvider; -import com.aol.micro.server.auto.discovery.JaxRsResource; +import com.oath.micro.server.auto.discovery.JaxRsResource; @JaxRsResource public class CustomBinder extends AbstractBinder { diff --git a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/test/SimpleApp.java b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/test/SimpleApp.java index 7a2c74e08..2e275f0bd 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/custom/binder/test/SimpleApp.java +++ b/micro-grizzly-with-jersey/src/test/java/app/custom/binder/test/SimpleApp.java @@ -5,9 +5,9 @@ import org.glassfish.jersey.server.ResourceConfig; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.module.ConfigurableModule; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.module.ConfigurableModule; diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java deleted file mode 100644 index d4b8eff5c..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java +++ /dev/null @@ -1,23 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.ArrayList; -import java.util.List; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -@Component -@Path("/alt-status") -public class AltAppResource implements AltAppRestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public List ping(ImmutableEntity entity) { - return entity.getList(); - } - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java deleted file mode 100644 index 8cb2643e3..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface AltAppRestResource extends RestResource { - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java deleted file mode 100644 index bc73c2862..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.Arrays; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.EmbeddedModule; - -@Microserver(basePackages = { "app.embedded.com.aol.micro.server" }) -public class EmbeddedAppLocalMain { - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( - EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")).start(); - - - - } - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java deleted file mode 100644 index 47228dc0b..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java +++ /dev/null @@ -1,102 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.NotFoundException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.EmbeddedModule; -import com.aol.micro.server.testing.RestAgent; - -public class EmbeddedAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer(){ - server = new MicroserverApp(EmbeddedAppLocalMain.class, - EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")); - server.start(); - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); - - - assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), - hasItem("hello")); - - } - - - @Test - public void nonBlockingRestClientTest(){ - assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"),is("-*test!-*test!")); - } - - CompletableFuture toCompletableFuture( - final ListenableFuture listenableFuture - ) { - //create an instance of CompletableFuture - CompletableFuture completable = new CompletableFuture() { - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - // propagate cancel to the listenable future - boolean result = listenableFuture.cancel(mayInterruptIfRunning); - super.cancel(mayInterruptIfRunning); - return result; - } - }; - - // add callback - listenableFuture.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(T result) { - completable.complete(result); - } - - @Override - public void onFailure(Throwable t) { - completable.completeExceptionally(t); - } - }); - return completable; - } - - @Test(expected=NotFoundException.class) - public void confirmAltAppCantUseTestAppResources(){ - - assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); - - } - @Test(expected=NotFoundException.class) - public void confirmTestAppCantUseAltAppResources(){ - - assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), - hasItem("hello")); - - } -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java deleted file mode 100644 index 778c55c90..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java +++ /dev/null @@ -1,29 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableEntity { - - private final String value; - private final List list; - - public ImmutableEntity() { - this(null,null); - } - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java deleted file mode 100644 index e93d43724..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java +++ /dev/null @@ -1,48 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.Arrays; -import java.util.List; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.micro.server.testing.RestAgent; -@Component -@Path("/test-status") -public class TestAppResource implements TestAppRestResource { - - private final SimpleReact simpleReact = new SimpleReact(); - private final RestAgent template = new RestAgent(); - private final List urls = Arrays.asList("http://localhost:8081/alternative-app/alt-status/ping", - "http://localhost:8080/test-app/test-status/ping", - "http://localhost:8082/simple-app/status/ping", - "http://localhost:8080/test-app/test-status/ping"); - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - @GET - @Produces("text/plain") - @Path("/rest-calls") - public String restCallResult(){ - - return LazyFutureStream.lazyFutureStreamFromIterable(urls) - .map(it ->template.get(it)) - .then(it -> "*"+it) - .peek(loadedAndModified -> System.out.println(loadedAndModified)) - .block().stream().reduce("", (acc,next) -> acc+"-"+next); - - } - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java deleted file mode 100644 index 3133fd8cc..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface TestAppRestResource extends RestResource { - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java new file mode 100644 index 000000000..1835ababe --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java @@ -0,0 +1,22 @@ +package app.embedded.com.oath.micro.server; + +import java.util.List; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +@Component +@Path("/alt-status") +public class AltAppResource implements AltAppRestResource { + + @POST + @Produces("application/json") + @Path("/ping") + public List ping(ImmutableEntity entity) { + return entity.getList(); + } + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java new file mode 100644 index 000000000..7045a4f35 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java @@ -0,0 +1,7 @@ +package app.embedded.com.oath.micro.server; + +import com.oath.micro.server.auto.discovery.RestResource; + +public interface AltAppRestResource extends RestResource { + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java new file mode 100644 index 000000000..dbb290069 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java @@ -0,0 +1,24 @@ +package app.embedded.com.oath.micro.server; + +import java.util.Arrays; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.EmbeddedModule; + +@Microserver(basePackages = { "app.embedded.com.oath.micro.server" }) +public class EmbeddedAppLocalMain { + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( + EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), + EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")).start(); + + + + } + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java new file mode 100644 index 000000000..83eb220c1 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java @@ -0,0 +1,102 @@ +package app.embedded.com.oath.micro.server; + +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.NotFoundException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.util.concurrent.ListenableFuture; +import org.springframework.util.concurrent.ListenableFutureCallback; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.EmbeddedModule; +import com.oath.micro.server.testing.RestAgent; + +public class EmbeddedAppTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer(){ + server = new MicroserverApp(EmbeddedAppLocalMain.class, + EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), + EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")); + server.start(); + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); + + + assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), + hasItem("hello")); + + } + + + @Test + public void nonBlockingRestClientTest(){ + assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"),is("-*test!-*test!")); + } + + CompletableFuture toCompletableFuture( + final ListenableFuture listenableFuture + ) { + //create an instance of CompletableFuture + CompletableFuture completable = new CompletableFuture() { + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + // propagate cancel to the listenable future + boolean result = listenableFuture.cancel(mayInterruptIfRunning); + super.cancel(mayInterruptIfRunning); + return result; + } + }; + + // add callback + listenableFuture.addCallback(new ListenableFutureCallback() { + @Override + public void onSuccess(T result) { + completable.complete(result); + } + + @Override + public void onFailure(Throwable t) { + completable.completeExceptionally(t); + } + }); + return completable; + } + + @Test(expected=NotFoundException.class) + public void confirmAltAppCantUseTestAppResources(){ + + assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); + + } + @Test(expected=NotFoundException.class) + public void confirmTestAppCantUseAltAppResources(){ + + assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), + hasItem("hello")); + + } +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java new file mode 100644 index 000000000..337b63b89 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java @@ -0,0 +1,29 @@ +package app.embedded.com.oath.micro.server; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "immutable") +@Getter +@AllArgsConstructor +@Builder +public class ImmutableEntity { + + private final String value; + private final List list; + + public ImmutableEntity() { + this(null,null); + } + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java new file mode 100644 index 000000000..f75309862 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java @@ -0,0 +1,46 @@ +package app.embedded.com.oath.micro.server; + +import java.util.Arrays; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import cyclops.futurestream.SimpleReact; +import cyclops.futurestream.FutureStream; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.testing.RestAgent; +@Component +@Path("/test-status") +public class TestAppResource implements TestAppRestResource { + + private final SimpleReact simpleReact = new SimpleReact(); + private final RestAgent template = new RestAgent(); + private final List urls = Arrays.asList( + "http://localhost:8080/test-app/test-status/ping","http://localhost:8080/test-app/test-status/ping"); + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "test!"; + } + + @GET + @Produces("text/plain") + @Path("/rest-calls") + public String restCallResult(){ + + return FutureStream.builder().fromIterable(urls) + .map(it ->template.get(it)) + .then(it -> "*"+it) + .peek(loadedAndModified -> System.out.println(loadedAndModified)) + .block().stream().reduce("", (acc,next) -> acc+"-"+next); + + } + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java new file mode 100644 index 000000000..7d4df5753 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java @@ -0,0 +1,7 @@ +package app.embedded.com.oath.micro.server; + +import com.oath.micro.server.auto.discovery.RestResource; + +public interface TestAppRestResource extends RestResource { + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/AutodiscoveredFilter.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/AutodiscoveredFilter.java deleted file mode 100644 index 0ea5b4990..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/AutodiscoveredFilter.java +++ /dev/null @@ -1,68 +0,0 @@ -package app.filter.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import lombok.Getter; -import lombok.Setter; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.FilterConfiguration; - -@Component -public class AutodiscoveredFilter implements Filter, FilterConfiguration { - - @Autowired - Bean bean; - @Getter - @Setter - private static volatile int called= 0; - - @Getter - private static boolean beanSet = false; - - @Override - public String[] getMapping() { - return new String[] { "/*" }; - } - public Class getFilter(){ - - return org.springframework.web.filter.DelegatingFilterProxy.class; - - } - public String getName(){ - return "autodiscoveredFilter"; - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - - called++; - if(bean!=null) - beanSet =true; - chain.doFilter(request, response); - } - - @Override - public void destroy() { - - - } - - - -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/Bean.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/Bean.java deleted file mode 100644 index f95b44b05..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/Bean.java +++ /dev/null @@ -1,8 +0,0 @@ -package app.filter.com.aol.micro.server; - -import org.springframework.stereotype.Component; - -@Component -public class Bean { - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/ConfiguredFilter.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/ConfiguredFilter.java deleted file mode 100644 index e00bc941b..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/ConfiguredFilter.java +++ /dev/null @@ -1,38 +0,0 @@ -package app.filter.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import lombok.Getter; - -public class ConfiguredFilter implements Filter { - - @Getter - private static volatile int called= 0; - @Override - public void init(FilterConfig filterConfig) throws ServletException { - // TODO Auto-generated method stub - - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - called++; - chain.doFilter(request, response); - - } - - @Override - public void destroy() { - // TODO Auto-generated method stub - - } - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterAppLocalMain.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterAppLocalMain.java deleted file mode 100644 index 25dc01cc3..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterAppLocalMain.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.filter.com.aol.micro.server; - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import app.servlet.com.aol.micro.server.AppRunnerLocalMain; - -import com.aol.micro.server.MicroserverApp; -@Configuration -@ComponentScan(basePackages = { "app.filter.com.aol.micro.server" }) -public class FilterAppLocalMain { - - - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( FilterAppLocalMain.class, () -> "filter-app") - .run(); - } - - } \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterRunnerTest.java deleted file mode 100644 index 239ca7258..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterRunnerTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package app.filter.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.Map; -import java.util.concurrent.ExecutionException; - -import javax.servlet.Filter; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; -import com.aol.micro.server.utility.HashMapBuilder; - - - -public class FilterRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - Map filters = HashMapBuilder.map("/filter-app/status/ping2",new ConfiguredFilter()).build(); - server = new MicroserverApp(ConfigurableModule.builder() - .context("filter-app") - .filters(filters ) - .requestListeners(Arrays.asList(new org.springframework.web.context.request.RequestContextListener())).build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testAutoDiscoveredFilter() throws InterruptedException, ExecutionException{ - AutodiscoveredFilter.setCalled(0); - - assertThat(rest.get("http://localhost:8080/filter-app/status/ping"),is("ok")); - assertThat(AutodiscoveredFilter.getCalled(),is(1)); - assertThat(AutodiscoveredFilter.isBeanSet(),is(true)); - } - @Test - public void testConfiguredFilter() throws InterruptedException, ExecutionException{ - - assertThat(ConfiguredFilter.getCalled(),is(0)); - assertThat(rest.get("http://localhost:8080/filter-app/status/ping2"),is("ok")); - assertThat(ConfiguredFilter.getCalled(),is(1)); - } - - - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterStatusResource.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterStatusResource.java deleted file mode 100644 index 2d046711b..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterStatusResource.java +++ /dev/null @@ -1,37 +0,0 @@ -package app.filter.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; -import org.springframework.web.context.WebApplicationContext; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) -@Path("/status") -public class FilterStatusResource implements RestResource { - - @Autowired - private RequestScopeUserInfo info; - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - info.print(); - return "ok"; - } - @GET - @Produces("text/plain") - @Path("/ping2") - public String ping2() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/RequestScopeUserInfo.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/RequestScopeUserInfo.java deleted file mode 100644 index c41605c39..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/filter/com/aol/micro/server/RequestScopeUserInfo.java +++ /dev/null @@ -1,20 +0,0 @@ -package app.filter.com.aol.micro.server; - -import javax.servlet.http.HttpServletRequest; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.context.annotation.ScopedProxyMode; -import org.springframework.stereotype.Component; -import org.springframework.web.context.WebApplicationContext; - -@Component -@Scope(value=WebApplicationContext.SCOPE_REQUEST,proxyMode=ScopedProxyMode.TARGET_CLASS) -public class RequestScopeUserInfo { - @Autowired - private HttpServletRequest request; - - public void print(){ - System.out.println(request.getAttribute("oc.info")); - } -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/AutodiscoveredFilter.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/AutodiscoveredFilter.java new file mode 100644 index 000000000..1f6dfc284 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/AutodiscoveredFilter.java @@ -0,0 +1,70 @@ +package app.filter.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import cyclops.control.Either; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.auto.discovery.AutoFilterConfiguration; + +import lombok.Getter; +import lombok.Setter; + +@Component +public class AutodiscoveredFilter implements AutoFilterConfiguration { + + @Autowired + Bean bean; + @Getter + @Setter + private static volatile int called= 0; + + @Getter + private static boolean beanSet = false; + + @Override + public String[] getMapping() { + return new String[] { "/*" }; + } + public Either,Filter> getFilter(){ + + return Either.left(org.springframework.web.filter.DelegatingFilterProxy.class); + + } + public String getName(){ + return "autodiscoveredFilter"; + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + + called++; + if(bean!=null) + beanSet =true; + chain.doFilter(request, response); + } + + @Override + public void destroy() { + + + } + + + +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/Bean.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/Bean.java new file mode 100644 index 000000000..e036a796f --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/Bean.java @@ -0,0 +1,8 @@ +package app.filter.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +@Component +public class Bean { + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/ConfiguredFilter.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/ConfiguredFilter.java new file mode 100644 index 000000000..aca52ad38 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/ConfiguredFilter.java @@ -0,0 +1,38 @@ +package app.filter.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import lombok.Getter; + +public class ConfiguredFilter implements Filter { + + @Getter + private static volatile int called= 0; + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // TODO Auto-generated method stub + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + called++; + chain.doFilter(request, response); + + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterAppLocalMain.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterAppLocalMain.java new file mode 100644 index 000000000..b650780a2 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterAppLocalMain.java @@ -0,0 +1,20 @@ +package app.filter.com.oath.micro.server; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.MicroserverApp; +@Configuration +@ComponentScan(basePackages = { "app.filter.com.aol.micro.server" }) +public class FilterAppLocalMain { + + + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( FilterAppLocalMain.class, () -> "filter-app") + .run(); + } + + } \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterRunnerTest.java new file mode 100644 index 000000000..d3c136b4a --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterRunnerTest.java @@ -0,0 +1,64 @@ +package app.filter.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import javax.servlet.Filter; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; +import com.oath.micro.server.utility.HashMapBuilder; + + + +public class FilterRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + Map filters = HashMapBuilder.map("/filter-app/status/ping2",new ConfiguredFilter()).build(); + server = new MicroserverApp(ConfigurableModule.builder() + .context("filter-app") + .filters(filters ) + .requestListeners(Arrays.asList(new org.springframework.web.context.request.RequestContextListener())).build()); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void testAutoDiscoveredFilter() throws InterruptedException, ExecutionException{ + AutodiscoveredFilter.setCalled(0); + + assertThat(rest.get("http://localhost:8080/filter-app/status/ping"),is("ok")); + assertThat(AutodiscoveredFilter.getCalled(),is(1)); + assertThat(AutodiscoveredFilter.isBeanSet(),is(true)); + } + @Test + public void testConfiguredFilter() throws InterruptedException, ExecutionException{ + + assertThat(ConfiguredFilter.getCalled(),is(0)); + assertThat(rest.get("http://localhost:8080/filter-app/status/ping2"),is("ok")); + assertThat(ConfiguredFilter.getCalled(),is(1)); + } + + + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterStatusResource.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterStatusResource.java new file mode 100644 index 000000000..c7166c216 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterStatusResource.java @@ -0,0 +1,36 @@ +package app.filter.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) +@Path("/status") +public class FilterStatusResource implements RestResource { + + @Autowired + private RequestScopeUserInfo info; + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + info.print(); + return "ok"; + } + @GET + @Produces("text/plain") + @Path("/ping2") + public String ping2() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/RequestScopeUserInfo.java b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/RequestScopeUserInfo.java new file mode 100644 index 000000000..84c19c3f4 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/filter/com/oath/micro/server/RequestScopeUserInfo.java @@ -0,0 +1,20 @@ +package app.filter.com.oath.micro.server; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.stereotype.Component; +import org.springframework.web.context.WebApplicationContext; + +@Component +@Scope(value=WebApplicationContext.SCOPE_REQUEST,proxyMode=ScopedProxyMode.TARGET_CLASS) +public class RequestScopeUserInfo { + @Autowired + private HttpServletRequest request; + + public void print(){ + System.out.println(request.getAttribute("oc.info")); + } +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java b/micro-grizzly-with-jersey/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java deleted file mode 100644 index bff7cbdc8..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java +++ /dev/null @@ -1,35 +0,0 @@ -package app.listeners.com.aol.micro.server; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import lombok.Getter; - -import org.springframework.stereotype.Component; - -@Component -public class AutodiscoveredListener implements ServletContextListener { - - @Getter - private static volatile int called= 0; - - @Override - public void contextInitialized(ServletContextEvent sce) { - called ++; - - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - - - } - - - - - - - - -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/listeners/com/aol/micro/server/ConfiguredListener.java b/micro-grizzly-with-jersey/src/test/java/app/listeners/com/aol/micro/server/ConfiguredListener.java deleted file mode 100644 index d15dcb76e..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/listeners/com/aol/micro/server/ConfiguredListener.java +++ /dev/null @@ -1,25 +0,0 @@ -package app.listeners.com.aol.micro.server; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import lombok.Getter; - -public class ConfiguredListener implements ServletContextListener { - - @Getter - private static volatile int called= 0; - - @Override - public void contextInitialized(ServletContextEvent sce) { - called ++; - - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - - - } - -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java deleted file mode 100644 index 4f8d7ab69..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.listeners.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.ExecutionException; - -import javax.servlet.ServletContextListener; - - - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - - -@Microserver -public class ListenerRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - List listeners = Arrays.asList(new ConfiguredListener()); - server = new MicroserverApp( ListenerRunnerTest.class, ConfigurableModule.builder().context("listener-app").listeners(listeners ).build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testListeners() throws InterruptedException, ExecutionException{ - - assertThat(AutodiscoveredListener.getCalled(),is(1)); - assertThat(ConfiguredListener.getCalled(),is(1)); - } - - - - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/listeners/com/oath/micro/server/AutodiscoveredListener.java b/micro-grizzly-with-jersey/src/test/java/app/listeners/com/oath/micro/server/AutodiscoveredListener.java new file mode 100644 index 000000000..a3dfdff21 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/listeners/com/oath/micro/server/AutodiscoveredListener.java @@ -0,0 +1,35 @@ +package app.listeners.com.oath.micro.server; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import lombok.Getter; + +import org.springframework.stereotype.Component; + +@Component +public class AutodiscoveredListener implements ServletContextListener { + + @Getter + private static volatile int called= 0; + + @Override + public void contextInitialized(ServletContextEvent sce) { + called ++; + + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + + + } + + + + + + + + +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/listeners/com/oath/micro/server/ConfiguredListener.java b/micro-grizzly-with-jersey/src/test/java/app/listeners/com/oath/micro/server/ConfiguredListener.java new file mode 100644 index 000000000..86a7cd34b --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/listeners/com/oath/micro/server/ConfiguredListener.java @@ -0,0 +1,25 @@ +package app.listeners.com.oath.micro.server; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import lombok.Getter; + +public class ConfiguredListener implements ServletContextListener { + + @Getter + private static volatile int called= 0; + + @Override + public void contextInitialized(ServletContextEvent sce) { + called ++; + + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + + + } + +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/listeners/com/oath/micro/server/ListenerRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/listeners/com/oath/micro/server/ListenerRunnerTest.java new file mode 100644 index 000000000..fa0222a76 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/listeners/com/oath/micro/server/ListenerRunnerTest.java @@ -0,0 +1,55 @@ +package app.listeners.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import javax.servlet.ServletContextListener; + + + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + + +@Microserver +public class ListenerRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + List listeners = Arrays.asList(new ConfiguredListener()); + server = new MicroserverApp( ListenerRunnerTest.class, ConfigurableModule.builder().context("listener-app").listeners(listeners ).build()); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void testListeners() throws InterruptedException, ExecutionException{ + + assertThat(AutodiscoveredListener.getCalled(),is(1)); + assertThat(ConfiguredListener.getCalled(),is(1)); + } + + + + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/micro/server/servers/AccessLogConfigTest.java b/micro-grizzly-with-jersey/src/test/java/app/micro/server/servers/AccessLogConfigTest.java index 194988553..e6e552f02 100644 --- a/micro-grizzly-with-jersey/src/test/java/app/micro/server/servers/AccessLogConfigTest.java +++ b/micro-grizzly-with-jersey/src/test/java/app/micro/server/servers/AccessLogConfigTest.java @@ -9,8 +9,8 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; @Microserver(properties={"access.log.output", "${user.home}"}) public class AccessLogConfigTest { @@ -22,13 +22,15 @@ public class AccessLogConfigTest { @Before public void startServer() { - logFile = new File(System.getProperty("user.home") + "/access-log-app-access.log"); - logFile.delete(); - assertThat(logFile.exists(), is(false)); + logFile = new File(System.getProperty("user.home") + "/access-log-app-access.log"); + logFile.delete(); + + assertThat(logFile.exists(), is(false)); + + server = new MicroserverApp(() -> "access-log-app"); + server.start(); - server = new MicroserverApp(() -> "access-log-app"); - server.start(); } diff --git a/micro-grizzly-with-jersey/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java b/micro-grizzly-with-jersey/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java deleted file mode 100644 index 04367ecbd..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package app.minimal.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.testing.RestAgent; - -@Rest -@Path("/single") -public class MinimalClassTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "minimal-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java b/micro-grizzly-with-jersey/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java new file mode 100644 index 000000000..c018eb7b2 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java @@ -0,0 +1,57 @@ +package app.minimal.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.testing.RestAgent; + +@Rest +@Path("/single") +public class MinimalClassTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp(()-> "minimal-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoRunnerTest.java deleted file mode 100644 index bb052650c..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoRunnerTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package app.noanno.com.aol.micro.server.copy; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - - -public class NoAnnoRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); - - - } - - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoStatusResource.java b/micro-grizzly-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoStatusResource.java deleted file mode 100644 index 8a3f5efaa..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoStatusResource.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.noanno.com.aol.micro.server.copy; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class NoAnnoStatusResource { - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/SimpleApp.java b/micro-grizzly-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/SimpleApp.java deleted file mode 100644 index 5fb7e2ca3..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/SimpleApp.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.noanno.com.aol.micro.server.copy; - -import com.aol.micro.server.MicroserverApp; - -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()-> "simple-app").run(); - } - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoRunnerTest.java new file mode 100644 index 000000000..589bf5144 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoRunnerTest.java @@ -0,0 +1,47 @@ +package app.noanno.com.oath.micro.server.copy; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; + + +public class NoAnnoRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp(()-> "simple-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); + + + } + + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoStatusResource.java b/micro-grizzly-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoStatusResource.java new file mode 100644 index 000000000..11a42968e --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoStatusResource.java @@ -0,0 +1,24 @@ +package app.noanno.com.oath.micro.server.copy; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class NoAnnoStatusResource { + + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/SimpleApp.java b/micro-grizzly-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/SimpleApp.java new file mode 100644 index 000000000..646004a31 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/SimpleApp.java @@ -0,0 +1,12 @@ +package app.noanno.com.oath.micro.server.copy; + +import com.oath.micro.server.MicroserverApp; + +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()-> "simple-app").run(); + } + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/properties/instance/com/aol/micro/server/ServicePropertiesTest.java b/micro-grizzly-with-jersey/src/test/java/app/properties/instance/com/aol/micro/server/ServicePropertiesTest.java deleted file mode 100644 index 0b12749f9..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/properties/instance/com/aol/micro/server/ServicePropertiesTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package app.properties.instance.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Value; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Rest -@Path("/single") -@Microserver(instancePropertiesName="myinstance.properties") -public class ServicePropertiesTest { - - RestAgent rest = new RestAgent(); - - @Value("${type.property}") - private String type; - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "minimal-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); - - - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - assertThat(type,equalTo("instance")); - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/properties/instance/com/oath/micro/server/ServicePropertiesTest.java b/micro-grizzly-with-jersey/src/test/java/app/properties/instance/com/oath/micro/server/ServicePropertiesTest.java new file mode 100644 index 000000000..7ef55708f --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/properties/instance/com/oath/micro/server/ServicePropertiesTest.java @@ -0,0 +1,65 @@ +package app.properties.instance.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Value; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Rest +@Path("/single") +@Microserver(instancePropertiesName="myinstance.properties") +public class ServicePropertiesTest { + + RestAgent rest = new RestAgent(); + + @Value("${type.property}") + private String type; + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp(()-> "minimal-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); + + + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + assertThat(type,equalTo("instance")); + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/properties/service/com/aol/micro/server/ServicePropertiesTest.java b/micro-grizzly-with-jersey/src/test/java/app/properties/service/com/aol/micro/server/ServicePropertiesTest.java deleted file mode 100644 index 84ceba8d7..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/properties/service/com/aol/micro/server/ServicePropertiesTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package app.properties.service.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Value; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Rest -@Path("/single") -@Microserver(serviceTypePropertiesName="myservice.properties") -public class ServicePropertiesTest { - - RestAgent rest = new RestAgent(); - - @Value("${type.property}") - private String type; - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "minimal-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); - - - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - assertThat(type,equalTo("set")); - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/properties/service/com/oath/micro/server/ServicePropertiesTest.java b/micro-grizzly-with-jersey/src/test/java/app/properties/service/com/oath/micro/server/ServicePropertiesTest.java new file mode 100644 index 000000000..d260cb148 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/properties/service/com/oath/micro/server/ServicePropertiesTest.java @@ -0,0 +1,65 @@ +package app.properties.service.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Value; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Rest +@Path("/single") +@Microserver(serviceTypePropertiesName="myservice.properties") +public class ServicePropertiesTest { + + RestAgent rest = new RestAgent(); + + @Value("${type.property}") + private String type; + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp(()-> "minimal-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); + + + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + assertThat(type,equalTo("set")); + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/publisher/binder/direct/AsyncPublisherTest.java b/micro-grizzly-with-jersey/src/test/java/app/publisher/binder/direct/AsyncPublisherTest.java new file mode 100644 index 000000000..980efe728 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/publisher/binder/direct/AsyncPublisherTest.java @@ -0,0 +1,42 @@ +package app.publisher.binder.direct; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +@Microserver +public class AsyncPublisherTest { + RestAgent rest = new RestAgent(); + MicroserverApp server; + + @Before + public void startServer() { + + server = new MicroserverApp(() -> "binder"); + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + assertThat(rest.get("http://localhost:8080/binder/test/myEndPoint"), is("hello world!")); + } + @Test + public void runAppAndBasicTest2() throws InterruptedException, ExecutionException { + assertThat(rest.get("http://localhost:8080/binder/test/async2"), is("hello")); + } +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/publisher/binder/direct/AsyncResource.java b/micro-grizzly-with-jersey/src/test/java/app/publisher/binder/direct/AsyncResource.java new file mode 100644 index 000000000..e7dd3aa50 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/publisher/binder/direct/AsyncResource.java @@ -0,0 +1,42 @@ +package app.publisher.binder.direct; + +import com.oath.micro.server.auto.discovery.Rest; +import cyclops.control.Future; +import cyclops.reactive.ReactiveSeq; +import cyclops.reactive.Spouts; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import java.util.concurrent.Executors; +import java.util.stream.Stream; + + +@Rest +@Path("/test") +public class AsyncResource { + + private void sleep() { + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @GET + @Path("myEndPoint") + public Future myEndPoint() { + return Future.of(() -> { + sleep(); + return "hello world!"; + }, Executors.newFixedThreadPool(1)); + } + + @GET + @Path("async2") + public ReactiveSeq async2() { + return Spouts.reactive(Stream.of("hello"), Executors.newFixedThreadPool(1)); + } + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/publisher/binder/direct/LazyTest.java b/micro-grizzly-with-jersey/src/test/java/app/publisher/binder/direct/LazyTest.java new file mode 100644 index 000000000..5a1409737 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/publisher/binder/direct/LazyTest.java @@ -0,0 +1,33 @@ +package app.publisher.binder.direct; + +import cyclops.reactive.collections.mutable.ListX; +import cyclops.reactive.ReactiveSeq; +import org.junit.Test; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +public class LazyTest { + + @Test + public void jdkSteam(){ + List list = Stream.of(1,2,3) + .peek(System.out::println) + .collect(Collectors.toList()); + } + @Test + public void lazy(){ + ListX list = ReactiveSeq.of(1,2,3) + .peek(System.out::println) + .to(ListX::fromIterable); + + + list.size(); + System.out.println("List " + list); + + + + } +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/root/context/single/RootSingleClassTest.java b/micro-grizzly-with-jersey/src/test/java/app/root/context/single/RootSingleClassTest.java new file mode 100644 index 000000000..8bdb62290 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/root/context/single/RootSingleClassTest.java @@ -0,0 +1,56 @@ +package app.root.context.single; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import java.util.concurrent.ExecutionException; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +@Microserver +@Path("/single") +public class RootSingleClassTest implements RestResource{ + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( RootSingleClassTest.class, ()-> ""); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/single/ping"),is("ok")); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java deleted file mode 100644 index b447491a1..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java +++ /dev/null @@ -1,20 +0,0 @@ -package app.servlet.com.aol.micro.server; - - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import com.aol.micro.server.MicroserverApp; - -@Configuration -@ComponentScan(basePackages = { "app.servlet.com.aol.micro.server" }) -public class AppRunnerLocalMain { - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( AppRunnerLocalMain.class, () -> "test-app") - .run(); - } - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java deleted file mode 100644 index d0123c905..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java +++ /dev/null @@ -1,30 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.ServletConfiguration; - -@Component -public class AutodiscoveredServlet extends HttpServlet implements ServletConfiguration { - - @Override - public String[] getMapping() { - return new String[] { "/servlet" }; - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - resp.setContentType("text/html"); - resp.getWriter().write("hello world"); - } - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java deleted file mode 100644 index 92577a92e..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class ConfiguredServlet extends HttpServlet { - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - resp.setContentType("text/html"); - resp.getWriter().write("configured servlet"); - } - - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java deleted file mode 100644 index aa6e20b4f..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package app.servlet.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ExecutionException; - -import javax.servlet.Servlet; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -public class ServletRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - Map servlets = new HashMap<>(); - servlets.put("/configured", new ConfiguredServlet()); - server = new MicroserverApp( AppRunnerLocalMain.class, ConfigurableModule.builder().context("test-app").servlets(servlets ).build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/test-app/servlet/ping"),is("ok")); - - } - - @Test - public void autoDiscoveredServletTest() throws InterruptedException, ExecutionException{ - - - assertThat(rest.get("http://localhost:8080/servlet"),is("hello world")); - - } - - @Test - public void configuredServletTest() throws InterruptedException, ExecutionException{ - - - assertThat(rest.get("http://localhost:8080/configured"),is("configured servlet")); - - } - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java deleted file mode 100644 index 890a64679..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/servlet") -public class ServletStatusResource implements RestResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/AppRunnerLocalMain.java b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/AppRunnerLocalMain.java new file mode 100644 index 000000000..065973f62 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/AppRunnerLocalMain.java @@ -0,0 +1,20 @@ +package app.servlet.com.oath.micro.server; + + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.MicroserverApp; + +@Configuration +@ComponentScan(basePackages = { "app.servlet.com.aol.micro.server" }) +public class AppRunnerLocalMain { + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( AppRunnerLocalMain.class, () -> "test-app") + .run(); + } + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/AutodiscoveredServlet.java b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/AutodiscoveredServlet.java new file mode 100644 index 000000000..66cbfd59c --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/AutodiscoveredServlet.java @@ -0,0 +1,30 @@ +package app.servlet.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.AutoServletConfiguration; + +@Component +public class AutodiscoveredServlet extends HttpServlet implements AutoServletConfiguration { + + @Override + public String[] getMapping() { + return new String[] { "/servlet" }; + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + resp.setContentType("text/html"); + resp.getWriter().write("hello world"); + } + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ConfiguredServlet.java b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ConfiguredServlet.java new file mode 100644 index 000000000..65de82291 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ConfiguredServlet.java @@ -0,0 +1,21 @@ +package app.servlet.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class ConfiguredServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + resp.setContentType("text/html"); + resp.getWriter().write("configured servlet"); + } + + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ServletRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ServletRunnerTest.java new file mode 100644 index 000000000..39f3896e3 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ServletRunnerTest.java @@ -0,0 +1,64 @@ +package app.servlet.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import javax.servlet.Servlet; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +public class ServletRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + Map servlets = new HashMap<>(); + servlets.put("/configured", new ConfiguredServlet()); + server = new MicroserverApp( AppRunnerLocalMain.class, ConfigurableModule.builder().context("test-app").servlets(servlets ).build()); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/test-app/servlet/ping"),is("ok")); + + } + + @Test + public void autoDiscoveredServletTest() throws InterruptedException, ExecutionException{ + + + assertThat(rest.get("http://localhost:8080/servlet"),is("hello world")); + + } + + @Test + public void configuredServletTest() throws InterruptedException, ExecutionException{ + + + assertThat(rest.get("http://localhost:8080/configured"),is("configured servlet")); + + } + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ServletStatusResource.java b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ServletStatusResource.java new file mode 100644 index 000000000..6d86eeb84 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ServletStatusResource.java @@ -0,0 +1,22 @@ +package app.servlet.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/servlet") +public class ServletStatusResource implements RestResource { + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java b/micro-grizzly-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java deleted file mode 100644 index 700a2c778..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java +++ /dev/null @@ -1,18 +0,0 @@ -package app.simple.com.aol.micro.server; - -import java.util.Arrays; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; - -public class SimpleApp { - - public static void main(String[] args){ - - new MicroserverApp(()-> "simple-app").run(); - } - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java deleted file mode 100644 index 6249ef506..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.simple.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class SimpleRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - // server = new MicroserverApp(()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); - - - } - - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java b/micro-grizzly-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java deleted file mode 100644 index 17e6c3e45..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java +++ /dev/null @@ -1,39 +0,0 @@ -package app.simple.com.aol.micro.server; - -import java.io.InputStream; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; -import org.glassfish.jersey.media.multipart.FormDataParam; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class SimpleStatusResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return "ok"; - } - - @POST - @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces(MediaType.TEXT_PLAIN) - @Path("/file") - public String create( - @FormDataParam("file") InputStream fileInputStream, - @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { - - return "done"; - } -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java b/micro-grizzly-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java new file mode 100644 index 000000000..e82a92291 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java @@ -0,0 +1,13 @@ +package app.simple.com.oath.micro.server; + +import com.oath.micro.server.MicroserverApp; + +public class SimpleApp { + + public static void main(String[] args){ + + new MicroserverApp(()-> "simple-app").run(); + } + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java new file mode 100644 index 000000000..ce6dd819a --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java @@ -0,0 +1,55 @@ +package app.simple.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class SimpleRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + // server = new MicroserverApp(()-> "simple-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); + + + } + + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java b/micro-grizzly-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java new file mode 100644 index 000000000..2a894a8fc --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java @@ -0,0 +1,39 @@ +package app.simple.com.oath.micro.server; + +import java.io.InputStream; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class SimpleStatusResource { + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + return "ok"; + } + + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.TEXT_PLAIN) + @Path("/file") + public String create( + @FormDataParam("file") InputStream fileInputStream, + @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { + + return "done"; + } +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java b/micro-grizzly-with-jersey/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java deleted file mode 100644 index d7725eed3..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package app.single.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -@Path("/single") -public class SingleClassTest implements RestResource{ - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( SingleClassTest.class, ()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/single/ping"),is("ok")); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java b/micro-grizzly-with-jersey/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java new file mode 100644 index 000000000..c5a34809d --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java @@ -0,0 +1,58 @@ +package app.single.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +@Path("/single") +public class SingleClassTest implements RestResource{ + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( SingleClassTest.class, ()-> "simple-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/single/ping"),is("ok")); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java b/micro-grizzly-with-jersey/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java deleted file mode 100644 index aef7a170c..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.single.main.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class SingleClassApp { - - public static void main(String[] args){ - new MicroserverApp(()-> "simple-app").run(); - } - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/single/main/com/oath/micro/server/SingleClassApp.java b/micro-grizzly-with-jersey/src/test/java/app/single/main/com/oath/micro/server/SingleClassApp.java new file mode 100644 index 000000000..2d7a71917 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/single/main/com/oath/micro/server/SingleClassApp.java @@ -0,0 +1,24 @@ +package app.single.main.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class SingleClassApp { + + public static void main(String[] args){ + new MicroserverApp(()-> "simple-app").run(); + } + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/single/serverconfig/com/aol/micro/server/SingleClassTest.java b/micro-grizzly-with-jersey/src/test/java/app/single/serverconfig/com/aol/micro/server/SingleClassTest.java deleted file mode 100644 index af9af9878..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/single/serverconfig/com/aol/micro/server/SingleClassTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package app.single.serverconfig.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - - -@Path("/single") -public class SingleClassTest implements RestResource{ - - RestAgent rest = new RestAgent(); - - boolean called; - MicroserverApp server; - @Before - public void startServer(){ - called = false; - server = new MicroserverApp( ConfigurableModule.builder() - .context("hello") - .serverConfigManager(server->called=true) - .build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/hello/single/ping"),is("ok")); - assertTrue(called); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/single/serverconfig/com/oath/micro/server/SingleClassTest.java b/micro-grizzly-with-jersey/src/test/java/app/single/serverconfig/com/oath/micro/server/SingleClassTest.java new file mode 100644 index 000000000..4dbcb9705 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/single/serverconfig/com/oath/micro/server/SingleClassTest.java @@ -0,0 +1,63 @@ +package app.single.serverconfig.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + + +@Path("/single") +public class SingleClassTest implements RestResource{ + + RestAgent rest = new RestAgent(); + + boolean called; + MicroserverApp server; + @Before + public void startServer(){ + called = false; + server = new MicroserverApp( ConfigurableModule.builder() + .context("hello") + .serverConfigManager(server->called=true) + .build()); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/hello/single/ping"),is("ok")); + assertTrue(called); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/spring/com/aol/micro/server/MyBean.java b/micro-grizzly-with-jersey/src/test/java/app/spring/com/aol/micro/server/MyBean.java deleted file mode 100644 index 0663a868d..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/spring/com/aol/micro/server/MyBean.java +++ /dev/null @@ -1,17 +0,0 @@ -package app.spring.com.aol.micro.server; - -import javax.inject.Inject; - -import org.springframework.beans.factory.annotation.Value; - -import lombok.Getter; - -@Getter -public class MyBean { - - public enum One{one,two}; - @Value("${one:one}") - One one; - @Inject - private MyDependency injected; -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/spring/com/aol/micro/server/MyDependency.java b/micro-grizzly-with-jersey/src/test/java/app/spring/com/aol/micro/server/MyDependency.java deleted file mode 100644 index 48d89e6c5..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/spring/com/aol/micro/server/MyDependency.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.spring.com.aol.micro.server; - -import lombok.Getter; - -import org.springframework.stereotype.Component; - -@Component -@Getter -public class MyDependency { - - private String data = "hello world"; -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java deleted file mode 100644 index 1a1765be0..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package app.spring.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.context.annotation.Bean; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; -/**@Configuration -@ComponentScan(basePackages = { "app.spring.com.aol.micro.server" })**/ -@Microserver -public class SpringRunnerTest { - - RestAgent rest = new RestAgent(); - - @Bean - public MyBean mybean(){ - return new MyBean(); - } - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( SpringRunnerTest.class, ()-> "spring-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testAutoWiring() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/spring-app/spring/ping"),is("hello world")); - - } - - - - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java b/micro-grizzly-with-jersey/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java deleted file mode 100644 index 331ac997e..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java +++ /dev/null @@ -1,32 +0,0 @@ -package app.spring.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/spring") -public class SpringStatusResource implements RestResource { - - @Autowired - private MyBean mybean; - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return mybean.getInjected().getData(); - } - @GET - @Produces("text/plain") - @Path("/ping2") - public String ping2() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/spring/com/oath/micro/server/MyBean.java b/micro-grizzly-with-jersey/src/test/java/app/spring/com/oath/micro/server/MyBean.java new file mode 100644 index 000000000..7c91f79fb --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/spring/com/oath/micro/server/MyBean.java @@ -0,0 +1,17 @@ +package app.spring.com.oath.micro.server; + +import javax.inject.Inject; + +import org.springframework.beans.factory.annotation.Value; + +import lombok.Getter; + +@Getter +public class MyBean { + + public enum One{one,two}; + @Value("${one:one}") + One one; + @Inject + private MyDependency injected; +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/spring/com/oath/micro/server/MyDependency.java b/micro-grizzly-with-jersey/src/test/java/app/spring/com/oath/micro/server/MyDependency.java new file mode 100644 index 000000000..1ca23b15b --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/spring/com/oath/micro/server/MyDependency.java @@ -0,0 +1,12 @@ +package app.spring.com.oath.micro.server; + +import lombok.Getter; + +import org.springframework.stereotype.Component; + +@Component +@Getter +public class MyDependency { + + private String data = "hello world"; +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java b/micro-grizzly-with-jersey/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java new file mode 100644 index 000000000..d45d0c0e1 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java @@ -0,0 +1,54 @@ +package app.spring.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.annotation.Bean; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; +/**@Configuration +@ComponentScan(basePackages = { "app.spring.com.aol.micro.server" })**/ +@Microserver +public class SpringRunnerTest { + + RestAgent rest = new RestAgent(); + + @Bean + public MyBean mybean(){ + return new MyBean(); + } + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( SpringRunnerTest.class, ()-> "spring-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void testAutoWiring() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/spring-app/spring/ping"),is("hello world")); + + } + + + + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java b/micro-grizzly-with-jersey/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java new file mode 100644 index 000000000..ae0c817de --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java @@ -0,0 +1,32 @@ +package app.spring.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/spring") +public class SpringStatusResource implements RestResource { + + @Autowired + private MyBean mybean; + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return mybean.getInjected().getData(); + } + @GET + @Produces("text/plain") + @Path("/ping2") + public String ping2() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-grizzly-with-jersey/src/test/java/app/validation/com/aol/micro/server/ImmutableEntity.java b/micro-grizzly-with-jersey/src/test/java/app/validation/com/aol/micro/server/ImmutableEntity.java deleted file mode 100644 index 5af51d60c..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/validation/com/aol/micro/server/ImmutableEntity.java +++ /dev/null @@ -1,28 +0,0 @@ -package app.validation.com.aol.micro.server; - - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableEntity { - - private final String value; - - - public ImmutableEntity() { - this(null); - } - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java b/micro-grizzly-with-jersey/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java deleted file mode 100644 index 880c619e8..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java +++ /dev/null @@ -1,23 +0,0 @@ -package app.validation.com.aol.micro.server; - -import javax.validation.constraints.NotNull; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -@Component -@Path("/status") -public class ValidationAppResource implements RestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public ImmutableEntity ping( @NotNull ImmutableEntity entity) { - return entity; - } - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java b/micro-grizzly-with-jersey/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java deleted file mode 100644 index fd153d579..000000000 --- a/micro-grizzly-with-jersey/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package app.validation.com.aol.micro.server; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.BadRequestException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.SimpleReactStream; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.testing.RestAgent; - -//@Microserver(basePackages = { "app.guava.com.aol.micro.server" }) -public class ValidationAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - ImmutableEntity entity; - - - SimpleReact simpleReact = new SimpleReact(); - SimpleReactStream stream; - - @Before - public void startServer() { - stream = simpleReact.ofAsync( - () -> server = new MicroserverApp(() -> "guava-app")).then(server -> server.start()); - - entity = ImmutableEntity.builder().value("value").build(); - - - } - - @After - public void stopServer() { - server.stop(); - } - - - @Test(expected=BadRequestException.class) - public void confirmError() throws InterruptedException, - ExecutionException { - - stream.block(); - rest.post( - "http://localhost:8080/guava-app/status/ping", null, - ImmutableEntity.class); - - - } - @Test - public void confirmNoError() throws InterruptedException, - ExecutionException { - - stream.block(); - rest.post( - "http://localhost:8080/guava-app/status/ping", entity, - ImmutableEntity.class); - - - } - - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/app/validation/com/oath/micro/server/ImmutableEntity.java b/micro-grizzly-with-jersey/src/test/java/app/validation/com/oath/micro/server/ImmutableEntity.java new file mode 100644 index 000000000..19e8f5b26 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/validation/com/oath/micro/server/ImmutableEntity.java @@ -0,0 +1,28 @@ +package app.validation.com.oath.micro.server; + + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "immutable") +@Getter +@AllArgsConstructor +@Builder +public class ImmutableEntity { + + private final String value; + + + public ImmutableEntity() { + this(null); + } + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java b/micro-grizzly-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java new file mode 100644 index 000000000..7a8d0c325 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java @@ -0,0 +1,23 @@ +package app.validation.com.oath.micro.server; + +import javax.validation.constraints.NotNull; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +@Component +@Path("/status") +public class ValidationAppResource implements RestResource { + + @POST + @Produces("application/json") + @Path("/ping") + public ImmutableEntity ping( @NotNull ImmutableEntity entity) { + return entity; + } + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java b/micro-grizzly-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java new file mode 100644 index 000000000..c560d1521 --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java @@ -0,0 +1,71 @@ +package app.validation.com.oath.micro.server; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.BadRequestException; + +import com.oath.cyclops.types.futurestream.SimpleReactStream; +import cyclops.futurestream.SimpleReact; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; + +//@Microserver(basePackages = { "app.guava.com.oath.micro.server" }) +public class ValidationAppTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + ImmutableEntity entity; + + + SimpleReact simpleReact = new SimpleReact(); + SimpleReactStream stream; + + @Before + public void startServer() { + stream = simpleReact.ofAsync( + () -> server = new MicroserverApp(() -> "guava-app")).then(server -> server.start()); + + entity = ImmutableEntity.builder().value("value").build(); + + + } + + @After + public void stopServer() { + server.stop(); + } + + + @Test(expected=BadRequestException.class) + public void confirmError() throws InterruptedException, + ExecutionException { + + stream.block(); + rest.post( + "http://localhost:8080/guava-app/status/ping", null, + ImmutableEntity.class); + + + } + @Test + public void confirmNoError() throws InterruptedException, + ExecutionException { + + stream.block(); + rest.post( + "http://localhost:8080/guava-app/status/ping", entity, + ImmutableEntity.class); + + + } + + + +} diff --git a/micro-grizzly-with-jersey/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-grizzly-with-jersey/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-grizzly-with-jersey/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-grizzly-with-jersey/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-grizzly-with-jersey/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-grizzly-with-jersey/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-grizzly/README.md b/micro-grizzly/README.md new file mode 100644 index 000000000..9d7d4dc50 --- /dev/null +++ b/micro-grizzly/README.md @@ -0,0 +1,24 @@ +# Grizzly web server Plugin + +[Example Grizzly apps](https://github.com/aol/micro-server/tree/master/micro-grizzly/src/test/java/app) + +Plugin that allows the Grizzly Web server to be used with Microserver. + + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-grizzly/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-grizzly) + +Simply add to the classpath + +Maven + + + com.oath.microservices + micro-grizzly + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-grizzly:x.yz' diff --git a/micro-grizzly/application.properties b/micro-grizzly/application.properties index f7184f073..09add10a7 100644 --- a/micro-grizzly/application.properties +++ b/micro-grizzly/application.properties @@ -1 +1,2 @@ -test=hello world \ No newline at end of file +test=hello world +override=boo! \ No newline at end of file diff --git a/micro-grizzly/build.gradle b/micro-grizzly/build.gradle index 89a641380..ba410263e 100644 --- a/micro-grizzly/build.gradle +++ b/micro-grizzly/build.gradle @@ -1,68 +1,66 @@ description = 'micro-grizzly' -dependencies { - compile group: 'org.glassfish.grizzly', name: 'grizzly-http-server', version:"$grizzlyVersion" - compile group: 'org.glassfish.grizzly', name: 'grizzly-http-all', version:"$grizzlyVersion" - - - compile project(':micro-core') - testCompile project(':micro-jersey') - testCompile project(':micro-jackson-configuration') - testCompile 'commons-io:commons-io:2.4' - +dependencies { + compile group: 'org.glassfish.grizzly', name: 'grizzly-http-server', version: "$grizzlyVersion" + compile group: 'org.glassfish.grizzly', name: 'grizzly-http-all', version: "$grizzlyVersion" + compile project(':micro-core') + testCompile project(':micro-jersey') + testCompile project(':micro-jackson-configuration') + testCompile 'commons-io:commons-io:' + commonsIOVersion + testCompile "com.oath.cyclops:cyclops-futurestream:$cyclopsVersion" } modifyPom { - project { - name 'Microserver Grizzly' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver Grizzly' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-grizzly' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } - groupId 'com.aol.microservices' - artifactId 'micro-grizzly' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - } - - } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-grizzly/readme.md b/micro-grizzly/readme.md deleted file mode 100644 index 6dcc51d7d..000000000 --- a/micro-grizzly/readme.md +++ /dev/null @@ -1,24 +0,0 @@ -# Grizzly web server Plugin - -[Example Grizzly apps](https://github.com/aol/micro-server/tree/master/micro-grizzly/src/test/java/app) - -Plugin that allows the Grizzly Web server to be used with Microserver. - - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-grizzly/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-grizzly) - -Simply add to the classpath - -Maven - - - com.aol.microservices - micro-grizzly - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-grizzly:x.yz' \ No newline at end of file diff --git a/micro-grizzly/src/main/java/com/aol/micro/server/servers/grizzly/GrizzlyApplication.java b/micro-grizzly/src/main/java/com/aol/micro/server/servers/grizzly/GrizzlyApplication.java deleted file mode 100644 index 631a3abf1..000000000 --- a/micro-grizzly/src/main/java/com/aol/micro/server/servers/grizzly/GrizzlyApplication.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.aol.micro.server.servers.grizzly; - -import java.io.IOException; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import javax.servlet.ServletContextListener; -import javax.servlet.ServletRequestListener; - -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Wither; - -import org.glassfish.grizzly.http.server.HttpServer; -import org.glassfish.grizzly.http.server.NetworkListener; -import org.glassfish.grizzly.http.server.accesslog.AccessLogBuilder; -import org.glassfish.grizzly.servlet.WebappContext; -import org.pcollections.PStack; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.aol.cyclops.util.ExceptionSoftener; -import com.aol.micro.server.ErrorCode; -import com.aol.micro.server.config.SSLProperties; -import com.aol.micro.server.module.WebServerProvider; -import com.aol.micro.server.servers.AccessLogLocationBean; -import com.aol.micro.server.servers.FilterConfigurer; -import com.aol.micro.server.servers.JaxRsServletConfigurer; -import com.aol.micro.server.servers.ServerApplication; -import com.aol.micro.server.servers.ServletConfigurer; -import com.aol.micro.server.servers.ServletContextListenerConfigurer; -import com.aol.micro.server.servers.model.AllData; -import com.aol.micro.server.servers.model.FilterData; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.servers.model.ServletData; - -@AllArgsConstructor(access = AccessLevel.PRIVATE) -public class GrizzlyApplication implements ServerApplication { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - @Getter - private final ServerData serverData; - - private final PStack filterData; - private final PStack servletData; - private final PStack servletContextListenerData; - private final PStack servletRequestListenerData; - @Wither - private final SSLProperties SSLProperties; - - public GrizzlyApplication(AllData serverData) { - this.serverData = serverData.getServerData(); - this.filterData = serverData.getFilterDataList(); - this.servletData = serverData.getServletDataList(); - this.servletContextListenerData = serverData.getServletContextListeners(); - this.servletRequestListenerData = serverData.getServletRequestListeners(); - this.SSLProperties = null; - } - - public void run(CompletableFuture start, JaxRsServletConfigurer jaxRsConfigurer, CompletableFuture end) { - - WebappContext webappContext = new WebappContext("WebappContext", ""); - - new ServletContextListenerConfigurer(serverData, servletContextListenerData, servletRequestListenerData); - - - jaxRsConfigurer.addServlet(this.serverData,webappContext); - - new ServletConfigurer(serverData, servletData).addServlets(webappContext); - - new FilterConfigurer(serverData, this.filterData).addFilters(webappContext); - - addListeners(webappContext); - - HttpServer httpServer = HttpServer.createSimpleServer(null, "0.0.0.0", serverData.getPort()); - serverData.getModule().getServerConfigManager().accept(new WebServerProvider(httpServer)); - addAccessLog(httpServer); - if (SSLProperties != null) - this.createSSLListener(serverData.getPort()); - - startServer(webappContext, httpServer, start, end); - } - - private void startServer(WebappContext webappContext, HttpServer httpServer, CompletableFuture start, CompletableFuture end) { - webappContext.deploy(httpServer); - try { - logger.info("Starting application {} on port {}", serverData.getModule().getContext(), serverData.getPort()); - logger.info("Browse to http://localhost:{}/{}/application.wadl", serverData.getPort(), serverData.getModule().getContext()); - logger.info("Configured resource classes :-"); - serverData.extractResources() - .forEach(t -> logger.info(t.v1() + " : " + "http://localhost:" + serverData.getPort() + "/" + serverData.getModule().getContext() + t.v2())); - ; - httpServer.start(); - start.complete(true); - end.get(); - - } catch (IOException e) { - throw ExceptionSoftener.throwSoftenedException(e); - } catch (ExecutionException e) { - throw ExceptionSoftener.throwSoftenedException(e); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw ExceptionSoftener.throwSoftenedException(e); - } finally { - httpServer.stop(); - } - } - - private void addAccessLog(HttpServer httpServer) { - try { - String accessLogLocation = serverData.getRootContext().getBean(AccessLogLocationBean.class).getAccessLogLocation(); - - accessLogLocation = accessLogLocation + "/" + replaceSlash(serverData.getModule().getContext()) + "-access.log"; - final AccessLogBuilder builder = new AccessLogBuilder(accessLogLocation); - - builder.rotatedDaily(); - builder.rotationPattern("yyyy-MM-dd"); - builder.instrument(httpServer.getServerConfiguration()); - } catch (Exception e) { - logger.error(ErrorCode.SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG.toString() + ": " + e.getMessage()); - if (e.getCause() != null) - logger.error("CAUSED BY: " + ErrorCode.SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG.toString() + ": " + e.getCause().getMessage()); - - } - - } - - - private NetworkListener createSSLListener(int port) { - - SSLConfigurationBuilder sslBuilder = new SSLConfigurationBuilder(); - NetworkListener listener = new NetworkListener("grizzly", "0.0.0.0", Integer.valueOf(port)); - listener.getFileCache().setEnabled(false); - - listener.setSecure(true); - listener.setSSLEngineConfig(sslBuilder.build(SSLProperties)); - - return listener; - } - - private void addListeners(WebappContext webappContext) { - new ServletContextListenerConfigurer(serverData, servletContextListenerData, servletRequestListenerData).addListeners(webappContext); - } - - private String replaceSlash(String context) { - if (context != null && context.contains("/")) { - return context.substring(0, context.indexOf("/")); - } - return context; - } - -} diff --git a/micro-grizzly/src/main/java/com/aol/micro/server/servers/grizzly/GrizzlyApplicationFactory.java b/micro-grizzly/src/main/java/com/aol/micro/server/servers/grizzly/GrizzlyApplicationFactory.java deleted file mode 100644 index 2fc9c4edb..000000000 --- a/micro-grizzly/src/main/java/com/aol/micro/server/servers/grizzly/GrizzlyApplicationFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.aol.micro.server.servers.grizzly; - -import java.util.List; - -import lombok.AllArgsConstructor; - -import org.pcollections.PStack; -import org.springframework.context.ApplicationContext; - -import com.aol.micro.server.module.Environment; -import com.aol.micro.server.module.Module; -import com.aol.micro.server.module.ModuleDataExtractor; -import com.aol.micro.server.servers.ServerApplication; -import com.aol.micro.server.servers.ServerApplicationFactory; -import com.aol.micro.server.servers.model.AllData; -import com.aol.micro.server.servers.model.FilterData; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.servers.model.ServletData; - -@AllArgsConstructor -public class GrizzlyApplicationFactory implements ServerApplicationFactory { - - - - - public ServerApplication createApp(final Module module, final ApplicationContext rootContext) { - ModuleDataExtractor extractor = new ModuleDataExtractor(module); - PStack resources = extractor.getRestResources(rootContext); - - Environment environment = rootContext.getBean(Environment.class); - - environment.assureModule(module); - String fullRestResource = "/" + module.getContext() + "/*"; - - ServerData serverData = new ServerData(environment.getModuleBean(module).getPort(), - resources, - rootContext, fullRestResource, module); - List filterDataList = extractor.createFilteredDataList(serverData); - List servletDataList = extractor.createServletDataList(serverData); - - GrizzlyApplication app = new GrizzlyApplication( - new AllData(serverData, - filterDataList, - servletDataList, - module.getListeners(serverData), - module.getRequestListeners(serverData))); - return app; - } -} diff --git a/micro-grizzly/src/main/java/com/aol/micro/server/servers/grizzly/SSLConfigurationBuilder.java b/micro-grizzly/src/main/java/com/aol/micro/server/servers/grizzly/SSLConfigurationBuilder.java deleted file mode 100644 index 1a56595d0..000000000 --- a/micro-grizzly/src/main/java/com/aol/micro/server/servers/grizzly/SSLConfigurationBuilder.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.aol.micro.server.servers.grizzly; - -import org.glassfish.grizzly.ssl.SSLContextConfigurator; -import org.glassfish.grizzly.ssl.SSLEngineConfigurator; - -import com.aol.micro.server.config.SSLProperties; - -public class SSLConfigurationBuilder { - - - public SSLEngineConfigurator build(SSLProperties sslProperties) { - - SSLContextConfigurator sslContext = new SSLContextConfigurator(); - - sslContext.setKeyStoreFile(sslProperties.getKeyStoreFile()); // contains server keypair - sslContext.setKeyStorePass(sslProperties.getKeyStorePass()); - sslContext.setTrustStoreFile(sslProperties.getTrustStoreFile()); // contains client certificate - sslContext.setTrustStorePass(sslProperties.getTrustStorePass()); - - - - sslProperties.getKeyStoreType().peek(type->sslContext.setKeyStoreType(type)); - sslProperties.getKeyStoreProvider().peek(provider->sslContext.setKeyStoreProvider(provider)); - - - sslProperties.getTrustStoreType().peek(type->sslContext.setTrustStoreType(type)); - sslProperties.getTrustStoreProvider().peek(provider->sslContext.setTrustStoreProvider(provider)); - - - - - - SSLEngineConfigurator sslConf = new SSLEngineConfigurator(sslContext).setClientMode(false); - sslProperties.getClientAuth().filter(auth-> auth.toLowerCase().equals("want")) - .peek(auth->sslConf.setWantClientAuth(true)); - sslProperties.getClientAuth().filter(auth-> auth.toLowerCase().equals("need")) - .peek(auth->sslConf.setNeedClientAuth(true)); - sslProperties.getCiphers().peek(ciphers->sslConf.setEnabledCipherSuites(ciphers.split(","))) - .peek(c-> sslConf.setCipherConfigured(true)); - sslProperties.getProtocol().peek(pr->sslConf.setEnabledProtocols(pr.split(","))) - .peek(p->sslConf.setProtocolConfigured(true)); - - - return sslConf; - } -} diff --git a/micro-grizzly/src/main/java/com/aol/micro/server/servers/grizzly/plugin/GrizzlyPlugin.java b/micro-grizzly/src/main/java/com/aol/micro/server/servers/grizzly/plugin/GrizzlyPlugin.java deleted file mode 100644 index 97989de8f..000000000 --- a/micro-grizzly/src/main/java/com/aol/micro/server/servers/grizzly/plugin/GrizzlyPlugin.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.aol.micro.server.servers.grizzly.plugin; - -import java.util.Optional; - -import com.aol.micro.server.Plugin; -import com.aol.micro.server.servers.ServerApplicationFactory; -import com.aol.micro.server.servers.grizzly.GrizzlyApplicationFactory; - - -public class GrizzlyPlugin implements Plugin{ - - @Override - public Optional serverApplicationFactory(){ - return Optional.of(new GrizzlyApplicationFactory()); - } - - -} diff --git a/micro-grizzly/src/main/java/com/oath/micro/server/servers/grizzly/GrizzlyApplication.java b/micro-grizzly/src/main/java/com/oath/micro/server/servers/grizzly/GrizzlyApplication.java new file mode 100644 index 000000000..ca46b1a50 --- /dev/null +++ b/micro-grizzly/src/main/java/com/oath/micro/server/servers/grizzly/GrizzlyApplication.java @@ -0,0 +1,166 @@ +package com.oath.micro.server.servers.grizzly; + +import java.io.IOException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import javax.servlet.ServletContextListener; +import javax.servlet.ServletRequestListener; + +import com.oath.cyclops.types.persistent.PersistentList; +import com.oath.cyclops.util.ExceptionSoftener; +import org.glassfish.grizzly.http.server.HttpServer; +import org.glassfish.grizzly.http.server.NetworkListener; +import org.glassfish.grizzly.http.server.accesslog.AccessLogBuilder; +import org.glassfish.grizzly.servlet.WebappContext; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +import com.oath.micro.server.InternalErrorCode; +import com.oath.micro.server.config.SSLProperties; +import com.oath.micro.server.module.WebServerProvider; +import com.oath.micro.server.servers.AccessLogLocationBean; +import com.oath.micro.server.servers.FilterConfigurer; +import com.oath.micro.server.servers.JaxRsServletConfigurer; +import com.oath.micro.server.servers.ServerApplication; +import com.oath.micro.server.servers.ServletConfigurer; +import com.oath.micro.server.servers.ServletContextListenerConfigurer; +import com.oath.micro.server.servers.model.AllData; +import com.oath.micro.server.servers.model.FilterData; +import com.oath.micro.server.servers.model.ServerData; +import com.oath.micro.server.servers.model.ServletData; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.beans.factory.BeanNotOfRequiredTypeException; + +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class GrizzlyApplication implements ServerApplication { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Getter + private final ServerData serverData; + + private final PersistentList filterData; + private final PersistentList servletData; + private final PersistentList servletContextListenerData; + private final PersistentList servletRequestListenerData; + + public GrizzlyApplication(AllData serverData) { + this.serverData = serverData.getServerData(); + this.filterData = serverData.getFilterDataList(); + this.servletData = serverData.getServletDataList(); + this.servletContextListenerData = serverData.getServletContextListeners(); + this.servletRequestListenerData = serverData.getServletRequestListeners(); + } + + public void run(CompletableFuture start, JaxRsServletConfigurer jaxRsConfigurer, CompletableFuture end) { + + WebappContext webappContext = new WebappContext("WebappContext", ""); + + new ServletContextListenerConfigurer(serverData, servletContextListenerData, servletRequestListenerData); + + + jaxRsConfigurer.addServlet(this.serverData,webappContext); + + new ServletConfigurer(serverData, servletData).addServlets(webappContext); + + new FilterConfigurer(serverData, this.filterData).addFilters(webappContext); + + addListeners(webappContext); + + HttpServer httpServer = HttpServer.createSimpleServer(null, "0.0.0.0", serverData.getPort()); + serverData.getModule().getServerConfigManager().accept(new WebServerProvider(httpServer)); + addAccessLog(httpServer); + addSSL(httpServer); + + startServer(webappContext, httpServer, start, end); + } + + private void addSSL(HttpServer httpServer) { + + try { + + SSLProperties sslProperties = serverData.getRootContext().getBean(SSLProperties.class); + if (sslProperties != null) { + httpServer.addListener(this.createSSLListener(serverData.getPort(), sslProperties)); + } + + }catch(BeanNotOfRequiredTypeException e){ + + } + + } + + private void startServer(WebappContext webappContext, HttpServer httpServer, CompletableFuture start, CompletableFuture end) { + webappContext.deploy(httpServer); + try { + logger.info("Starting application {} on port {}", serverData.getModule().getContext(), serverData.getPort()); + logger.info("Browse to http://localhost:{}{}/application.wadl", serverData.getPort(), serverData.getNormalizedContextPath()); + logger.info("Configured resource classes :-"); + serverData.extractResources() + .forEach(t -> logger.info(t._1() + " : " + "http://localhost:" + serverData.getPort() + "/" + serverData.getNormalizedContextPath() + t._2())); + ; + httpServer.start(); + start.complete(true); + end.get(); + + } catch (IOException e) { + throw ExceptionSoftener.throwSoftenedException(e); + } catch (ExecutionException e) { + throw ExceptionSoftener.throwSoftenedException(e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw ExceptionSoftener.throwSoftenedException(e); + } finally { + httpServer.stop(); + } + } + + private void addAccessLog(HttpServer httpServer) { + try { + String accessLogLocation = serverData.getRootContext().getBean(AccessLogLocationBean.class).getAccessLogLocation(); + + accessLogLocation = accessLogLocation + "/" + replaceSlash(serverData.getModule().getContext()) + "-access.log"; + final AccessLogBuilder builder = new AccessLogBuilder(accessLogLocation); + + builder.rotatedDaily(); + builder.rotationPattern("yyyy-MM-dd"); + builder.instrument(httpServer.getServerConfiguration()); + } catch (Exception e) { + logger.error(InternalErrorCode.SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG.toString() + ": " + e.getMessage()); + if (e.getCause() != null) + logger.error("CAUSED BY: " + InternalErrorCode.SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG.toString() + ": " + e.getCause().getMessage()); + + } + } + + + private NetworkListener createSSLListener(int port, SSLProperties sslProperties) { + + SSLConfigurationBuilder sslBuilder = new SSLConfigurationBuilder(); + NetworkListener listener = new NetworkListener("grizzly", "0.0.0.0", Integer.valueOf(port)); + listener.getFileCache().setEnabled(false); + + listener.setSecure(true); + listener.setSSLEngineConfig(sslBuilder.build(sslProperties)); + + return listener; + } + + private void addListeners(WebappContext webappContext) { + new ServletContextListenerConfigurer(serverData, servletContextListenerData, servletRequestListenerData).addListeners(webappContext); + } + + private String replaceSlash(String context) { + if (context != null && context.contains("/")) { + return context.substring(0, context.indexOf("/")); + } + return context; + } + +} diff --git a/micro-grizzly/src/main/java/com/oath/micro/server/servers/grizzly/GrizzlyApplicationFactory.java b/micro-grizzly/src/main/java/com/oath/micro/server/servers/grizzly/GrizzlyApplicationFactory.java new file mode 100644 index 000000000..dd207c3da --- /dev/null +++ b/micro-grizzly/src/main/java/com/oath/micro/server/servers/grizzly/GrizzlyApplicationFactory.java @@ -0,0 +1,50 @@ +package com.oath.micro.server.servers.grizzly; + +import java.util.List; + +import com.oath.cyclops.types.persistent.PersistentList; +import com.oath.micro.server.module.MicroserverEnvironment; +import lombok.AllArgsConstructor; + + +import org.springframework.context.ApplicationContext; + +import com.oath.micro.server.module.Module; +import com.oath.micro.server.module.ModuleDataExtractor; +import com.oath.micro.server.servers.ServerApplication; +import com.oath.micro.server.servers.ServerApplicationFactory; +import com.oath.micro.server.servers.model.AllData; +import com.oath.micro.server.servers.model.FilterData; +import com.oath.micro.server.servers.model.ServerData; +import com.oath.micro.server.servers.model.ServletData; + +@AllArgsConstructor +public class GrizzlyApplicationFactory implements ServerApplicationFactory { + + + + + public ServerApplication createApp(final Module module, final ApplicationContext rootContext) { + ModuleDataExtractor extractor = new ModuleDataExtractor(module); + PersistentList resources = extractor.getRestResources(rootContext); + + MicroserverEnvironment microserverEnvironment = rootContext.getBean(MicroserverEnvironment.class); + + microserverEnvironment.assureModule(module); + String fullRestResource = "/" + module.getContext() + "/*"; + + ServerData serverData = new ServerData(microserverEnvironment.getModuleBean(module).getPort(), + resources, + rootContext, fullRestResource, module); + List filterDataList = extractor.createFilteredDataList(serverData); + List servletDataList = extractor.createServletDataList(serverData); + + GrizzlyApplication app = new GrizzlyApplication( + new AllData(serverData, + filterDataList, + servletDataList, + module.getListeners(serverData), + module.getRequestListeners(serverData))); + return app; + } +} diff --git a/micro-grizzly/src/main/java/com/oath/micro/server/servers/grizzly/SSLConfigurationBuilder.java b/micro-grizzly/src/main/java/com/oath/micro/server/servers/grizzly/SSLConfigurationBuilder.java new file mode 100644 index 000000000..e043a91f2 --- /dev/null +++ b/micro-grizzly/src/main/java/com/oath/micro/server/servers/grizzly/SSLConfigurationBuilder.java @@ -0,0 +1,52 @@ +package com.oath.micro.server.servers.grizzly; + +import cyclops.control.Maybe; +import org.glassfish.grizzly.ssl.SSLContextConfigurator; +import org.glassfish.grizzly.ssl.SSLEngineConfigurator; + +import com.oath.micro.server.config.SSLProperties; + +public class SSLConfigurationBuilder { + + + public SSLEngineConfigurator build(SSLProperties sslProperties) { + + SSLContextConfigurator sslContext = new SSLContextConfigurator(); + + sslContext.setKeyStoreFile(sslProperties.getKeyStoreFile()); // contains server keypair + sslContext.setKeyStorePass(sslProperties.getKeyStorePass()); + + /** + * trustStore stores public key or certificates from CA (Certificate Authorities) + * which is used to trust remote party or SSL connection. So should be optional + */ + sslProperties.getTrustStoreFile().ifPresent(file->sslContext.setTrustStoreFile(file)); // contains client certificate + sslProperties.getTrustStorePass().ifPresent(pass->sslContext.setTrustStorePass(pass)); + + + + sslProperties.getKeyStoreType().ifPresent(type->sslContext.setKeyStoreType(type)); + sslProperties.getKeyStoreProvider().ifPresent(provider->sslContext.setKeyStoreProvider(provider)); + + + sslProperties.getTrustStoreType().ifPresent(type->sslContext.setTrustStoreType(type)); + sslProperties.getTrustStoreProvider().ifPresent(provider->sslContext.setTrustStoreProvider(provider)); + + + + + + SSLEngineConfigurator sslConf = new SSLEngineConfigurator(sslContext).setClientMode(false); + sslProperties.getClientAuth().filter(auth-> auth.toLowerCase().equals("want")) + .ifPresent(auth->sslConf.setWantClientAuth(true)); + sslProperties.getClientAuth().filter(auth-> auth.toLowerCase().equals("need")) + .ifPresent(auth->sslConf.setNeedClientAuth(true)); + Maybe.fromOptional(sslProperties.getCiphers()).peek(ciphers->sslConf.setEnabledCipherSuites(ciphers.split(","))) + .forEach(c-> sslConf.setCipherConfigured(true)); + Maybe.fromOptional(sslProperties.getProtocol()).peek(pr->sslConf.setEnabledProtocols(pr.split(","))) + .forEach(p->sslConf.setProtocolConfigured(true)); + + + return sslConf; + } +} diff --git a/micro-grizzly/src/main/java/com/oath/micro/server/servers/grizzly/plugin/GrizzlyPlugin.java b/micro-grizzly/src/main/java/com/oath/micro/server/servers/grizzly/plugin/GrizzlyPlugin.java new file mode 100644 index 000000000..13ff94f0a --- /dev/null +++ b/micro-grizzly/src/main/java/com/oath/micro/server/servers/grizzly/plugin/GrizzlyPlugin.java @@ -0,0 +1,18 @@ +package com.oath.micro.server.servers.grizzly.plugin; + +import java.util.Optional; + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.servers.ServerApplicationFactory; +import com.oath.micro.server.servers.grizzly.GrizzlyApplicationFactory; + + +public class GrizzlyPlugin implements Plugin{ + + @Override + public Optional serverApplicationFactory(){ + return Optional.of(new GrizzlyApplicationFactory()); + } + + +} diff --git a/micro-grizzly/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-grizzly/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 6456cfd54..000000000 --- a/micro-grizzly/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.servers.grizzly.plugin.GrizzlyPlugin \ No newline at end of file diff --git a/micro-grizzly/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-grizzly/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..c32dea54f --- /dev/null +++ b/micro-grizzly/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.servers.grizzly.plugin.GrizzlyPlugin \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/access/log/micro/server/servers/AccessLogConfigTest.java b/micro-grizzly/src/test/java/app/access/log/micro/server/servers/AccessLogConfigTest.java index 9aac6b106..6bea5bf8a 100644 --- a/micro-grizzly/src/test/java/app/access/log/micro/server/servers/AccessLogConfigTest.java +++ b/micro-grizzly/src/test/java/app/access/log/micro/server/servers/AccessLogConfigTest.java @@ -11,8 +11,8 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; @Microserver(properties={"access.log.output", "${user.home}"}) public class AccessLogConfigTest { @@ -25,7 +25,7 @@ public class AccessLogConfigTest { public void startServer() throws IOException { logFile = new File(System.getProperty("user.home") + "/access-log-app-access.log"); - FileUtils.forceDelete(logFile); + FileUtils.deleteQuietly(logFile); assertThat(logFile.exists(), is(false)); diff --git a/micro-grizzly/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java b/micro-grizzly/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java deleted file mode 100644 index 979b5fbf5..000000000 --- a/micro-grizzly/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java +++ /dev/null @@ -1,57 +0,0 @@ -package app.async.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.io.IOException; -import java.util.Properties; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.spring.properties.PropertyFileConfig; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class AsyncAppRunner { - - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( ()-> "async-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - Thread.sleep(2000); - - assertThat(rest.get("http://localhost:8080/async-app/async/expensive"),is(";test!;test!;test!")); - - } - - @Test - public void loadProperties() throws IOException{ - - Properties props = new PropertyFileConfig(true).propertyFactory() ; - assertThat(props.getProperty("test"),is("hello world")); - } - - - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/async/com/aol/micro/server/AsyncResource.java b/micro-grizzly/src/test/java/app/async/com/aol/micro/server/AsyncResource.java deleted file mode 100644 index d87c018d6..000000000 --- a/micro-grizzly/src/test/java/app/async/com/aol/micro/server/AsyncResource.java +++ /dev/null @@ -1,56 +0,0 @@ -package app.async.com.aol.micro.server; - -import java.util.Arrays; -import java.util.List; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.container.Suspended; - -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.testing.RestAgent; - -@Path("/async") -@Component -public class AsyncResource implements RestResource{ - - private final SimpleReact simpleReact =new SimpleReact(); - private final List urls = Arrays.asList("http://localhost:8080/async-app/async/ping2", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping"); - - private final RestAgent client = new RestAgent(); - - @GET - @Path("/expensive") - @Produces("text/plain") - public void expensive(@Suspended AsyncResponse asyncResponse){ - - LazyFutureStream.lazyFutureStreamFromIterable(urls) - .then(it->client.get(it)) - .onFail(it -> "") - .peek(it -> - System.out.println(it)) - .convertToSimpleReact() - .allOf(data -> { - System.out.println(data); - return asyncResponse.resume(ReactiveSeq.fromIterable(data).join(";")); }); - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - -} diff --git a/micro-grizzly/src/test/java/app/async/com/aol/micro/server/Simple.java b/micro-grizzly/src/test/java/app/async/com/aol/micro/server/Simple.java deleted file mode 100644 index edefa80ef..000000000 --- a/micro-grizzly/src/test/java/app/async/com/aol/micro/server/Simple.java +++ /dev/null @@ -1,16 +0,0 @@ -package app.async.com.aol.micro.server; - -import java.io.IOException; -import java.util.Properties; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.spring.properties.PropertyFileConfig; - -public class Simple { - - public static void main(String[] args) throws IOException{ - - new MicroserverApp(()->"test-app").run(); - } -} diff --git a/micro-grizzly/src/test/java/app/async/com/aol/micro/server/SimpleApp.java b/micro-grizzly/src/test/java/app/async/com/aol/micro/server/SimpleApp.java deleted file mode 100644 index 919b7c6b0..000000000 --- a/micro-grizzly/src/test/java/app/async/com/aol/micro/server/SimpleApp.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.async.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; - - - -@Rest -@Path("/test") -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()->"test-app").run(); - } - @GET - public String myEndPoint(){ - return "hello world!"; - } - - -} diff --git a/micro-grizzly/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java b/micro-grizzly/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java new file mode 100644 index 000000000..5d6ea0ea7 --- /dev/null +++ b/micro-grizzly/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java @@ -0,0 +1,58 @@ +package app.async.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.Properties; +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.spring.properties.PropertyFileConfig; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class AsyncAppRunner { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + + server = new MicroserverApp( + () -> "async-app"); + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + Thread.sleep(2000); + + assertThat(rest.get("http://localhost:8080/async-app/async/expensive"), is(";test!;test!;test!")); + + } + + @Test + public void loadProperties() throws IOException { + + Properties props = new PropertyFileConfig( + true).propertyFactory(); + assertThat(props.getProperty("test"), is("hello world")); + assertThat(props.getProperty("override"), is("boo!")); + } + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/async/com/oath/micro/server/AsyncResource.java b/micro-grizzly/src/test/java/app/async/com/oath/micro/server/AsyncResource.java new file mode 100644 index 000000000..53d933ab5 --- /dev/null +++ b/micro-grizzly/src/test/java/app/async/com/oath/micro/server/AsyncResource.java @@ -0,0 +1,56 @@ +package app.async.com.oath.micro.server; + +import java.util.Arrays; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; + +import cyclops.futurestream.SimpleReact; +import cyclops.futurestream.FutureStream; +import cyclops.reactive.ReactiveSeq; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.testing.RestAgent; + +@Path("/async") +@Component +public class AsyncResource implements RestResource{ + + private final SimpleReact simpleReact =new SimpleReact(); + private final List urls = Arrays.asList("http://localhost:8080/async-app/async/ping2", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping"); + + private final RestAgent client = new RestAgent(); + + @GET + @Path("/expensive") + @Produces("text/plain") + public void expensive(@Suspended AsyncResponse asyncResponse){ + + FutureStream.builder().fromIterable(urls) + .then(it->client.get(it)) + .onFail(it -> "") + .peek(it -> + System.out.println(it)) + .convertToSimpleReact() + .allOf(data -> { + System.out.println(data); + return asyncResponse.resume(ReactiveSeq.fromIterable(data).join(";")); }); + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "test!"; + } + + +} diff --git a/micro-grizzly/src/test/java/app/async/com/oath/micro/server/Simple.java b/micro-grizzly/src/test/java/app/async/com/oath/micro/server/Simple.java new file mode 100644 index 000000000..3eb3e7504 --- /dev/null +++ b/micro-grizzly/src/test/java/app/async/com/oath/micro/server/Simple.java @@ -0,0 +1,13 @@ +package app.async.com.oath.micro.server; + +import java.io.IOException; + +import com.oath.micro.server.MicroserverApp; + +public class Simple { + + public static void main(String[] args) throws IOException{ + + new MicroserverApp(()->"test-app").run(); + } +} diff --git a/micro-grizzly/src/test/java/app/async/com/oath/micro/server/SimpleApp.java b/micro-grizzly/src/test/java/app/async/com/oath/micro/server/SimpleApp.java new file mode 100644 index 000000000..916d0330e --- /dev/null +++ b/micro-grizzly/src/test/java/app/async/com/oath/micro/server/SimpleApp.java @@ -0,0 +1,24 @@ +package app.async.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; + + + +@Rest +@Path("/test") +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()->"test-app").run(); + } + @GET + public String myEndPoint(){ + return "hello world!"; + } + + +} diff --git a/micro-grizzly/src/test/java/app/custom/binder/test/SimpleApp.java b/micro-grizzly/src/test/java/app/custom/binder/test/SimpleApp.java index 7a2c74e08..2e275f0bd 100644 --- a/micro-grizzly/src/test/java/app/custom/binder/test/SimpleApp.java +++ b/micro-grizzly/src/test/java/app/custom/binder/test/SimpleApp.java @@ -5,9 +5,9 @@ import org.glassfish.jersey.server.ResourceConfig; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.module.ConfigurableModule; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.module.ConfigurableModule; diff --git a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java b/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java deleted file mode 100644 index d4b8eff5c..000000000 --- a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java +++ /dev/null @@ -1,23 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.ArrayList; -import java.util.List; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -@Component -@Path("/alt-status") -public class AltAppResource implements AltAppRestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public List ping(ImmutableEntity entity) { - return entity.getList(); - } - -} diff --git a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java b/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java deleted file mode 100644 index 8cb2643e3..000000000 --- a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface AltAppRestResource extends RestResource { - -} diff --git a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java b/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java deleted file mode 100644 index 9e602c91c..000000000 --- a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.Arrays; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.EmbeddedModule; - -@Microserver(basePackages = { "app.embedded.com.aol.micro.server" }) -public class EmbeddedAppLocalMain { - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( - EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")).start(); - - } - - -} diff --git a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java b/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java deleted file mode 100644 index 47228dc0b..000000000 --- a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java +++ /dev/null @@ -1,102 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.NotFoundException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.EmbeddedModule; -import com.aol.micro.server.testing.RestAgent; - -public class EmbeddedAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer(){ - server = new MicroserverApp(EmbeddedAppLocalMain.class, - EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")); - server.start(); - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); - - - assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), - hasItem("hello")); - - } - - - @Test - public void nonBlockingRestClientTest(){ - assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"),is("-*test!-*test!")); - } - - CompletableFuture toCompletableFuture( - final ListenableFuture listenableFuture - ) { - //create an instance of CompletableFuture - CompletableFuture completable = new CompletableFuture() { - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - // propagate cancel to the listenable future - boolean result = listenableFuture.cancel(mayInterruptIfRunning); - super.cancel(mayInterruptIfRunning); - return result; - } - }; - - // add callback - listenableFuture.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(T result) { - completable.complete(result); - } - - @Override - public void onFailure(Throwable t) { - completable.completeExceptionally(t); - } - }); - return completable; - } - - @Test(expected=NotFoundException.class) - public void confirmAltAppCantUseTestAppResources(){ - - assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); - - } - @Test(expected=NotFoundException.class) - public void confirmTestAppCantUseAltAppResources(){ - - assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), - hasItem("hello")); - - } -} diff --git a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java b/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java deleted file mode 100644 index 778c55c90..000000000 --- a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java +++ /dev/null @@ -1,29 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableEntity { - - private final String value; - private final List list; - - public ImmutableEntity() { - this(null,null); - } - -} diff --git a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java b/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java deleted file mode 100644 index e93d43724..000000000 --- a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java +++ /dev/null @@ -1,48 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.Arrays; -import java.util.List; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.micro.server.testing.RestAgent; -@Component -@Path("/test-status") -public class TestAppResource implements TestAppRestResource { - - private final SimpleReact simpleReact = new SimpleReact(); - private final RestAgent template = new RestAgent(); - private final List urls = Arrays.asList("http://localhost:8081/alternative-app/alt-status/ping", - "http://localhost:8080/test-app/test-status/ping", - "http://localhost:8082/simple-app/status/ping", - "http://localhost:8080/test-app/test-status/ping"); - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - @GET - @Produces("text/plain") - @Path("/rest-calls") - public String restCallResult(){ - - return LazyFutureStream.lazyFutureStreamFromIterable(urls) - .map(it ->template.get(it)) - .then(it -> "*"+it) - .peek(loadedAndModified -> System.out.println(loadedAndModified)) - .block().stream().reduce("", (acc,next) -> acc+"-"+next); - - } - -} diff --git a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java b/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java deleted file mode 100644 index 3133fd8cc..000000000 --- a/micro-grizzly/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface TestAppRestResource extends RestResource { - -} diff --git a/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java new file mode 100644 index 000000000..1835ababe --- /dev/null +++ b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java @@ -0,0 +1,22 @@ +package app.embedded.com.oath.micro.server; + +import java.util.List; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +@Component +@Path("/alt-status") +public class AltAppResource implements AltAppRestResource { + + @POST + @Produces("application/json") + @Path("/ping") + public List ping(ImmutableEntity entity) { + return entity.getList(); + } + +} diff --git a/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java new file mode 100644 index 000000000..7045a4f35 --- /dev/null +++ b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java @@ -0,0 +1,7 @@ +package app.embedded.com.oath.micro.server; + +import com.oath.micro.server.auto.discovery.RestResource; + +public interface AltAppRestResource extends RestResource { + +} diff --git a/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java new file mode 100644 index 000000000..0a38613b7 --- /dev/null +++ b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java @@ -0,0 +1,22 @@ +package app.embedded.com.oath.micro.server; + +import java.util.Arrays; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.EmbeddedModule; + +@Microserver(basePackages = { "app.embedded.com.oath.micro.server" }) +public class EmbeddedAppLocalMain { + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( + EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), + EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")).start(); + + } + + +} diff --git a/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java new file mode 100644 index 000000000..16c1876ee --- /dev/null +++ b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java @@ -0,0 +1,105 @@ +package app.embedded.com.oath.micro.server; + +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.NotFoundException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.util.concurrent.ListenableFuture; +import org.springframework.util.concurrent.ListenableFutureCallback; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.EmbeddedModule; +import com.oath.micro.server.testing.RestAgent; + +public class EmbeddedAppTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer(){ + server = new MicroserverApp(EmbeddedAppLocalMain.class, + EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), + EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")); + server.start(); + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); + + + assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), + hasItem("hello")); + + } + + + @Test + public void nonBlockingRestClientTest(){ + + assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"), is("-*test!-*test!")); + + } + + CompletableFuture toCompletableFuture( + final ListenableFuture listenableFuture + ) { + //create an instance of CompletableFuture + CompletableFuture completable = new CompletableFuture() { + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + // propagate cancel to the listenable future + boolean result = listenableFuture.cancel(mayInterruptIfRunning); + super.cancel(mayInterruptIfRunning); + return result; + } + }; + + // add callback + listenableFuture.addCallback(new ListenableFutureCallback() { + @Override + public void onSuccess(T result) { + completable.complete(result); + } + + @Override + public void onFailure(Throwable t) { + completable.completeExceptionally(t); + } + }); + return completable; + } + + @Test(expected=NotFoundException.class) + public void confirmAltAppCantUseTestAppResources(){ + + assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); + + } + @Test(expected=NotFoundException.class) + public void confirmTestAppCantUseAltAppResources(){ + + assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), + hasItem("hello")); + + } +} diff --git a/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java new file mode 100644 index 000000000..337b63b89 --- /dev/null +++ b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java @@ -0,0 +1,29 @@ +package app.embedded.com.oath.micro.server; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "immutable") +@Getter +@AllArgsConstructor +@Builder +public class ImmutableEntity { + + private final String value; + private final List list; + + public ImmutableEntity() { + this(null,null); + } + +} diff --git a/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java new file mode 100644 index 000000000..9661a9672 --- /dev/null +++ b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java @@ -0,0 +1,47 @@ +package app.embedded.com.oath.micro.server; + +import java.util.Arrays; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import cyclops.futurestream.SimpleReact; +import cyclops.futurestream.FutureStream; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.testing.RestAgent; +@Component +@Path("/test-status") +public class TestAppResource implements TestAppRestResource { + + private final SimpleReact simpleReact = new SimpleReact(); + private final RestAgent template = new RestAgent(); + private final List urls = Arrays.asList( + "http://localhost:8080/test-app/test-status/ping","http://localhost:8080/test-app/test-status/ping"); + + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "test!"; + } + + @GET + @Produces("text/plain") + @Path("/rest-calls") + public String restCallResult(){ + + return FutureStream.builder().fromIterable(urls) + .map(it ->template.get(it)) + .then(it -> "*"+it) + .peek(loadedAndModified -> System.out.println(loadedAndModified)) + .block().stream().reduce("", (acc,next) -> acc+"-"+next); + + } + +} diff --git a/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java new file mode 100644 index 000000000..7d4df5753 --- /dev/null +++ b/micro-grizzly/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java @@ -0,0 +1,7 @@ +package app.embedded.com.oath.micro.server; + +import com.oath.micro.server.auto.discovery.RestResource; + +public interface TestAppRestResource extends RestResource { + +} diff --git a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/AutodiscoveredFilter.java b/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/AutodiscoveredFilter.java deleted file mode 100644 index 0ea5b4990..000000000 --- a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/AutodiscoveredFilter.java +++ /dev/null @@ -1,68 +0,0 @@ -package app.filter.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import lombok.Getter; -import lombok.Setter; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.FilterConfiguration; - -@Component -public class AutodiscoveredFilter implements Filter, FilterConfiguration { - - @Autowired - Bean bean; - @Getter - @Setter - private static volatile int called= 0; - - @Getter - private static boolean beanSet = false; - - @Override - public String[] getMapping() { - return new String[] { "/*" }; - } - public Class getFilter(){ - - return org.springframework.web.filter.DelegatingFilterProxy.class; - - } - public String getName(){ - return "autodiscoveredFilter"; - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - - called++; - if(bean!=null) - beanSet =true; - chain.doFilter(request, response); - } - - @Override - public void destroy() { - - - } - - - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/Bean.java b/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/Bean.java deleted file mode 100644 index f95b44b05..000000000 --- a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/Bean.java +++ /dev/null @@ -1,8 +0,0 @@ -package app.filter.com.aol.micro.server; - -import org.springframework.stereotype.Component; - -@Component -public class Bean { - -} diff --git a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/ConfiguredFilter.java b/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/ConfiguredFilter.java deleted file mode 100644 index e00bc941b..000000000 --- a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/ConfiguredFilter.java +++ /dev/null @@ -1,38 +0,0 @@ -package app.filter.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import lombok.Getter; - -public class ConfiguredFilter implements Filter { - - @Getter - private static volatile int called= 0; - @Override - public void init(FilterConfig filterConfig) throws ServletException { - // TODO Auto-generated method stub - - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - called++; - chain.doFilter(request, response); - - } - - @Override - public void destroy() { - // TODO Auto-generated method stub - - } - -} diff --git a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/FilterAppLocalMain.java b/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/FilterAppLocalMain.java deleted file mode 100644 index 25dc01cc3..000000000 --- a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/FilterAppLocalMain.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.filter.com.aol.micro.server; - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import app.servlet.com.aol.micro.server.AppRunnerLocalMain; - -import com.aol.micro.server.MicroserverApp; -@Configuration -@ComponentScan(basePackages = { "app.filter.com.aol.micro.server" }) -public class FilterAppLocalMain { - - - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( FilterAppLocalMain.class, () -> "filter-app") - .run(); - } - - } \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/FilterRunnerTest.java b/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/FilterRunnerTest.java deleted file mode 100644 index 239ca7258..000000000 --- a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/FilterRunnerTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package app.filter.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.Map; -import java.util.concurrent.ExecutionException; - -import javax.servlet.Filter; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; -import com.aol.micro.server.utility.HashMapBuilder; - - - -public class FilterRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - Map filters = HashMapBuilder.map("/filter-app/status/ping2",new ConfiguredFilter()).build(); - server = new MicroserverApp(ConfigurableModule.builder() - .context("filter-app") - .filters(filters ) - .requestListeners(Arrays.asList(new org.springframework.web.context.request.RequestContextListener())).build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testAutoDiscoveredFilter() throws InterruptedException, ExecutionException{ - AutodiscoveredFilter.setCalled(0); - - assertThat(rest.get("http://localhost:8080/filter-app/status/ping"),is("ok")); - assertThat(AutodiscoveredFilter.getCalled(),is(1)); - assertThat(AutodiscoveredFilter.isBeanSet(),is(true)); - } - @Test - public void testConfiguredFilter() throws InterruptedException, ExecutionException{ - - assertThat(ConfiguredFilter.getCalled(),is(0)); - assertThat(rest.get("http://localhost:8080/filter-app/status/ping2"),is("ok")); - assertThat(ConfiguredFilter.getCalled(),is(1)); - } - - - - -} diff --git a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/FilterStatusResource.java b/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/FilterStatusResource.java deleted file mode 100644 index 2d046711b..000000000 --- a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/FilterStatusResource.java +++ /dev/null @@ -1,37 +0,0 @@ -package app.filter.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; -import org.springframework.web.context.WebApplicationContext; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) -@Path("/status") -public class FilterStatusResource implements RestResource { - - @Autowired - private RequestScopeUserInfo info; - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - info.print(); - return "ok"; - } - @GET - @Produces("text/plain") - @Path("/ping2") - public String ping2() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/RequestScopeUserInfo.java b/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/RequestScopeUserInfo.java deleted file mode 100644 index c41605c39..000000000 --- a/micro-grizzly/src/test/java/app/filter/com/aol/micro/server/RequestScopeUserInfo.java +++ /dev/null @@ -1,20 +0,0 @@ -package app.filter.com.aol.micro.server; - -import javax.servlet.http.HttpServletRequest; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.context.annotation.ScopedProxyMode; -import org.springframework.stereotype.Component; -import org.springframework.web.context.WebApplicationContext; - -@Component -@Scope(value=WebApplicationContext.SCOPE_REQUEST,proxyMode=ScopedProxyMode.TARGET_CLASS) -public class RequestScopeUserInfo { - @Autowired - private HttpServletRequest request; - - public void print(){ - System.out.println(request.getAttribute("oc.info")); - } -} diff --git a/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/AutodiscoveredFilter.java b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/AutodiscoveredFilter.java new file mode 100644 index 000000000..1f6dfc284 --- /dev/null +++ b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/AutodiscoveredFilter.java @@ -0,0 +1,70 @@ +package app.filter.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import cyclops.control.Either; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.auto.discovery.AutoFilterConfiguration; + +import lombok.Getter; +import lombok.Setter; + +@Component +public class AutodiscoveredFilter implements AutoFilterConfiguration { + + @Autowired + Bean bean; + @Getter + @Setter + private static volatile int called= 0; + + @Getter + private static boolean beanSet = false; + + @Override + public String[] getMapping() { + return new String[] { "/*" }; + } + public Either,Filter> getFilter(){ + + return Either.left(org.springframework.web.filter.DelegatingFilterProxy.class); + + } + public String getName(){ + return "autodiscoveredFilter"; + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + + called++; + if(bean!=null) + beanSet =true; + chain.doFilter(request, response); + } + + @Override + public void destroy() { + + + } + + + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/Bean.java b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/Bean.java new file mode 100644 index 000000000..e036a796f --- /dev/null +++ b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/Bean.java @@ -0,0 +1,8 @@ +package app.filter.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +@Component +public class Bean { + +} diff --git a/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/ConfiguredFilter.java b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/ConfiguredFilter.java new file mode 100644 index 000000000..aca52ad38 --- /dev/null +++ b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/ConfiguredFilter.java @@ -0,0 +1,38 @@ +package app.filter.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import lombok.Getter; + +public class ConfiguredFilter implements Filter { + + @Getter + private static volatile int called= 0; + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // TODO Auto-generated method stub + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + called++; + chain.doFilter(request, response); + + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + +} diff --git a/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/FilterAppLocalMain.java b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/FilterAppLocalMain.java new file mode 100644 index 000000000..ca4b44b28 --- /dev/null +++ b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/FilterAppLocalMain.java @@ -0,0 +1,20 @@ +package app.filter.com.oath.micro.server; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.MicroserverApp; +@Configuration +@ComponentScan(basePackages = { "app.filter.com.oath.micro.server" }) +public class FilterAppLocalMain { + + + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( FilterAppLocalMain.class, () -> "filter-app") + .run(); + } + + } \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/FilterRunnerTest.java b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/FilterRunnerTest.java new file mode 100644 index 000000000..d3c136b4a --- /dev/null +++ b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/FilterRunnerTest.java @@ -0,0 +1,64 @@ +package app.filter.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import javax.servlet.Filter; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; +import com.oath.micro.server.utility.HashMapBuilder; + + + +public class FilterRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + Map filters = HashMapBuilder.map("/filter-app/status/ping2",new ConfiguredFilter()).build(); + server = new MicroserverApp(ConfigurableModule.builder() + .context("filter-app") + .filters(filters ) + .requestListeners(Arrays.asList(new org.springframework.web.context.request.RequestContextListener())).build()); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void testAutoDiscoveredFilter() throws InterruptedException, ExecutionException{ + AutodiscoveredFilter.setCalled(0); + + assertThat(rest.get("http://localhost:8080/filter-app/status/ping"),is("ok")); + assertThat(AutodiscoveredFilter.getCalled(),is(1)); + assertThat(AutodiscoveredFilter.isBeanSet(),is(true)); + } + @Test + public void testConfiguredFilter() throws InterruptedException, ExecutionException{ + + assertThat(ConfiguredFilter.getCalled(),is(0)); + assertThat(rest.get("http://localhost:8080/filter-app/status/ping2"),is("ok")); + assertThat(ConfiguredFilter.getCalled(),is(1)); + } + + + + +} diff --git a/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/FilterStatusResource.java b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/FilterStatusResource.java new file mode 100644 index 000000000..c7166c216 --- /dev/null +++ b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/FilterStatusResource.java @@ -0,0 +1,36 @@ +package app.filter.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) +@Path("/status") +public class FilterStatusResource implements RestResource { + + @Autowired + private RequestScopeUserInfo info; + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + info.print(); + return "ok"; + } + @GET + @Produces("text/plain") + @Path("/ping2") + public String ping2() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/RequestScopeUserInfo.java b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/RequestScopeUserInfo.java new file mode 100644 index 000000000..84c19c3f4 --- /dev/null +++ b/micro-grizzly/src/test/java/app/filter/com/oath/micro/server/RequestScopeUserInfo.java @@ -0,0 +1,20 @@ +package app.filter.com.oath.micro.server; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.stereotype.Component; +import org.springframework.web.context.WebApplicationContext; + +@Component +@Scope(value=WebApplicationContext.SCOPE_REQUEST,proxyMode=ScopedProxyMode.TARGET_CLASS) +public class RequestScopeUserInfo { + @Autowired + private HttpServletRequest request; + + public void print(){ + System.out.println(request.getAttribute("oc.info")); + } +} diff --git a/micro-grizzly/src/test/java/app/jackson/custom/com/aol/micro/server/CustomRunnerTest.java b/micro-grizzly/src/test/java/app/jackson/custom/com/aol/micro/server/CustomRunnerTest.java deleted file mode 100644 index 338df9cbc..000000000 --- a/micro-grizzly/src/test/java/app/jackson/custom/com/aol/micro/server/CustomRunnerTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package app.jackson.custom.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class CustomRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - assertThat(rest.postString("http://localhost:8080/simple-app/status/ping","{\"primitive\":null}").getStatus(),is(500)); - - - } - - - -} diff --git a/micro-grizzly/src/test/java/app/jackson/custom/com/aol/micro/server/CustomStatusResource.java b/micro-grizzly/src/test/java/app/jackson/custom/com/aol/micro/server/CustomStatusResource.java deleted file mode 100644 index d765ba53f..000000000 --- a/micro-grizzly/src/test/java/app/jackson/custom/com/aol/micro/server/CustomStatusResource.java +++ /dev/null @@ -1,20 +0,0 @@ -package app.jackson.custom.com.aol.micro.server; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class CustomStatusResource { - - @POST - @Path("/ping") - public String ping(MyEntity entity) { - return "ok"; - - } - - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/jackson/custom/com/aol/micro/server/MapperExtension.java b/micro-grizzly/src/test/java/app/jackson/custom/com/aol/micro/server/MapperExtension.java deleted file mode 100644 index 3bd1c4e45..000000000 --- a/micro-grizzly/src/test/java/app/jackson/custom/com/aol/micro/server/MapperExtension.java +++ /dev/null @@ -1,18 +0,0 @@ -package app.jackson.custom.com.aol.micro.server; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.jackson.JacksonMapperConfigurator; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; - -@Component -public class MapperExtension implements JacksonMapperConfigurator { - - @Override - public void accept(ObjectMapper t) { - t.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true); - - } - -} diff --git a/micro-grizzly/src/test/java/app/jackson/custom/com/aol/micro/server/MyEntity.java b/micro-grizzly/src/test/java/app/jackson/custom/com/aol/micro/server/MyEntity.java deleted file mode 100644 index e62499bff..000000000 --- a/micro-grizzly/src/test/java/app/jackson/custom/com/aol/micro/server/MyEntity.java +++ /dev/null @@ -1,26 +0,0 @@ -package app.jackson.custom.com.aol.micro.server; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.Value; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "myentity") -public class MyEntity { - - @XmlElement(name="primitive") - int i; - - public MyEntity(int i) { - super(); - this.i = i; - } - public MyEntity(){ - this.i=-1; - } -} diff --git a/micro-grizzly/src/test/java/app/jackson/custom/com/oath/micro/server/CustomRunnerTest.java b/micro-grizzly/src/test/java/app/jackson/custom/com/oath/micro/server/CustomRunnerTest.java new file mode 100644 index 000000000..3275ccd5a --- /dev/null +++ b/micro-grizzly/src/test/java/app/jackson/custom/com/oath/micro/server/CustomRunnerTest.java @@ -0,0 +1,54 @@ +package app.jackson.custom.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class CustomRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + assertThat(rest.postString("http://localhost:8080/simple-app/status/ping","{\"primitive\":null}").getStatus(),is(400)); + + + } + + + +} diff --git a/micro-grizzly/src/test/java/app/jackson/custom/com/oath/micro/server/CustomStatusResource.java b/micro-grizzly/src/test/java/app/jackson/custom/com/oath/micro/server/CustomStatusResource.java new file mode 100644 index 000000000..6e8a488ba --- /dev/null +++ b/micro-grizzly/src/test/java/app/jackson/custom/com/oath/micro/server/CustomStatusResource.java @@ -0,0 +1,20 @@ +package app.jackson.custom.com.oath.micro.server; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class CustomStatusResource { + + @POST + @Path("/ping") + public String ping(MyEntity entity) { + return "ok"; + + } + + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/jackson/custom/com/oath/micro/server/MapperExtension.java b/micro-grizzly/src/test/java/app/jackson/custom/com/oath/micro/server/MapperExtension.java new file mode 100644 index 000000000..60a50428a --- /dev/null +++ b/micro-grizzly/src/test/java/app/jackson/custom/com/oath/micro/server/MapperExtension.java @@ -0,0 +1,18 @@ +package app.jackson.custom.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.jackson.JacksonMapperConfigurator; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +@Component +public class MapperExtension implements JacksonMapperConfigurator { + + @Override + public void accept(ObjectMapper t) { + t.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true); + + } + +} diff --git a/micro-grizzly/src/test/java/app/jackson/custom/com/oath/micro/server/MyEntity.java b/micro-grizzly/src/test/java/app/jackson/custom/com/oath/micro/server/MyEntity.java new file mode 100644 index 000000000..79f8f0b9a --- /dev/null +++ b/micro-grizzly/src/test/java/app/jackson/custom/com/oath/micro/server/MyEntity.java @@ -0,0 +1,24 @@ +package app.jackson.custom.com.oath.micro.server; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "myentity") +public class MyEntity { + + @XmlElement(name="primitive") + int i; + + public MyEntity(int i) { + super(); + this.i = i; + } + public MyEntity(){ + this.i=-1; + } +} diff --git a/micro-grizzly/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/IncludesRunnerTest.java b/micro-grizzly/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/IncludesRunnerTest.java deleted file mode 100644 index cb69f2db4..000000000 --- a/micro-grizzly/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/IncludesRunnerTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package app.jackson.includes.all.com.aol.micro.server.copy; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.core.Response; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(properties={"jackson.serialization","ALWAYS"}) -public class IncludesRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.getJson("http://localhost:8080/simple-app/status/ping"),is("{\"primitive\":null}")); - - - } - - - -} diff --git a/micro-grizzly/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/IncludesStatusResource.java b/micro-grizzly/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/IncludesStatusResource.java deleted file mode 100644 index 566d503b9..000000000 --- a/micro-grizzly/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/IncludesStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.jackson.includes.all.com.aol.micro.server.copy; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class IncludesStatusResource { - - @GET - @Path("/ping") - @Produces("application/json") - public MyEntity ping() { - return new MyEntity(); - - } - - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/MyEntity.java b/micro-grizzly/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/MyEntity.java deleted file mode 100644 index e2c6b02ba..000000000 --- a/micro-grizzly/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/MyEntity.java +++ /dev/null @@ -1,26 +0,0 @@ -package app.jackson.includes.all.com.aol.micro.server.copy; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.Value; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "myentity") -public class MyEntity { - - @XmlElement(name="primitive") - Integer i = null; - - public MyEntity(int i) { - super(); - this.i = i; - } - public MyEntity(){ - this.i=null; - } -} diff --git a/micro-grizzly/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/IncludesRunnerTest.java b/micro-grizzly/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/IncludesRunnerTest.java new file mode 100644 index 000000000..59fce660a --- /dev/null +++ b/micro-grizzly/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/IncludesRunnerTest.java @@ -0,0 +1,55 @@ +package app.jackson.includes.all.com.oath.micro.server.copy; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties={"jackson.serialization","ALWAYS"}) +public class IncludesRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.getJson("http://localhost:8080/simple-app/status/ping"),is("{\"primitive\":null}")); + + + } + + + +} diff --git a/micro-grizzly/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/IncludesStatusResource.java b/micro-grizzly/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/IncludesStatusResource.java new file mode 100644 index 000000000..bc0d8f3bb --- /dev/null +++ b/micro-grizzly/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/IncludesStatusResource.java @@ -0,0 +1,22 @@ +package app.jackson.includes.all.com.oath.micro.server.copy; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class IncludesStatusResource { + + @GET + @Path("/ping") + @Produces("application/json") + public MyEntity ping() { + return new MyEntity(); + + } + + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/MyEntity.java b/micro-grizzly/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/MyEntity.java new file mode 100644 index 000000000..2b28c5d5b --- /dev/null +++ b/micro-grizzly/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/MyEntity.java @@ -0,0 +1,24 @@ +package app.jackson.includes.all.com.oath.micro.server.copy; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "myentity") +public class MyEntity { + + @XmlElement(name="primitive") + Integer i = null; + + public MyEntity(int i) { + super(); + this.i = i; + } + public MyEntity(){ + this.i=null; + } +} diff --git a/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/IncludesRunnerTest.java b/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/IncludesRunnerTest.java deleted file mode 100644 index ee7b44059..000000000 --- a/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/IncludesRunnerTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package app.jackson.includes.nonnull.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.core.Response; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class IncludesRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.getJson("http://localhost:8080/simple-app/status/ping"),is("{}")); - - - } - - - -} diff --git a/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/IncludesStatusResource.java b/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/IncludesStatusResource.java deleted file mode 100644 index f3a9b74b4..000000000 --- a/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/IncludesStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.jackson.includes.nonnull.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class IncludesStatusResource { - - @GET - @Path("/ping") - @Produces("application/json") - public MyEntity ping() { - return new MyEntity(); - - } - - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/MyEntity.java b/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/MyEntity.java deleted file mode 100644 index 3caa39982..000000000 --- a/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/MyEntity.java +++ /dev/null @@ -1,26 +0,0 @@ -package app.jackson.includes.nonnull.com.aol.micro.server; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.Value; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "myentity") -public class MyEntity { - - @XmlElement(name="primitive") - Integer i = null; - - public MyEntity(int i) { - super(); - this.i = i; - } - public MyEntity(){ - this.i=null; - } -} diff --git a/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/IncludesRunnerTest.java b/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/IncludesRunnerTest.java new file mode 100644 index 000000000..0171ea10f --- /dev/null +++ b/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/IncludesRunnerTest.java @@ -0,0 +1,55 @@ +package app.jackson.includes.nonnull.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class IncludesRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.getJson("http://localhost:8080/simple-app/status/ping"),is("{}")); + + + } + + + +} diff --git a/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/IncludesStatusResource.java b/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/IncludesStatusResource.java new file mode 100644 index 000000000..477b68744 --- /dev/null +++ b/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/IncludesStatusResource.java @@ -0,0 +1,22 @@ +package app.jackson.includes.nonnull.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class IncludesStatusResource { + + @GET + @Path("/ping") + @Produces("application/json") + public MyEntity ping() { + return new MyEntity(); + + } + + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/MyEntity.java b/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/MyEntity.java new file mode 100644 index 000000000..6671f20d4 --- /dev/null +++ b/micro-grizzly/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/MyEntity.java @@ -0,0 +1,24 @@ +package app.jackson.includes.nonnull.com.oath.micro.server; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "myentity") +public class MyEntity { + + @XmlElement(name="primitive") + Integer i = null; + + public MyEntity(int i) { + super(); + this.i = i; + } + public MyEntity(){ + this.i=null; + } +} diff --git a/micro-grizzly/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java b/micro-grizzly/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java deleted file mode 100644 index d20d97709..000000000 --- a/micro-grizzly/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java +++ /dev/null @@ -1,31 +0,0 @@ -package app.listeners.com.aol.micro.server; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import lombok.Getter; - -import org.springframework.stereotype.Component; - -@Component -public class AutodiscoveredListener implements ServletContextListener { - - @Getter - private static volatile int called= 0; - - @Override - public void contextInitialized(ServletContextEvent sce) { - called ++; - - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - - - } - - - - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/listeners/com/aol/micro/server/ConfiguredListener.java b/micro-grizzly/src/test/java/app/listeners/com/aol/micro/server/ConfiguredListener.java deleted file mode 100644 index d15dcb76e..000000000 --- a/micro-grizzly/src/test/java/app/listeners/com/aol/micro/server/ConfiguredListener.java +++ /dev/null @@ -1,25 +0,0 @@ -package app.listeners.com.aol.micro.server; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import lombok.Getter; - -public class ConfiguredListener implements ServletContextListener { - - @Getter - private static volatile int called= 0; - - @Override - public void contextInitialized(ServletContextEvent sce) { - called ++; - - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - - - } - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java b/micro-grizzly/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java deleted file mode 100644 index 4f8d7ab69..000000000 --- a/micro-grizzly/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.listeners.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.ExecutionException; - -import javax.servlet.ServletContextListener; - - - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - - -@Microserver -public class ListenerRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - List listeners = Arrays.asList(new ConfiguredListener()); - server = new MicroserverApp( ListenerRunnerTest.class, ConfigurableModule.builder().context("listener-app").listeners(listeners ).build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testListeners() throws InterruptedException, ExecutionException{ - - assertThat(AutodiscoveredListener.getCalled(),is(1)); - assertThat(ConfiguredListener.getCalled(),is(1)); - } - - - - - -} diff --git a/micro-grizzly/src/test/java/app/listeners/com/oath/micro/server/AutodiscoveredListener.java b/micro-grizzly/src/test/java/app/listeners/com/oath/micro/server/AutodiscoveredListener.java new file mode 100644 index 000000000..9c7be370e --- /dev/null +++ b/micro-grizzly/src/test/java/app/listeners/com/oath/micro/server/AutodiscoveredListener.java @@ -0,0 +1,31 @@ +package app.listeners.com.oath.micro.server; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import lombok.Getter; + +import org.springframework.stereotype.Component; + +@Component +public class AutodiscoveredListener implements ServletContextListener { + + @Getter + private static volatile int called= 0; + + @Override + public void contextInitialized(ServletContextEvent sce) { + called ++; + + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + + + } + + + + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/listeners/com/oath/micro/server/ConfiguredListener.java b/micro-grizzly/src/test/java/app/listeners/com/oath/micro/server/ConfiguredListener.java new file mode 100644 index 000000000..86a7cd34b --- /dev/null +++ b/micro-grizzly/src/test/java/app/listeners/com/oath/micro/server/ConfiguredListener.java @@ -0,0 +1,25 @@ +package app.listeners.com.oath.micro.server; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import lombok.Getter; + +public class ConfiguredListener implements ServletContextListener { + + @Getter + private static volatile int called= 0; + + @Override + public void contextInitialized(ServletContextEvent sce) { + called ++; + + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + + + } + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/listeners/com/oath/micro/server/ListenerRunnerTest.java b/micro-grizzly/src/test/java/app/listeners/com/oath/micro/server/ListenerRunnerTest.java new file mode 100644 index 000000000..fa0222a76 --- /dev/null +++ b/micro-grizzly/src/test/java/app/listeners/com/oath/micro/server/ListenerRunnerTest.java @@ -0,0 +1,55 @@ +package app.listeners.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import javax.servlet.ServletContextListener; + + + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + + +@Microserver +public class ListenerRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + List listeners = Arrays.asList(new ConfiguredListener()); + server = new MicroserverApp( ListenerRunnerTest.class, ConfigurableModule.builder().context("listener-app").listeners(listeners ).build()); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void testListeners() throws InterruptedException, ExecutionException{ + + assertThat(AutodiscoveredListener.getCalled(),is(1)); + assertThat(ConfiguredListener.getCalled(),is(1)); + } + + + + + +} diff --git a/micro-grizzly/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java b/micro-grizzly/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java deleted file mode 100644 index 04367ecbd..000000000 --- a/micro-grizzly/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package app.minimal.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.testing.RestAgent; - -@Rest -@Path("/single") -public class MinimalClassTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "minimal-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java b/micro-grizzly/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java new file mode 100644 index 000000000..c018eb7b2 --- /dev/null +++ b/micro-grizzly/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java @@ -0,0 +1,57 @@ +package app.minimal.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.testing.RestAgent; + +@Rest +@Path("/single") +public class MinimalClassTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp(()-> "minimal-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoRunnerTest.java b/micro-grizzly/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoRunnerTest.java deleted file mode 100644 index bb052650c..000000000 --- a/micro-grizzly/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoRunnerTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package app.noanno.com.aol.micro.server.copy; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - - -public class NoAnnoRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); - - - } - - - -} diff --git a/micro-grizzly/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoStatusResource.java b/micro-grizzly/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoStatusResource.java deleted file mode 100644 index 8a3f5efaa..000000000 --- a/micro-grizzly/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoStatusResource.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.noanno.com.aol.micro.server.copy; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class NoAnnoStatusResource { - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/noanno/com/aol/micro/server/copy/SimpleApp.java b/micro-grizzly/src/test/java/app/noanno/com/aol/micro/server/copy/SimpleApp.java deleted file mode 100644 index 5fb7e2ca3..000000000 --- a/micro-grizzly/src/test/java/app/noanno/com/aol/micro/server/copy/SimpleApp.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.noanno.com.aol.micro.server.copy; - -import com.aol.micro.server.MicroserverApp; - -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()-> "simple-app").run(); - } - - -} diff --git a/micro-grizzly/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoRunnerTest.java b/micro-grizzly/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoRunnerTest.java new file mode 100644 index 000000000..589bf5144 --- /dev/null +++ b/micro-grizzly/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoRunnerTest.java @@ -0,0 +1,47 @@ +package app.noanno.com.oath.micro.server.copy; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; + + +public class NoAnnoRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp(()-> "simple-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); + + + } + + + +} diff --git a/micro-grizzly/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoStatusResource.java b/micro-grizzly/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoStatusResource.java new file mode 100644 index 000000000..11a42968e --- /dev/null +++ b/micro-grizzly/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoStatusResource.java @@ -0,0 +1,24 @@ +package app.noanno.com.oath.micro.server.copy; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class NoAnnoStatusResource { + + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/noanno/com/oath/micro/server/copy/SimpleApp.java b/micro-grizzly/src/test/java/app/noanno/com/oath/micro/server/copy/SimpleApp.java new file mode 100644 index 000000000..646004a31 --- /dev/null +++ b/micro-grizzly/src/test/java/app/noanno/com/oath/micro/server/copy/SimpleApp.java @@ -0,0 +1,12 @@ +package app.noanno.com.oath.micro.server.copy; + +import com.oath.micro.server.MicroserverApp; + +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()-> "simple-app").run(); + } + + +} diff --git a/micro-grizzly/src/test/java/app/properties/com/oath/micro/server/PropertiesClassTest.java b/micro-grizzly/src/test/java/app/properties/com/oath/micro/server/PropertiesClassTest.java new file mode 100644 index 000000000..166cc5be1 --- /dev/null +++ b/micro-grizzly/src/test/java/app/properties/com/oath/micro/server/PropertiesClassTest.java @@ -0,0 +1,60 @@ +package app.properties.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Value; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { "override", "oops" }, propertiesName = "application.properties") +@Path("/single") +public class PropertiesClassTest implements RestResource { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Value("${override}") + String overrideValue; + + @Before + public void startServer() { + + server = new MicroserverApp( + PropertiesClassTest.class, () -> "simple-app"); + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + assertThat(rest.get("http://localhost:8080/simple-app/single/ping"), is("boo!")); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return overrideValue; + } + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/properties/override/com/oath/micro/server/PropertiesClassTest.java b/micro-grizzly/src/test/java/app/properties/override/com/oath/micro/server/PropertiesClassTest.java new file mode 100644 index 000000000..dbea49437 --- /dev/null +++ b/micro-grizzly/src/test/java/app/properties/override/com/oath/micro/server/PropertiesClassTest.java @@ -0,0 +1,62 @@ +package app.properties.override.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { "simple-app1.port", "8080" }, propertiesName = "application.properties") +@Path("/single") +public class PropertiesClassTest implements RestResource { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + + System.setProperty("simple-app1.port", "8081"); + try { + server = new MicroserverApp( + PropertiesClassTest.class, () -> "simple-app1"); + server.start(); + + } finally { + System.setProperty("simple-app1.port", "8080"); + } + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + assertThat(rest.get("http://localhost:8081/simple-app1/single/ping"), is("boo!")); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "boo!"; + } + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java b/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java deleted file mode 100644 index b447491a1..000000000 --- a/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java +++ /dev/null @@ -1,20 +0,0 @@ -package app.servlet.com.aol.micro.server; - - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import com.aol.micro.server.MicroserverApp; - -@Configuration -@ComponentScan(basePackages = { "app.servlet.com.aol.micro.server" }) -public class AppRunnerLocalMain { - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( AppRunnerLocalMain.class, () -> "test-app") - .run(); - } - -} diff --git a/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java b/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java deleted file mode 100644 index d0123c905..000000000 --- a/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java +++ /dev/null @@ -1,30 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.ServletConfiguration; - -@Component -public class AutodiscoveredServlet extends HttpServlet implements ServletConfiguration { - - @Override - public String[] getMapping() { - return new String[] { "/servlet" }; - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - resp.setContentType("text/html"); - resp.getWriter().write("hello world"); - } - -} diff --git a/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java b/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java deleted file mode 100644 index 92577a92e..000000000 --- a/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class ConfiguredServlet extends HttpServlet { - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - resp.setContentType("text/html"); - resp.getWriter().write("configured servlet"); - } - - - -} diff --git a/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java b/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java deleted file mode 100644 index aa6e20b4f..000000000 --- a/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package app.servlet.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ExecutionException; - -import javax.servlet.Servlet; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -public class ServletRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - Map servlets = new HashMap<>(); - servlets.put("/configured", new ConfiguredServlet()); - server = new MicroserverApp( AppRunnerLocalMain.class, ConfigurableModule.builder().context("test-app").servlets(servlets ).build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/test-app/servlet/ping"),is("ok")); - - } - - @Test - public void autoDiscoveredServletTest() throws InterruptedException, ExecutionException{ - - - assertThat(rest.get("http://localhost:8080/servlet"),is("hello world")); - - } - - @Test - public void configuredServletTest() throws InterruptedException, ExecutionException{ - - - assertThat(rest.get("http://localhost:8080/configured"),is("configured servlet")); - - } - - -} diff --git a/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java b/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java deleted file mode 100644 index 890a64679..000000000 --- a/micro-grizzly/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/servlet") -public class ServletStatusResource implements RestResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/AppRunnerLocalMain.java b/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/AppRunnerLocalMain.java new file mode 100644 index 000000000..217fc92d4 --- /dev/null +++ b/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/AppRunnerLocalMain.java @@ -0,0 +1,20 @@ +package app.servlet.com.oath.micro.server; + + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.MicroserverApp; + +@Configuration +@ComponentScan(basePackages = { "app.servlet.com.oath.micro.server" }) +public class AppRunnerLocalMain { + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( AppRunnerLocalMain.class, () -> "test-app") + .run(); + } + +} diff --git a/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/AutodiscoveredServlet.java b/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/AutodiscoveredServlet.java new file mode 100644 index 000000000..66cbfd59c --- /dev/null +++ b/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/AutodiscoveredServlet.java @@ -0,0 +1,30 @@ +package app.servlet.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.AutoServletConfiguration; + +@Component +public class AutodiscoveredServlet extends HttpServlet implements AutoServletConfiguration { + + @Override + public String[] getMapping() { + return new String[] { "/servlet" }; + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + resp.setContentType("text/html"); + resp.getWriter().write("hello world"); + } + +} diff --git a/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/ConfiguredServlet.java b/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/ConfiguredServlet.java new file mode 100644 index 000000000..65de82291 --- /dev/null +++ b/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/ConfiguredServlet.java @@ -0,0 +1,21 @@ +package app.servlet.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class ConfiguredServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + resp.setContentType("text/html"); + resp.getWriter().write("configured servlet"); + } + + + +} diff --git a/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/ServletRunnerTest.java b/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/ServletRunnerTest.java new file mode 100644 index 000000000..39f3896e3 --- /dev/null +++ b/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/ServletRunnerTest.java @@ -0,0 +1,64 @@ +package app.servlet.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import javax.servlet.Servlet; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +public class ServletRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + Map servlets = new HashMap<>(); + servlets.put("/configured", new ConfiguredServlet()); + server = new MicroserverApp( AppRunnerLocalMain.class, ConfigurableModule.builder().context("test-app").servlets(servlets ).build()); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/test-app/servlet/ping"),is("ok")); + + } + + @Test + public void autoDiscoveredServletTest() throws InterruptedException, ExecutionException{ + + + assertThat(rest.get("http://localhost:8080/servlet"),is("hello world")); + + } + + @Test + public void configuredServletTest() throws InterruptedException, ExecutionException{ + + + assertThat(rest.get("http://localhost:8080/configured"),is("configured servlet")); + + } + + +} diff --git a/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/ServletStatusResource.java b/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/ServletStatusResource.java new file mode 100644 index 000000000..6d86eeb84 --- /dev/null +++ b/micro-grizzly/src/test/java/app/servlet/com/oath/micro/server/ServletStatusResource.java @@ -0,0 +1,22 @@ +package app.servlet.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/servlet") +public class ServletStatusResource implements RestResource { + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java b/micro-grizzly/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java deleted file mode 100644 index 700a2c778..000000000 --- a/micro-grizzly/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java +++ /dev/null @@ -1,18 +0,0 @@ -package app.simple.com.aol.micro.server; - -import java.util.Arrays; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; - -public class SimpleApp { - - public static void main(String[] args){ - - new MicroserverApp(()-> "simple-app").run(); - } - - -} diff --git a/micro-grizzly/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java b/micro-grizzly/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java deleted file mode 100644 index 6249ef506..000000000 --- a/micro-grizzly/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.simple.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class SimpleRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - // server = new MicroserverApp(()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); - - - } - - - -} diff --git a/micro-grizzly/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java b/micro-grizzly/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java deleted file mode 100644 index 07b6a5610..000000000 --- a/micro-grizzly/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java +++ /dev/null @@ -1,40 +0,0 @@ -package app.simple.com.aol.micro.server; - -import java.io.InputStream; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; -import org.glassfish.jersey.media.multipart.FormDataParam; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class SimpleStatusResource { - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return "ok"; - } - - @POST - @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces(MediaType.TEXT_PLAIN) - @Path("/file") - public String create(@FormDataParam("file") InputStream fileInputStream, - @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { - - return "done"; - } -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java b/micro-grizzly/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java new file mode 100644 index 000000000..e82a92291 --- /dev/null +++ b/micro-grizzly/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java @@ -0,0 +1,13 @@ +package app.simple.com.oath.micro.server; + +import com.oath.micro.server.MicroserverApp; + +public class SimpleApp { + + public static void main(String[] args){ + + new MicroserverApp(()-> "simple-app").run(); + } + + +} diff --git a/micro-grizzly/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java b/micro-grizzly/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java new file mode 100644 index 000000000..ce6dd819a --- /dev/null +++ b/micro-grizzly/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java @@ -0,0 +1,55 @@ +package app.simple.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class SimpleRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + // server = new MicroserverApp(()-> "simple-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); + + + } + + + +} diff --git a/micro-grizzly/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java b/micro-grizzly/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java new file mode 100644 index 000000000..7be280bdf --- /dev/null +++ b/micro-grizzly/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java @@ -0,0 +1,40 @@ +package app.simple.com.oath.micro.server; + +import java.io.InputStream; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class SimpleStatusResource { + + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + return "ok"; + } + + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.TEXT_PLAIN) + @Path("/file") + public String create(@FormDataParam("file") InputStream fileInputStream, + @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { + + return "done"; + } +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java b/micro-grizzly/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java deleted file mode 100644 index d7725eed3..000000000 --- a/micro-grizzly/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package app.single.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -@Path("/single") -public class SingleClassTest implements RestResource{ - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( SingleClassTest.class, ()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/single/ping"),is("ok")); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java b/micro-grizzly/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java new file mode 100644 index 000000000..c5a34809d --- /dev/null +++ b/micro-grizzly/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java @@ -0,0 +1,58 @@ +package app.single.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +@Path("/single") +public class SingleClassTest implements RestResource{ + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( SingleClassTest.class, ()-> "simple-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/single/ping"),is("ok")); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java b/micro-grizzly/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java deleted file mode 100644 index aef7a170c..000000000 --- a/micro-grizzly/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.single.main.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class SingleClassApp { - - public static void main(String[] args){ - new MicroserverApp(()-> "simple-app").run(); - } - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} diff --git a/micro-grizzly/src/test/java/app/single/main/com/oath/micro/server/SingleClassApp.java b/micro-grizzly/src/test/java/app/single/main/com/oath/micro/server/SingleClassApp.java new file mode 100644 index 000000000..2d7a71917 --- /dev/null +++ b/micro-grizzly/src/test/java/app/single/main/com/oath/micro/server/SingleClassApp.java @@ -0,0 +1,24 @@ +package app.single.main.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class SingleClassApp { + + public static void main(String[] args){ + new MicroserverApp(()-> "simple-app").run(); + } + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} diff --git a/micro-grizzly/src/test/java/app/single/serverconfig/com/aol/micro/server/SingleClassTest.java b/micro-grizzly/src/test/java/app/single/serverconfig/com/aol/micro/server/SingleClassTest.java deleted file mode 100644 index af9af9878..000000000 --- a/micro-grizzly/src/test/java/app/single/serverconfig/com/aol/micro/server/SingleClassTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package app.single.serverconfig.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - - -@Path("/single") -public class SingleClassTest implements RestResource{ - - RestAgent rest = new RestAgent(); - - boolean called; - MicroserverApp server; - @Before - public void startServer(){ - called = false; - server = new MicroserverApp( ConfigurableModule.builder() - .context("hello") - .serverConfigManager(server->called=true) - .build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/hello/single/ping"),is("ok")); - assertTrue(called); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/single/serverconfig/com/oath/micro/server/SingleClassTest.java b/micro-grizzly/src/test/java/app/single/serverconfig/com/oath/micro/server/SingleClassTest.java new file mode 100644 index 000000000..4dbcb9705 --- /dev/null +++ b/micro-grizzly/src/test/java/app/single/serverconfig/com/oath/micro/server/SingleClassTest.java @@ -0,0 +1,63 @@ +package app.single.serverconfig.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + + +@Path("/single") +public class SingleClassTest implements RestResource{ + + RestAgent rest = new RestAgent(); + + boolean called; + MicroserverApp server; + @Before + public void startServer(){ + called = false; + server = new MicroserverApp( ConfigurableModule.builder() + .context("hello") + .serverConfigManager(server->called=true) + .build()); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/hello/single/ping"),is("ok")); + assertTrue(called); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/spring/com/aol/micro/server/MyBean.java b/micro-grizzly/src/test/java/app/spring/com/aol/micro/server/MyBean.java deleted file mode 100644 index 1f7a589ff..000000000 --- a/micro-grizzly/src/test/java/app/spring/com/aol/micro/server/MyBean.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.spring.com.aol.micro.server; - -import javax.inject.Inject; - -import lombok.Getter; - -@Getter -public class MyBean { - - @Inject - private MyDependency injected; -} diff --git a/micro-grizzly/src/test/java/app/spring/com/aol/micro/server/MyDependency.java b/micro-grizzly/src/test/java/app/spring/com/aol/micro/server/MyDependency.java deleted file mode 100644 index 48d89e6c5..000000000 --- a/micro-grizzly/src/test/java/app/spring/com/aol/micro/server/MyDependency.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.spring.com.aol.micro.server; - -import lombok.Getter; - -import org.springframework.stereotype.Component; - -@Component -@Getter -public class MyDependency { - - private String data = "hello world"; -} diff --git a/micro-grizzly/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java b/micro-grizzly/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java deleted file mode 100644 index 1a1765be0..000000000 --- a/micro-grizzly/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package app.spring.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.context.annotation.Bean; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; -/**@Configuration -@ComponentScan(basePackages = { "app.spring.com.aol.micro.server" })**/ -@Microserver -public class SpringRunnerTest { - - RestAgent rest = new RestAgent(); - - @Bean - public MyBean mybean(){ - return new MyBean(); - } - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( SpringRunnerTest.class, ()-> "spring-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testAutoWiring() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/spring-app/spring/ping"),is("hello world")); - - } - - - - - -} diff --git a/micro-grizzly/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java b/micro-grizzly/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java deleted file mode 100644 index 331ac997e..000000000 --- a/micro-grizzly/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java +++ /dev/null @@ -1,32 +0,0 @@ -package app.spring.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/spring") -public class SpringStatusResource implements RestResource { - - @Autowired - private MyBean mybean; - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return mybean.getInjected().getData(); - } - @GET - @Produces("text/plain") - @Path("/ping2") - public String ping2() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/spring/com/oath/micro/server/MyBean.java b/micro-grizzly/src/test/java/app/spring/com/oath/micro/server/MyBean.java new file mode 100644 index 000000000..328b7d185 --- /dev/null +++ b/micro-grizzly/src/test/java/app/spring/com/oath/micro/server/MyBean.java @@ -0,0 +1,12 @@ +package app.spring.com.oath.micro.server; + +import javax.inject.Inject; + +import lombok.Getter; + +@Getter +public class MyBean { + + @Inject + private MyDependency injected; +} diff --git a/micro-grizzly/src/test/java/app/spring/com/oath/micro/server/MyDependency.java b/micro-grizzly/src/test/java/app/spring/com/oath/micro/server/MyDependency.java new file mode 100644 index 000000000..1ca23b15b --- /dev/null +++ b/micro-grizzly/src/test/java/app/spring/com/oath/micro/server/MyDependency.java @@ -0,0 +1,12 @@ +package app.spring.com.oath.micro.server; + +import lombok.Getter; + +import org.springframework.stereotype.Component; + +@Component +@Getter +public class MyDependency { + + private String data = "hello world"; +} diff --git a/micro-grizzly/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java b/micro-grizzly/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java new file mode 100644 index 000000000..56483ff3b --- /dev/null +++ b/micro-grizzly/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java @@ -0,0 +1,54 @@ +package app.spring.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.annotation.Bean; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; +/**@Configuration +@ComponentScan(basePackages = { "app.spring.com.oath.micro.server" })**/ +@Microserver +public class SpringRunnerTest { + + RestAgent rest = new RestAgent(); + + @Bean + public MyBean mybean(){ + return new MyBean(); + } + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( SpringRunnerTest.class, ()-> "spring-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void testAutoWiring() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/spring-app/spring/ping"),is("hello world")); + + } + + + + + +} diff --git a/micro-grizzly/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java b/micro-grizzly/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java new file mode 100644 index 000000000..ae0c817de --- /dev/null +++ b/micro-grizzly/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java @@ -0,0 +1,32 @@ +package app.spring.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/spring") +public class SpringStatusResource implements RestResource { + + @Autowired + private MyBean mybean; + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return mybean.getInjected().getData(); + } + @GET + @Produces("text/plain") + @Path("/ping2") + public String ping2() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-grizzly/src/test/java/app/validation/com/aol/micro/server/ImmutableEntity.java b/micro-grizzly/src/test/java/app/validation/com/aol/micro/server/ImmutableEntity.java deleted file mode 100644 index 5af51d60c..000000000 --- a/micro-grizzly/src/test/java/app/validation/com/aol/micro/server/ImmutableEntity.java +++ /dev/null @@ -1,28 +0,0 @@ -package app.validation.com.aol.micro.server; - - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableEntity { - - private final String value; - - - public ImmutableEntity() { - this(null); - } - -} diff --git a/micro-grizzly/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java b/micro-grizzly/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java deleted file mode 100644 index 880c619e8..000000000 --- a/micro-grizzly/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java +++ /dev/null @@ -1,23 +0,0 @@ -package app.validation.com.aol.micro.server; - -import javax.validation.constraints.NotNull; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -@Component -@Path("/status") -public class ValidationAppResource implements RestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public ImmutableEntity ping( @NotNull ImmutableEntity entity) { - return entity; - } - - -} diff --git a/micro-grizzly/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java b/micro-grizzly/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java deleted file mode 100644 index fd153d579..000000000 --- a/micro-grizzly/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package app.validation.com.aol.micro.server; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.BadRequestException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.SimpleReactStream; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.testing.RestAgent; - -//@Microserver(basePackages = { "app.guava.com.aol.micro.server" }) -public class ValidationAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - ImmutableEntity entity; - - - SimpleReact simpleReact = new SimpleReact(); - SimpleReactStream stream; - - @Before - public void startServer() { - stream = simpleReact.ofAsync( - () -> server = new MicroserverApp(() -> "guava-app")).then(server -> server.start()); - - entity = ImmutableEntity.builder().value("value").build(); - - - } - - @After - public void stopServer() { - server.stop(); - } - - - @Test(expected=BadRequestException.class) - public void confirmError() throws InterruptedException, - ExecutionException { - - stream.block(); - rest.post( - "http://localhost:8080/guava-app/status/ping", null, - ImmutableEntity.class); - - - } - @Test - public void confirmNoError() throws InterruptedException, - ExecutionException { - - stream.block(); - rest.post( - "http://localhost:8080/guava-app/status/ping", entity, - ImmutableEntity.class); - - - } - - - -} diff --git a/micro-grizzly/src/test/java/app/validation/com/oath/micro/server/ImmutableEntity.java b/micro-grizzly/src/test/java/app/validation/com/oath/micro/server/ImmutableEntity.java new file mode 100644 index 000000000..19e8f5b26 --- /dev/null +++ b/micro-grizzly/src/test/java/app/validation/com/oath/micro/server/ImmutableEntity.java @@ -0,0 +1,28 @@ +package app.validation.com.oath.micro.server; + + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "immutable") +@Getter +@AllArgsConstructor +@Builder +public class ImmutableEntity { + + private final String value; + + + public ImmutableEntity() { + this(null); + } + +} diff --git a/micro-grizzly/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java b/micro-grizzly/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java new file mode 100644 index 000000000..7a8d0c325 --- /dev/null +++ b/micro-grizzly/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java @@ -0,0 +1,23 @@ +package app.validation.com.oath.micro.server; + +import javax.validation.constraints.NotNull; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +@Component +@Path("/status") +public class ValidationAppResource implements RestResource { + + @POST + @Produces("application/json") + @Path("/ping") + public ImmutableEntity ping( @NotNull ImmutableEntity entity) { + return entity; + } + + +} diff --git a/micro-grizzly/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java b/micro-grizzly/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java new file mode 100644 index 000000000..c560d1521 --- /dev/null +++ b/micro-grizzly/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java @@ -0,0 +1,71 @@ +package app.validation.com.oath.micro.server; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.BadRequestException; + +import com.oath.cyclops.types.futurestream.SimpleReactStream; +import cyclops.futurestream.SimpleReact; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; + +//@Microserver(basePackages = { "app.guava.com.oath.micro.server" }) +public class ValidationAppTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + ImmutableEntity entity; + + + SimpleReact simpleReact = new SimpleReact(); + SimpleReactStream stream; + + @Before + public void startServer() { + stream = simpleReact.ofAsync( + () -> server = new MicroserverApp(() -> "guava-app")).then(server -> server.start()); + + entity = ImmutableEntity.builder().value("value").build(); + + + } + + @After + public void stopServer() { + server.stop(); + } + + + @Test(expected=BadRequestException.class) + public void confirmError() throws InterruptedException, + ExecutionException { + + stream.block(); + rest.post( + "http://localhost:8080/guava-app/status/ping", null, + ImmutableEntity.class); + + + } + @Test + public void confirmNoError() throws InterruptedException, + ExecutionException { + + stream.block(); + rest.post( + "http://localhost:8080/guava-app/status/ping", entity, + ImmutableEntity.class); + + + } + + + +} diff --git a/micro-grizzly/src/test/java/com/aol/micro/server/servers/ServerRunnerTest.java b/micro-grizzly/src/test/java/com/aol/micro/server/servers/ServerRunnerTest.java deleted file mode 100644 index f70d9c89a..000000000 --- a/micro-grizzly/src/test/java/com/aol/micro/server/servers/ServerRunnerTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.aol.micro.server.servers; - -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.CompletableFuture; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; -import org.springframework.context.ApplicationContext; - -import com.aol.micro.server.servers.grizzly.GrizzlyApplication; -import com.aol.micro.server.servers.model.AllData; -import com.aol.micro.server.servers.model.ServerData; - - - -public class ServerRunnerTest { - - private ServerRunner serverRunner; - private GrizzlyApplication serverApplication1; - private GrizzlyApplication serverApplication2; - private ServerData[] registered; - volatile int server1Count =0; - volatile int server2Count =0; - @Before - public void setUp() { - - server1Count =0; - server2Count =0; - - ServerData data1 = new ServerData(8080,Arrays.asList(), Mockito.mock(ApplicationContext.class), "url1", () -> "app-context"); - ServerData data2 = new ServerData(8081, Arrays.asList(), Mockito.mock(ApplicationContext.class), "url2", () -> "test-context"); - - serverApplication1 = new GrizzlyApplication(AllData.builder().serverData(data1).build()){ - @Override - public void run(CompletableFuture start,JaxRsServletConfigurer jaxRsConfigurer, CompletableFuture end) { - server1Count++; - start.complete(true); - - } - }; - serverApplication2 = new GrizzlyApplication(AllData.builder().serverData(data2).build()){ - @Override - public void run(CompletableFuture start,JaxRsServletConfigurer jaxRsConfigurer,CompletableFuture end) { - server2Count++; - start.complete(true); - - } - }; - - serverRunner = new ServerRunner( (array) -> {registered = array; } , - Arrays.asList(serverApplication1, serverApplication2), new CompletableFuture()); - - - } - - @Test - public void testRun() { - serverRunner.run(); - assertThat(server1Count,is(1)); - assertThat(server2Count,is(1)); - } -} diff --git a/micro-grizzly/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-grizzly/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index 24b169f2e..000000000 --- a/micro-grizzly/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - public Response postString(String url, String payload) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(payload,MediaType.APPLICATION_JSON)); - } - -} diff --git a/micro-grizzly/src/test/java/com/oath/micro/server/servers/ServerRunnerTest.java b/micro-grizzly/src/test/java/com/oath/micro/server/servers/ServerRunnerTest.java new file mode 100644 index 000000000..a082597f2 --- /dev/null +++ b/micro-grizzly/src/test/java/com/oath/micro/server/servers/ServerRunnerTest.java @@ -0,0 +1,66 @@ +package com.oath.micro.server.servers; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.CompletableFuture; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.context.ApplicationContext; + +import com.oath.micro.server.servers.grizzly.GrizzlyApplication; +import com.oath.micro.server.servers.model.AllData; +import com.oath.micro.server.servers.model.ServerData; + + + +public class ServerRunnerTest { + + private ServerRunner serverRunner; + private GrizzlyApplication serverApplication1; + private GrizzlyApplication serverApplication2; + private ServerData[] registered; + volatile int server1Count =0; + volatile int server2Count =0; + @Before + public void setUp() { + + server1Count =0; + server2Count =0; + + ServerData data1 = new ServerData(8080,Arrays.asList(), Mockito.mock(ApplicationContext.class), "url1", () -> "app-context"); + ServerData data2 = new ServerData(8081, Arrays.asList(), Mockito.mock(ApplicationContext.class), "url2", () -> "test-context"); + + serverApplication1 = new GrizzlyApplication(AllData.builder().serverData(data1).build()){ + @Override + public void run(CompletableFuture start,JaxRsServletConfigurer jaxRsConfigurer, CompletableFuture end) { + server1Count++; + start.complete(true); + + } + }; + serverApplication2 = new GrizzlyApplication(AllData.builder().serverData(data2).build()){ + @Override + public void run(CompletableFuture start,JaxRsServletConfigurer jaxRsConfigurer,CompletableFuture end) { + server2Count++; + start.complete(true); + + } + }; + + serverRunner = new ServerRunner( (array) -> {registered = array; } , + Arrays.asList(serverApplication1, serverApplication2), new CompletableFuture()); + + + } + + @Test + public void testRun() { + serverRunner.run(); + assertThat(server1Count,is(1)); + assertThat(server2Count,is(1)); + } +} diff --git a/micro-grizzly/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-grizzly/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..7b83464d9 --- /dev/null +++ b/micro-grizzly/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,64 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + public Response postString(String url, String payload) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(payload,MediaType.APPLICATION_JSON)); + } + +} diff --git a/micro-guava/README.md b/micro-guava/README.md new file mode 100644 index 000000000..5e80d35ea --- /dev/null +++ b/micro-guava/README.md @@ -0,0 +1,49 @@ +# Guava Plugin for Microserver + +[micro-guava example apps](https://github.com/aol/micro-server/tree/master/micro-guava/src/test/java/app) + +This plugin + +1. Configures Jackson for Guava serialisation / deserialisation, so Guava types can be used as input and output to jax-rs Resources +2. Configures a Guava EventBus as a Spring Bean (named microserverEventBus) + +## To use + +Simply add to the classpath + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-guava/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-guava) + +Maven + + + com.oath.microservices + micro-guava + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-guava:x.yz' + + +# Example Guava Resource + + @Rest + @Path("/status") + public class GuavaAppResource { + + @POST + @Produces("application/json") + @Path("/ping") + + public ImmutableList ping( ImmutableGuavaEntity entity) { + return entity.getList(); + } + @POST + @Produces("application/json") + @Path("/optional") + public Optional optional(Jdk8Entity entity) { + return entity.getName(); + } + + } diff --git a/micro-guava/build.gradle b/micro-guava/build.gradle index dd6c45883..8a445de06 100644 --- a/micro-guava/build.gradle +++ b/micro-guava/build.gradle @@ -1,62 +1,62 @@ description = 'micro-guava' dependencies { - compile 'com.aol.cyclops:cyclops-guava:'+cyclopsVersion - compile 'com.fasterxml.jackson.datatype:jackson-datatype-guava:'+guavaDatatypeVersion - - compile project(':micro-core') - compile project(':micro-jackson-configuration') - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') - - + + compile 'com.fasterxml.jackson.datatype:jackson-datatype-guava:' + guavaDatatypeVersion + compile project(':micro-core') + compile project(':micro-jackson-configuration') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') + testCompile "com.oath.cyclops:cyclops-futurestream:$cyclopsVersion" + + } modifyPom { - project { - name 'Microserver guava' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-guava' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - } - - } + project { + name 'Microserver guava' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-guava' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-guava/readme.md b/micro-guava/readme.md deleted file mode 100644 index b49cfd2e7..000000000 --- a/micro-guava/readme.md +++ /dev/null @@ -1,49 +0,0 @@ -# Guava Plugin for Microserver - -[micro-guava example apps](https://github.com/aol/micro-server/tree/master/micro-guava/src/test/java/app) - -This plugin - -1. Configures Jackson for Guava serialisation / deserialisation, so Guava types can be used as input and output to jax-rs Resources -2. Configures a Guava EventBus as a Spring Bean (named microserverEventBus) - -## To use - -Simply add to the classpath - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-guava/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-guava) - -Maven - - - com.aol.microservices - micro-guava - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-guava:x.yz' - - -# Example Guava Resource - - @Rest - @Path("/status") - public class GuavaAppResource { - - @POST - @Produces("application/json") - @Path("/ping") - - public ImmutableList ping( ImmutableGuavaEntity entity) { - return entity.getList(); - } - @POST - @Produces("application/json") - @Path("/optional") - public Optional optional(Jdk8Entity entity) { - return entity.getName(); - } - - } diff --git a/micro-guava/src/main/java/com/aol/micro/server/guava/GuavaPlugin.java b/micro-guava/src/main/java/com/aol/micro/server/guava/GuavaPlugin.java deleted file mode 100644 index 69e4a3998..000000000 --- a/micro-guava/src/main/java/com/aol/micro/server/guava/GuavaPlugin.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.aol.micro.server.guava; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.guava.spring.GuavaConfig; -import com.fasterxml.jackson.databind.Module; -import com.fasterxml.jackson.datatype.guava.GuavaModule; - -/** - * - * Collections of Spring configuration classes (Classes annotated with @Configuration) - * that configure various useful pieces of functionality - such as property file loading, - * datasources, scheduling etc - * - * @author johnmcclean - * - */ -public class GuavaPlugin implements Plugin{ - - @Override - public PSetX springClasses() { - return PSetX.of(GuavaConfig.class); - } - @Override - public PSetX jacksonModules(){ - return PSetX.of(new GuavaModule()); - } - - - -} diff --git a/micro-guava/src/main/java/com/oath/micro/server/guava/GuavaPlugin.java b/micro-guava/src/main/java/com/oath/micro/server/guava/GuavaPlugin.java new file mode 100644 index 000000000..ef79f1be9 --- /dev/null +++ b/micro-guava/src/main/java/com/oath/micro/server/guava/GuavaPlugin.java @@ -0,0 +1,34 @@ +package com.oath.micro.server.guava; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.guava.spring.GuavaConfig; +import com.fasterxml.jackson.databind.Module; +import com.fasterxml.jackson.datatype.guava.GuavaModule; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +/** + * + * Collections of Spring configuration classes (Classes annotated with @Configuration) + * that configure various useful pieces of functionality - such as property file loading, + * datasources, scheduling etc + * + * @author johnmcclean + * + */ +public class GuavaPlugin implements Plugin{ + + @Override + public Set springClasses() { + return SetX.of(GuavaConfig.class); + } + @Override + public Set jacksonModules(){ + return SetX.of(new GuavaModule()); + } + + + +} diff --git a/micro-guava/src/main/java/com/aol/micro/server/guava/spring/GuavaConfig.java b/micro-guava/src/main/java/com/oath/micro/server/guava/spring/GuavaConfig.java similarity index 86% rename from micro-guava/src/main/java/com/aol/micro/server/guava/spring/GuavaConfig.java rename to micro-guava/src/main/java/com/oath/micro/server/guava/spring/GuavaConfig.java index 2204b319b..e9bb8d3f6 100644 --- a/micro-guava/src/main/java/com/aol/micro/server/guava/spring/GuavaConfig.java +++ b/micro-guava/src/main/java/com/oath/micro/server/guava/spring/GuavaConfig.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.guava.spring; +package com.oath.micro.server.guava.spring; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/micro-guava/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-guava/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index c04494ef6..000000000 --- a/micro-guava/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.guava.GuavaPlugin \ No newline at end of file diff --git a/micro-guava/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-guava/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..384298c9b --- /dev/null +++ b/micro-guava/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.guava.GuavaPlugin \ No newline at end of file diff --git a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java b/micro-guava/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java deleted file mode 100644 index d4b8eff5c..000000000 --- a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java +++ /dev/null @@ -1,23 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.ArrayList; -import java.util.List; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -@Component -@Path("/alt-status") -public class AltAppResource implements AltAppRestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public List ping(ImmutableEntity entity) { - return entity.getList(); - } - -} diff --git a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java b/micro-guava/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java deleted file mode 100644 index 8cb2643e3..000000000 --- a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface AltAppRestResource extends RestResource { - -} diff --git a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java b/micro-guava/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java deleted file mode 100644 index bc73c2862..000000000 --- a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.Arrays; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.EmbeddedModule; - -@Microserver(basePackages = { "app.embedded.com.aol.micro.server" }) -public class EmbeddedAppLocalMain { - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( - EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")).start(); - - - - } - - -} diff --git a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java b/micro-guava/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java deleted file mode 100644 index bf1d3a7a7..000000000 --- a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java +++ /dev/null @@ -1,103 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.NotFoundException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.EmbeddedModule; -import com.aol.micro.server.testing.RestAgent; -import com.google.common.collect.ImmutableList; - -public class EmbeddedAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer(){ - server = new MicroserverApp(EmbeddedAppLocalMain.class, - EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")); - server.start(); - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); - - - assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value",ImmutableList.of("hello","world")),List.class), - hasItem("hello")); - - } - - - @Test - public void nonBlockingRestClientTest(){ - assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"),is("-*test!-*test!")); - } - - CompletableFuture toCompletableFuture( - final ListenableFuture listenableFuture - ) { - //create an instance of CompletableFuture - CompletableFuture completable = new CompletableFuture() { - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - // propagate cancel to the listenable future - boolean result = listenableFuture.cancel(mayInterruptIfRunning); - super.cancel(mayInterruptIfRunning); - return result; - } - }; - - // add callback - listenableFuture.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(T result) { - completable.complete(result); - } - - @Override - public void onFailure(Throwable t) { - completable.completeExceptionally(t); - } - }); - return completable; - } - - @Test(expected=NotFoundException.class) - public void confirmAltAppCantUseTestAppResources(){ - - assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); - - } - @Test(expected=NotFoundException.class) - public void confirmTestAppCantUseAltAppResources(){ - - assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",ImmutableList.of("hello","world")),List.class), - hasItem("hello")); - - } -} diff --git a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java b/micro-guava/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java deleted file mode 100644 index 19aebac39..000000000 --- a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java +++ /dev/null @@ -1,29 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -import com.google.common.collect.ImmutableList; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableEntity { - - private final String value; - private final ImmutableList list; - - public ImmutableEntity() { - this(null,null); - } - -} diff --git a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java b/micro-guava/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java deleted file mode 100644 index 0a192ffca..000000000 --- a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java +++ /dev/null @@ -1,46 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.micro.server.testing.RestAgent; -import com.google.common.collect.ImmutableList; -@Component -@Path("/test-status") -public class TestAppResource implements TestAppRestResource { - - private final SimpleReact simpleReact = new SimpleReact(); - private final RestAgent template = new RestAgent(); - private final ImmutableList urls = ImmutableList.of("http://localhost:8081/alternative-app/alt-status/ping", - "http://localhost:8080/test-app/test-status/ping", - "http://localhost:8082/simple-app/status/ping", - "http://localhost:8080/test-app/test-status/ping"); - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - @GET - @Produces("text/plain") - @Path("/rest-calls") - public String restCallResult(){ - - return LazyFutureStream.lazyFutureStreamFromIterable(urls) - .map(it ->template.get(it)) - .then(it -> "*"+it) - .peek(loadedAndModified -> System.out.println(loadedAndModified)) - .block().stream().reduce("", (acc,next) -> acc+"-"+next); - - } - -} diff --git a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java b/micro-guava/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java deleted file mode 100644 index 3133fd8cc..000000000 --- a/micro-guava/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface TestAppRestResource extends RestResource { - -} diff --git a/micro-guava/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java new file mode 100644 index 000000000..1835ababe --- /dev/null +++ b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java @@ -0,0 +1,22 @@ +package app.embedded.com.oath.micro.server; + +import java.util.List; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +@Component +@Path("/alt-status") +public class AltAppResource implements AltAppRestResource { + + @POST + @Produces("application/json") + @Path("/ping") + public List ping(ImmutableEntity entity) { + return entity.getList(); + } + +} diff --git a/micro-guava/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java new file mode 100644 index 000000000..7045a4f35 --- /dev/null +++ b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java @@ -0,0 +1,7 @@ +package app.embedded.com.oath.micro.server; + +import com.oath.micro.server.auto.discovery.RestResource; + +public interface AltAppRestResource extends RestResource { + +} diff --git a/micro-guava/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java new file mode 100644 index 000000000..dbb290069 --- /dev/null +++ b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java @@ -0,0 +1,24 @@ +package app.embedded.com.oath.micro.server; + +import java.util.Arrays; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.EmbeddedModule; + +@Microserver(basePackages = { "app.embedded.com.oath.micro.server" }) +public class EmbeddedAppLocalMain { + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( + EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), + EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")).start(); + + + + } + + +} diff --git a/micro-guava/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java new file mode 100644 index 000000000..d0327a39b --- /dev/null +++ b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java @@ -0,0 +1,103 @@ +package app.embedded.com.oath.micro.server; + +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.NotFoundException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.util.concurrent.ListenableFuture; +import org.springframework.util.concurrent.ListenableFutureCallback; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.EmbeddedModule; +import com.oath.micro.server.testing.RestAgent; +import com.google.common.collect.ImmutableList; + +public class EmbeddedAppTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer(){ + server = new MicroserverApp(EmbeddedAppLocalMain.class, + EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), + EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")); + server.start(); + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); + + + assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value",ImmutableList.of("hello","world")),List.class), + hasItem("hello")); + + } + + + @Test + public void nonBlockingRestClientTest(){ + assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"),is("-*test!-*test!")); + } + + CompletableFuture toCompletableFuture( + final ListenableFuture listenableFuture + ) { + //create an instance of CompletableFuture + CompletableFuture completable = new CompletableFuture() { + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + // propagate cancel to the listenable future + boolean result = listenableFuture.cancel(mayInterruptIfRunning); + super.cancel(mayInterruptIfRunning); + return result; + } + }; + + // add callback + listenableFuture.addCallback(new ListenableFutureCallback() { + @Override + public void onSuccess(T result) { + completable.complete(result); + } + + @Override + public void onFailure(Throwable t) { + completable.completeExceptionally(t); + } + }); + return completable; + } + + @Test(expected=NotFoundException.class) + public void confirmAltAppCantUseTestAppResources(){ + + assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); + + } + @Test(expected=NotFoundException.class) + public void confirmTestAppCantUseAltAppResources(){ + + assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",ImmutableList.of("hello","world")),List.class), + hasItem("hello")); + + } +} diff --git a/micro-guava/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java new file mode 100644 index 000000000..3d90d3096 --- /dev/null +++ b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java @@ -0,0 +1,29 @@ +package app.embedded.com.oath.micro.server; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +import com.google.common.collect.ImmutableList; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "immutable") +@Getter +@AllArgsConstructor +@Builder +public class ImmutableEntity { + + private final String value; + private final ImmutableList list; + + public ImmutableEntity() { + this(null,null); + } + +} diff --git a/micro-guava/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java new file mode 100644 index 000000000..e416ccc4d --- /dev/null +++ b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java @@ -0,0 +1,48 @@ +package app.embedded.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import cyclops.futurestream.SimpleReact; +import cyclops.futurestream.FutureStream; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.testing.RestAgent; +import com.google.common.collect.ImmutableList; + +import java.util.Arrays; +import java.util.List; + +@Component +@Path("/test-status") +public class TestAppResource implements TestAppRestResource { + + private final SimpleReact simpleReact = new SimpleReact(); + private final RestAgent template = new RestAgent(); + private final List urls = Arrays.asList( + "http://localhost:8080/test-app/test-status/ping","http://localhost:8080/test-app/test-status/ping"); + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "test!"; + } + + @GET + @Produces("text/plain") + @Path("/rest-calls") + public String restCallResult(){ + + return FutureStream.builder().fromIterable(urls) + .map(it ->template.get(it)) + .then(it -> "*"+it) + .peek(loadedAndModified -> System.out.println(loadedAndModified)) + .block().stream().reduce("", (acc,next) -> acc+"-"+next); + + } + +} diff --git a/micro-guava/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java new file mode 100644 index 000000000..7d4df5753 --- /dev/null +++ b/micro-guava/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java @@ -0,0 +1,7 @@ +package app.embedded.com.oath.micro.server; + +import com.oath.micro.server.auto.discovery.RestResource; + +public interface TestAppRestResource extends RestResource { + +} diff --git a/micro-guava/src/test/java/app/guava/com/aol/micro/server/GuavaAppResource.java b/micro-guava/src/test/java/app/guava/com/aol/micro/server/GuavaAppResource.java deleted file mode 100644 index a6cdf2661..000000000 --- a/micro-guava/src/test/java/app/guava/com/aol/micro/server/GuavaAppResource.java +++ /dev/null @@ -1,29 +0,0 @@ -package app.guava.com.aol.micro.server; - -import java.util.Optional; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.auto.discovery.Rest; -import com.google.common.collect.ImmutableList; -@Rest -@Path("/status") -public class GuavaAppResource { - - @POST - @Produces("application/json") - @Path("/ping") - - public ImmutableList ping( ImmutableGuavaEntity entity) { - return entity.getList(); - } - @POST - @Produces("application/json") - @Path("/optional") - public Optional optional(Jdk8Entity entity) { - return entity.getName(); - } - -} diff --git a/micro-guava/src/test/java/app/guava/com/aol/micro/server/GuavaAppTest.java b/micro-guava/src/test/java/app/guava/com/aol/micro/server/GuavaAppTest.java deleted file mode 100644 index b79cf24df..000000000 --- a/micro-guava/src/test/java/app/guava/com/aol/micro/server/GuavaAppTest.java +++ /dev/null @@ -1,92 +0,0 @@ -package app.guava.com.aol.micro.server; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.List; -import java.util.Optional; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.SimpleReactStream; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.jackson.JacksonUtil; -import com.aol.micro.server.testing.RestAgent; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableSet; - -@Microserver(basePackages = { "app.guava.com.aol.micro.server" }) -public class GuavaAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - ImmutableGuavaEntity entity; - Jdk8Entity present; - Jdk8Entity absent; - - SimpleReact simpleReact = new SimpleReact(); - SimpleReactStream stream; - - @Before - public void startServer() { - stream = simpleReact.ofAsync( - () -> server = new MicroserverApp(GuavaAppTest.class, - () -> "guava-app")).then(server -> server.start()); - - entity = ImmutableGuavaEntity.builder().value("value") - .list(ImmutableList.of("hello", "world")) - .mapOfSets(ImmutableMap.of("key1", ImmutableSet.of(1, 2, 3))) - .multiMap(ImmutableMultimap.of("1", 2, "1", 2, "2", 4)).build(); - - JacksonUtil.convertFromJson(JacksonUtil.serializeToJson(entity), - ImmutableGuavaEntity.class); - - present = Jdk8Entity.builder().name(Optional.of("test")).build(); - - JacksonUtil.convertFromJson(JacksonUtil.serializeToJson(present), - Optional.class); - absent = Jdk8Entity.builder().name(Optional.empty()).build(); - } - - @After - public void stopServer() { - server.stop(); - } - - @Test - public void confirmExpectedUrlsPresentTest() throws InterruptedException, - ExecutionException { - - stream.block(); - - assertThat((List) rest.post( - "http://localhost:8080/guava-app/status/ping", entity, - List.class), hasItem("hello")); - - } - - @Test - public void confirmOptionalConversionWorking() throws InterruptedException, - ExecutionException { - - stream.block(); - - assertThat(rest.post("http://localhost:8080/guava-app/status/optional", - present, String.class), is("\"test\"")); - - assertThat(rest.post("http://localhost:8080/guava-app/status/optional", - absent, String.class), is("null")); - - } - -} diff --git a/micro-guava/src/test/java/app/guava/com/aol/micro/server/ImmutableGuavaEntity.java b/micro-guava/src/test/java/app/guava/com/aol/micro/server/ImmutableGuavaEntity.java deleted file mode 100644 index 8ee2bb325..000000000 --- a/micro-guava/src/test/java/app/guava/com/aol/micro/server/ImmutableGuavaEntity.java +++ /dev/null @@ -1,34 +0,0 @@ -package app.guava.com.aol.micro.server; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableSet; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableGuavaEntity { - - private final String value; - private final ImmutableList list; - private final ImmutableMap mapOfSets; - private final ImmutableMultimap multiMap; - - public ImmutableGuavaEntity() { - this(null,null,null,null); - } - -} diff --git a/micro-guava/src/test/java/app/guava/com/aol/micro/server/Jdk8Entity.java b/micro-guava/src/test/java/app/guava/com/aol/micro/server/Jdk8Entity.java deleted file mode 100644 index 039cb2645..000000000 --- a/micro-guava/src/test/java/app/guava/com/aol/micro/server/Jdk8Entity.java +++ /dev/null @@ -1,27 +0,0 @@ -package app.guava.com.aol.micro.server; - -import java.util.Optional; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "optional") -@Getter -@AllArgsConstructor -@Builder -public class Jdk8Entity { - - private final Optional name; - - public Jdk8Entity(){ - name = Optional.empty(); - } -} diff --git a/micro-guava/src/test/java/app/guava/com/oath/micro/server/GuavaAppResource.java b/micro-guava/src/test/java/app/guava/com/oath/micro/server/GuavaAppResource.java new file mode 100644 index 000000000..8a196aafe --- /dev/null +++ b/micro-guava/src/test/java/app/guava/com/oath/micro/server/GuavaAppResource.java @@ -0,0 +1,29 @@ +package app.guava.com.oath.micro.server; + +import java.util.Optional; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.auto.discovery.Rest; +import com.google.common.collect.ImmutableList; +@Rest +@Path("/status") +public class GuavaAppResource { + + @POST + @Produces("application/json") + @Path("/ping") + + public ImmutableList ping( ImmutableGuavaEntity entity) { + return entity.getList(); + } + @POST + @Produces("application/json") + @Path("/optional") + public Optional optional(Jdk8Entity entity) { + return entity.getName(); + } + +} diff --git a/micro-guava/src/test/java/app/guava/com/oath/micro/server/GuavaAppTest.java b/micro-guava/src/test/java/app/guava/com/oath/micro/server/GuavaAppTest.java new file mode 100644 index 000000000..a17d0a146 --- /dev/null +++ b/micro-guava/src/test/java/app/guava/com/oath/micro/server/GuavaAppTest.java @@ -0,0 +1,94 @@ +package app.guava.com.oath.micro.server; + +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +import com.oath.cyclops.types.futurestream.SimpleReactStream; +import cyclops.futurestream.SimpleReact; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.testing.RestAgent; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; + +@Ignore +@Microserver(basePackages = { "app.guava.com.oath.micro.server" }) +public class GuavaAppTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + ImmutableGuavaEntity entity; + Jdk8Entity present; + Jdk8Entity absent; + + SimpleReact simpleReact = new SimpleReact(); + SimpleReactStream stream; + + @Before + public void startServer() { + stream = simpleReact.ofAsync( + () -> server = new MicroserverApp(GuavaAppTest.class, + () -> "guava-app")).then(server -> server.start()); + + entity = ImmutableGuavaEntity.builder().value("value") + .list(ImmutableList.of("hello", "world")) + .mapOfSets(ImmutableMap.of("key1", ImmutableSet.of(1, 2, 3))) + .multiMap(ImmutableMultimap.of("1", 2, "1", 2, "2", 4)).build(); + + JacksonUtil.convertFromJson(JacksonUtil.serializeToJson(entity), + ImmutableGuavaEntity.class); + + present = Jdk8Entity.builder().name(Optional.of("test")).build(); + + JacksonUtil.convertFromJson(JacksonUtil.serializeToJson(present), + Optional.class); + absent = Jdk8Entity.builder().name(Optional.empty()).build(); + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void confirmExpectedUrlsPresentTest() throws InterruptedException, + ExecutionException { + + stream.block(); + + assertThat((List) rest.post( + "http://localhost:8080/guava-app/status/ping", entity, + List.class), hasItem("hello")); + + } + + @Test + public void confirmOptionalConversionWorking() throws InterruptedException, + ExecutionException { + + stream.block(); + + assertThat(rest.post("http://localhost:8080/guava-app/status/optional", + present, String.class), is("\"test\"")); + + assertThat(rest.post("http://localhost:8080/guava-app/status/optional", + absent, String.class), is("null")); + + } + +} diff --git a/micro-guava/src/test/java/app/guava/com/oath/micro/server/ImmutableGuavaEntity.java b/micro-guava/src/test/java/app/guava/com/oath/micro/server/ImmutableGuavaEntity.java new file mode 100644 index 000000000..e4e706907 --- /dev/null +++ b/micro-guava/src/test/java/app/guava/com/oath/micro/server/ImmutableGuavaEntity.java @@ -0,0 +1,34 @@ +package app.guava.com.oath.micro.server; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "immutable") +@Getter +@AllArgsConstructor +@Builder +public class ImmutableGuavaEntity { + + private final String value; + private final ImmutableList list; + private final ImmutableMap mapOfSets; + private final ImmutableMultimap multiMap; + + public ImmutableGuavaEntity() { + this(null,null,null,null); + } + +} diff --git a/micro-guava/src/test/java/app/guava/com/oath/micro/server/Jdk8Entity.java b/micro-guava/src/test/java/app/guava/com/oath/micro/server/Jdk8Entity.java new file mode 100644 index 000000000..df2b8662e --- /dev/null +++ b/micro-guava/src/test/java/app/guava/com/oath/micro/server/Jdk8Entity.java @@ -0,0 +1,27 @@ +package app.guava.com.oath.micro.server; + +import java.util.Optional; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "optional") +@Getter +@AllArgsConstructor +@Builder +public class Jdk8Entity { + + private final Optional name; + + public Jdk8Entity(){ + name = Optional.empty(); + } +} diff --git a/micro-guava/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java b/micro-guava/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java deleted file mode 100644 index 70c61fd26..000000000 --- a/micro-guava/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java +++ /dev/null @@ -1,25 +0,0 @@ -package app.validation.com.aol.micro.server; - -import javax.validation.constraints.NotNull; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import app.guava.com.aol.micro.server.ImmutableGuavaEntity; - -import com.aol.micro.server.auto.discovery.RestResource; -@Component -@Path("/status") -public class ValidationAppResource implements RestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public ImmutableGuavaEntity ping( @NotNull ImmutableGuavaEntity entity) { - return entity; - } - - -} diff --git a/micro-guava/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java b/micro-guava/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java deleted file mode 100644 index 0a19b2b6f..000000000 --- a/micro-guava/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package app.validation.com.aol.micro.server; - -import java.util.List; -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.InternalServerErrorException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import app.guava.com.aol.micro.server.ImmutableGuavaEntity; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.SimpleReactStream; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableSet; - -@Microserver(basePackages = { "app.guava.com.aol.micro.server" }) -public class ValidationAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - ImmutableGuavaEntity entity; - - - SimpleReact simpleReact = new SimpleReact(); - SimpleReactStream stream; - - @Before - public void startServer() { - stream = simpleReact.ofAsync( - () -> server = new MicroserverApp(ValidationAppTest.class, - () -> "guava-app")).then(server -> server.start()); - - entity = ImmutableGuavaEntity.builder().value("value") - .list(ImmutableList.of("hello", "world")) - .mapOfSets(ImmutableMap.of("key1", ImmutableSet.of(1, 2, 3))) - .multiMap(ImmutableMultimap.of("1", 2, "1", 2, "2", 4)).build(); - - - } - - @After - public void stopServer() { - server.stop(); - } - - - @Test(expected=InternalServerErrorException.class) - public void confirmError() throws InterruptedException, - ExecutionException { - - stream.block(); - rest.post( - "http://localhost:8080/guava-app/status/ping", null, - List.class); - - - } - @Test - public void confirmNoError() throws InterruptedException, - ExecutionException { - - stream.block(); - rest.post( - "http://localhost:8080/guava-app/status/ping", entity, - List.class); - - - } - - - -} diff --git a/micro-guava/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java b/micro-guava/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java new file mode 100644 index 000000000..a4a665c82 --- /dev/null +++ b/micro-guava/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java @@ -0,0 +1,25 @@ +package app.validation.com.oath.micro.server; + +import javax.validation.constraints.NotNull; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import app.guava.com.oath.micro.server.ImmutableGuavaEntity; + +import com.oath.micro.server.auto.discovery.RestResource; +@Component +@Path("/status") +public class ValidationAppResource implements RestResource { + + @POST + @Produces("application/json") + @Path("/ping") + public ImmutableGuavaEntity ping( @NotNull ImmutableGuavaEntity entity) { + return entity; + } + + +} diff --git a/micro-guava/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java b/micro-guava/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java new file mode 100644 index 000000000..c89223477 --- /dev/null +++ b/micro-guava/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java @@ -0,0 +1,82 @@ +package app.validation.com.oath.micro.server; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.InternalServerErrorException; + +import com.oath.cyclops.types.futurestream.SimpleReactStream; +import cyclops.futurestream.SimpleReact; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import app.guava.com.oath.micro.server.ImmutableGuavaEntity; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; + +@Microserver(basePackages = { "app.guava.com.oath.micro.server" }) +public class ValidationAppTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + ImmutableGuavaEntity entity; + + + SimpleReact simpleReact = new SimpleReact(); + SimpleReactStream stream; + + @Before + public void startServer() { + stream = simpleReact.ofAsync( + () -> server = new MicroserverApp(ValidationAppTest.class, + () -> "guava-app")).then(server -> server.start()); + + entity = ImmutableGuavaEntity.builder().value("value") + .list(ImmutableList.of("hello", "world")) + .mapOfSets(ImmutableMap.of("key1", ImmutableSet.of(1, 2, 3))) + .multiMap(ImmutableMultimap.of("1", 2, "1", 2, "2", 4)).build(); + + + } + + @After + public void stopServer() { + server.stop(); + } + + + @Test(expected=InternalServerErrorException.class) + public void confirmError() throws InterruptedException, + ExecutionException { + + stream.block(); + rest.post( + "http://localhost:8080/guava-app/status/ping", null, + List.class); + + + } + @Test + public void confirmNoError() throws InterruptedException, + ExecutionException { + + stream.block(); + rest.post( + "http://localhost:8080/guava-app/status/ping", entity, + List.class); + + + } + + + +} diff --git a/micro-guava/src/test/java/com/aol/micro/server/rest/JacksonUtilTest.java b/micro-guava/src/test/java/com/aol/micro/server/rest/JacksonUtilTest.java deleted file mode 100644 index ecf8ee13e..000000000 --- a/micro-guava/src/test/java/com/aol/micro/server/rest/JacksonUtilTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.aol.micro.server.rest; - - -import static junit.framework.Assert.assertTrue; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.Getter; -import lombok.Setter; - -import org.junit.Test; - -import com.aol.micro.server.rest.jackson.JacksonUtil; -import com.google.common.collect.ImmutableList; - - -public class JacksonUtilTest { - - @Test - public void testGenerics(){ - String s = JacksonUtil.serializeToJson(ImmutableList.of(new MyEntity())); - ImmutableList list = JacksonUtil.convertFromJson(s, JacksonUtil.getMapper().getTypeFactory().constructParametricType(ImmutableList.class,MyEntity.class)); - assertThat(list.get(0),is(new MyEntity())); - - } - @Test - public void generateSampleRequest() { - - DummyQueryRequest request = new DummyQueryRequest(); - request.getData().add("blah"); - - assertTrue(JacksonUtil.serializeToJson(request).contains("strData")); - - } - - - @Test - public void serialiseAndDeserialise(){ - DummyQueryRequest request = new DummyQueryRequest(); - request.getData().add("blah"); - String requestStr = (String) JacksonUtil.serializeToJsonLogFailure(request); - DummyQueryRequest requestDeserialised = JacksonUtil.convertFromJson(requestStr, DummyQueryRequest.class); - assertTrue(request.getData().contains("blah")); - } - - -} - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlRootElement(name = "queryRequest") -@XmlType(name = "") -class DummyQueryRequest { - - @XmlElement(name = "strData") - @Getter - @Setter - private List data = new ArrayList(); - - -} - diff --git a/micro-guava/src/test/java/com/aol/micro/server/rest/MyEntity.java b/micro-guava/src/test/java/com/aol/micro/server/rest/MyEntity.java deleted file mode 100644 index b6a7a0ec7..000000000 --- a/micro-guava/src/test/java/com/aol/micro/server/rest/MyEntity.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.aol.micro.server.rest; - -import lombok.EqualsAndHashCode; -import lombok.Getter; - -@EqualsAndHashCode -@Getter -public class MyEntity { - - private final String name ="myEntity"; - -} diff --git a/micro-guava/src/test/java/com/aol/micro/server/rest/RestContextListenerTest.java b/micro-guava/src/test/java/com/aol/micro/server/rest/RestContextListenerTest.java deleted file mode 100644 index b853d9a62..000000000 --- a/micro-guava/src/test/java/com/aol/micro/server/rest/RestContextListenerTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.aol.micro.server.rest; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.rest.jersey.JerseyRestApplication; -import com.aol.micro.server.rest.jersey.JerseySpringIntegrationContextListener; -import com.aol.micro.server.servers.model.ServerData; -import com.google.common.collect.Lists; - -public class RestContextListenerTest { - - private JerseySpringIntegrationContextListener restContextListener; - private ServletStatusResource statsResource; - - @Before - public void setUp() { - statsResource = new ServletStatusResource(); - ServerData serverData = new ServerData(8080, Lists.newArrayList(statsResource), null, "baseUrl", () -> "test"); - restContextListener = new JerseySpringIntegrationContextListener(serverData); - } - - @Test - public void testContextInitialized() { - restContextListener.contextInitialized(null); - assertThat(JerseyRestApplication.getResourcesMap().get("test").get(0), is(statsResource)); - } - - @Test - public void testContextDestroyed() { - restContextListener.contextDestroyed(null); - } - -} diff --git a/micro-guava/src/test/java/com/aol/micro/server/rest/ServletStatusResource.java b/micro-guava/src/test/java/com/aol/micro/server/rest/ServletStatusResource.java deleted file mode 100644 index c5e3cf667..000000000 --- a/micro-guava/src/test/java/com/aol/micro/server/rest/ServletStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aol.micro.server.rest; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/servlet") -public class ServletStatusResource implements RestResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-guava/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-guava/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-guava/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-guava/src/test/java/com/oath/micro/server/rest/JacksonUtilTest.java b/micro-guava/src/test/java/com/oath/micro/server/rest/JacksonUtilTest.java new file mode 100644 index 000000000..dde6aebb4 --- /dev/null +++ b/micro-guava/src/test/java/com/oath/micro/server/rest/JacksonUtilTest.java @@ -0,0 +1,70 @@ +package com.oath.micro.server.rest; + + +import static junit.framework.Assert.assertTrue; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.Getter; +import lombok.Setter; + +import org.junit.Test; + +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.google.common.collect.ImmutableList; + + +public class JacksonUtilTest { + + @Test + public void testGenerics(){ + String s = JacksonUtil.serializeToJson(ImmutableList.of(new MyEntity())); + ImmutableList list = JacksonUtil.convertFromJson(s, JacksonUtil.getMapper().getTypeFactory().constructParametricType(ImmutableList.class,MyEntity.class)); + assertThat(list.get(0),is(new MyEntity())); + + } + @Test + public void generateSampleRequest() { + + DummyQueryRequest request = new DummyQueryRequest(); + request.getData().add("blah"); + + assertTrue(JacksonUtil.serializeToJson(request).contains("strData")); + + } + + + @Test + public void serialiseAndDeserialise(){ + DummyQueryRequest request = new DummyQueryRequest(); + request.getData().add("blah"); + String requestStr = (String) JacksonUtil.serializeToJsonLogFailure(request); + DummyQueryRequest requestDeserialised = JacksonUtil.convertFromJson(requestStr, DummyQueryRequest.class); + assertTrue(request.getData().contains("blah")); + } + + +} + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "queryRequest") +@XmlType(name = "") +class DummyQueryRequest { + + @XmlElement(name = "strData") + @Getter + @Setter + private List data = new ArrayList(); + + +} + diff --git a/micro-guava/src/test/java/com/oath/micro/server/rest/MyEntity.java b/micro-guava/src/test/java/com/oath/micro/server/rest/MyEntity.java new file mode 100644 index 000000000..c691212ff --- /dev/null +++ b/micro-guava/src/test/java/com/oath/micro/server/rest/MyEntity.java @@ -0,0 +1,12 @@ +package com.oath.micro.server.rest; + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@EqualsAndHashCode +@Getter +public class MyEntity { + + private final String name ="myEntity"; + +} diff --git a/micro-guava/src/test/java/com/oath/micro/server/rest/RestContextListenerTest.java b/micro-guava/src/test/java/com/oath/micro/server/rest/RestContextListenerTest.java new file mode 100644 index 000000000..715793b5f --- /dev/null +++ b/micro-guava/src/test/java/com/oath/micro/server/rest/RestContextListenerTest.java @@ -0,0 +1,37 @@ +package com.oath.micro.server.rest; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.rest.jersey.JerseyRestApplication; +import com.oath.micro.server.rest.jersey.JerseySpringIntegrationContextListener; +import com.oath.micro.server.servers.model.ServerData; +import com.google.common.collect.Lists; + +public class RestContextListenerTest { + + private JerseySpringIntegrationContextListener restContextListener; + private ServletStatusResource statsResource; + + @Before + public void setUp() { + statsResource = new ServletStatusResource(); + ServerData serverData = new ServerData(8080, Lists.newArrayList(statsResource), null, "baseUrl", () -> "test"); + restContextListener = new JerseySpringIntegrationContextListener(serverData); + } + + @Test + public void testContextInitialized() { + restContextListener.contextInitialized(null); + assertThat(JerseyRestApplication.getResourcesMap().get("test").get(0), is(statsResource)); + } + + @Test + public void testContextDestroyed() { + restContextListener.contextDestroyed(null); + } + +} diff --git a/micro-guava/src/test/java/com/oath/micro/server/rest/ServletStatusResource.java b/micro-guava/src/test/java/com/oath/micro/server/rest/ServletStatusResource.java new file mode 100644 index 000000000..e7fa33979 --- /dev/null +++ b/micro-guava/src/test/java/com/oath/micro/server/rest/ServletStatusResource.java @@ -0,0 +1,22 @@ +package com.oath.micro.server.rest; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/servlet") +public class ServletStatusResource implements RestResource { + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-guava/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-guava/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-guava/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-hibernate/README.md b/micro-hibernate/README.md new file mode 100644 index 000000000..d0a50a4f5 --- /dev/null +++ b/micro-hibernate/README.md @@ -0,0 +1,206 @@ + # Hibernate plugin + + [micro-hibernate example apps](https://github.com/aol/micro-server/tree/master/micro-hibernate/src/test/java/app) + +Adds Hibernate support. + +## To use + + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-hibernate/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-hibernate) + +Simply add to the classpath + +Maven + + + com.oath.microservices + micro-hibernate + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-data:x.yz' + +# Configuring a data source + +A datasource can be configured by setting the following properties in application.properties, instance.properties or via the Microserver annotation + + db.connection.driver: (e.g. (org.hsqldb.jdbcDriver) + db.connection.url: (e.g. jdbc:hsqldb:mem:aname) + db.connection.username: (e.g. admin) + db.connection.password: (e.g. password) + db.connection.dialect: (e.g. org.hibernate.dialect.HSQLDialect) + db.connection.hibernate.showsql: (e.g. true | false) + db.connection.ddl.auto: (e.g. create-drop) + +The Microserver annotation can also be used to set some default properties, or they can be set in an application.properties or instance.properties file ([see wiki for more details](https://github.com/aol/micro-server/wiki/Defining-Properties)). + + +The important properties for us to set are the datasource properties + + @Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", + "db.connection.url","jdbc:hsqldb:mem:aname", + "db.connection.username", "sa", + "db.connection.dialect","org.hibernate.dialect.HSQLDialect", + "db.connection.ddl.auto","create-drop"}) + + public class MyMainClass { + + + } + + +# Hibernate + +[Hibernate example app](https://github.com/aol/micro-server/tree/master/micro-data/src/test/java/app/hibernate/com/aol/micro/server) + +Use the Microserver annotation to set the Hibernate entityScan + + @Microserver(entityScan="app.hibernate.com.aol.micro.server") + public class MyMainClass { + + + } + + + ## SessionFactory + + micro-data will create a Spring managed SessionFactory for you that you can inject into your Spring beans to take full advantage of Hibernate functionality. + + E.g. + + @Rest + @Path("/persistence") + public class PersistentResource{ + + + private final SessionFactory sessionFactory; + + + @Autowired + public PersistentResource(SessionFactory sessionFactory) { + + this.sessionFactory = sessionFactory; + } + + @GET + @Produces("text/plain") + @Path("/create") + public String createEntity() { + + final Session session = sessionFactory.openSession(); + session.save(HibernateEntity.builder() + .name("test") + .value("value").build()); + session.flush(); + return "ok"; + } + + @GET + @Produces("application/json") + @Path("/get") + public List get(){ + final Session session = sessionFactory.openSession(); + + Criteria criteria = session.createCriteria(HibernateEntity.class) + .add(Example.create(HibernateEntity.builder() + .name("test") + .build())); + + return criteria.list(); + + } + + } + + # Spring Data + + [Spring Data example app](https://github.com/aol/micro-server/tree/master/micro-data/src/test/java/app/spring/data/jpa/com/aol/micro/server) + + On your main class add the following annotation to switch on Spring Data + + @EnableJpaRepositories + + Example : note in this example we are also going to use Hibernate to construct an in-memory database + + + @Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", + "db.connection.url","jdbc:hsqldb:mem:aname", + "db.connection.username", "sa", + "db.connection.dialect","org.hibernate.dialect.HSQLDialect", + "db.connection.ddl.auto","create-drop"}, entityScan="app.spring.data.jpa.com.aol.micro.server") + @EnableJpaRepositories + public class SpringDataTest { + + private final AsyncRestClient> listClient = new AsyncRestClient(1000,1000).withGenericResponse(List.class, SpringDataEntity.class); + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer(){ + + Config.reset(); + server = new MicroserverApp(()->"hibernate-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/hibernate-app/persistence/create"),is("ok")); + assertThat(listClient.get("http://localhost:8080/hibernate-app/persistence/get").get().get(0),is(SpringDataEntity.class)); + + + } + + } + + # Plain ol' JDBC + +[JDBC Template Exmaple App](https://github.com/aol/micro-server/tree/master/micro-data/src/test/java/app/jdbc/com/aol/micro/server) + +The micro-data plugin also facilitate JDBC use via the Spring JDBCTemplate. A Spring called SQL will be created that contains a JDBCTemplate, simply inject SQL into your classes. + + e.g. + + @Rest + @Path("/persistence") + public class PersistentResource { + + private final SQL dao; + + @Autowired + public PersistentResource(SQL dao) { + + this.dao = dao; + } + + @GET + @Produces("text/plain") + @Path("/create") + public String createEntity() { + dao.getJdbc().update("insert into t_jdbc VALUES (1,'hello','world',1)"); + + return "ok"; + } + + @GET + @Produces("application/json") + @Path("/get") + public JdbcEntity get() { + return dao.getJdbc(). queryForObject("select * from t_jdbc", new BeanPropertyRowMapper(JdbcEntity.class)); + } + + } diff --git a/micro-hibernate/build.gradle b/micro-hibernate/build.gradle index ef945da2e..22899118f 100644 --- a/micro-hibernate/build.gradle +++ b/micro-hibernate/build.gradle @@ -1,79 +1,83 @@ description = 'micro-hibernate' + dependencies { - - compile ('org.hibernate:hibernate-validator:'+hibernateValidator) { - exclude group: 'org.jboss.logging' - } - compile 'javax.transaction:jta:'+jtaVersion - compile group: 'org.hibernate', name: 'hibernate-core', version:hibernateVersion - compile group: 'org.hibernate', name: 'hibernate-entitymanager', version:hibernateVersion - compile group: 'org.springframework', name: 'spring-orm', version:"${springVersion}" - - compile project(':micro-jdbc') - testCompile project(':micro-jackson-configuration') - testCompile project(':micro-client') - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') - testCompile project(':micro-hikaricp') - testCompile group: 'org.hsqldb', name:'hsqldb', version:'2.0.0' + + compile('org.hibernate:hibernate-validator:' + hibernateValidator) { + exclude group: 'org.jboss.logging' + } + compile 'javax.transaction:jta:' + jtaVersion + compile(group: 'org.hibernate', name: 'hibernate-core', version: hibernateVersion) + compile group: 'org.hibernate', name: 'hibernate-entitymanager', version: hibernateVersion + compile group: 'org.hibernate', name: 'hibernate-entitymanager', version: hibernateVersion + compile group: 'org.hibernate', name: 'hibernate-validator', version: '6.0.13.Final' + compile group: 'org.glassfish', name: 'javax.el', version: '3.0.0' + compile group: 'org.springframework', name: 'spring-orm', version: "${springVersion}" + + compile project(':micro-jdbc') + testCompile project(':micro-jackson-configuration') + testCompile project(':micro-client') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') + testCompile project(':micro-hikaricp') + testCompile group: 'org.hsqldb', name: 'hsqldb', version: '2.0.0' } modifyPom { - project { - name 'Microserver hibernate' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver hibernate' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-hibernate' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } - groupId 'com.aol.microservices' - artifactId 'micro-hibernate' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - developer { - id 'earlzero' - name 'Nikita Sapozhnikov' - email 'nikita.sapozhnikov@teamaol.com' - } - } - - } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-hibernate/readme.md b/micro-hibernate/readme.md deleted file mode 100644 index 4e7fb6749..000000000 --- a/micro-hibernate/readme.md +++ /dev/null @@ -1,254 +0,0 @@ - # Hibernate & Spring Data plugin - - [micro-hibernate example apps](https://github.com/aol/micro-server/tree/master/micro-hibernate/src/test/java/app) - -Adds Spring Data, and Hibernate support. - -## To use - - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-hibernate/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-hibernate) - -Simply add to the classpath - -Maven - - - com.aol.microservices - micro-hibernate - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-data:x.yz' - -# Configuring a data source - -A datasource can be configured by setting the following properties in application.properties, instance.properties or via the Microserver annotation - - db.connection.driver: (e.g. (org.hsqldb.jdbcDriver) - db.connection.url: (e.g. jdbc:hsqldb:mem:aname) - db.connection.username: (e.g. admin) - db.connection.password: (e.g. password) - db.connection.dialect: (e.g. org.hibernate.dialect.HSQLDialect) - db.connection.hibernate.showsql: (e.g. true | false) - db.connection.ddl.auto: (e.g. create-drop) - -The Microserver annotation can also be used to set some default properties, or they can be set in an application.properties or instance.properties file ([see wiki for more details](https://github.com/aol/micro-server/wiki/Defining-Properties)). - - -The important properties for us to set are the datasource properties - - @Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", - "db.connection.url","jdbc:hsqldb:mem:aname", - "db.connection.username", "sa", - "db.connection.dialect","org.hibernate.dialect.HSQLDialect", - "db.connection.ddl.auto","create-drop"}) - - public class MyMainClass { - - - } - - -# Hibernate - -[Hibernate example app](https://github.com/aol/micro-server/tree/master/micro-data/src/test/java/app/hibernate/com/aol/micro/server) - -Use the Microserver annotation to set the Hibernate entityScan - - @Microserver(entityScan="app.hibernate.com.aol.micro.server") - public class MyMainClass { - - - } - - - ## SessionFactory - - micro-data will create a Spring managed SessionFactory for you that you can inject into your Spring beans to take full advantage of Hibernate functionality. - - E.g. - - @Rest - @Path("/persistence") - public class PersistentResource{ - - - private final SessionFactory sessionFactory; - - - @Autowired - public PersistentResource(SessionFactory sessionFactory) { - - this.sessionFactory = sessionFactory; - } - - @GET - @Produces("text/plain") - @Path("/create") - public String createEntity() { - - final Session session = sessionFactory.openSession(); - session.save(HibernateEntity.builder() - .name("test") - .value("value").build()); - session.flush(); - return "ok"; - } - - @GET - @Produces("application/json") - @Path("/get") - public List get(){ - final Session session = sessionFactory.openSession(); - - Criteria criteria = session.createCriteria(HibernateEntity.class) - .add(Example.create(HibernateEntity.builder() - .name("test") - .build())); - - return criteria.list(); - - } - - } - - # Spring Data - - [Spring Data example app](https://github.com/aol/micro-server/tree/master/micro-data/src/test/java/app/spring/data/jpa/com/aol/micro/server) - - On your main class add the following annotation to switch on Spring Data - - @EnableJpaRepositories - - Example : note in this example we are also going to use Hibernate to construct an in-memory database - - - @Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", - "db.connection.url","jdbc:hsqldb:mem:aname", - "db.connection.username", "sa", - "db.connection.dialect","org.hibernate.dialect.HSQLDialect", - "db.connection.ddl.auto","create-drop"}, entityScan="app.spring.data.jpa.com.aol.micro.server") - @EnableJpaRepositories - public class SpringDataTest { - - private final AsyncRestClient> listClient = new AsyncRestClient(1000,1000).withGenericResponse(List.class, SpringDataEntity.class); - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer(){ - - Config.reset(); - server = new MicroserverApp(()->"hibernate-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/hibernate-app/persistence/create"),is("ok")); - assertThat(listClient.get("http://localhost:8080/hibernate-app/persistence/get").get().get(0),is(SpringDataEntity.class)); - - - } - - } - -## Spring Data Repositories - -We can define a Spring Data Repository e.g. A Crud Repository for a simple Entity - - public interface SpringDataRepository extends CrudRepository { - - } - -## Using Spring Data Repositories - -Simply inject the Repository into your Rest Resource - - @Rest - @Path("/persistence") - public class PersistentResource { - - - private final SpringDataRepository dao; - - @Autowired - public PersistentResource(SpringDataRepository dao) { - - this.dao = dao; - } - - @GET - @Produces("text/plain") - @Path("/create") - public String createEntity() { - - SpringDataEntity saved = dao.save(SpringDataEntity.builder() - .name("test") - .value("value").build()); - - return "ok"; - } - - @GET - @Produces("application/json") - @Path("/get") - public Iterable get(){ - - return dao.findAll(); - - } - } - - - # Plain ol' JDBC - -[JDBC Template Exmaple App](https://github.com/aol/micro-server/tree/master/micro-data/src/test/java/app/jdbc/com/aol/micro/server) - -The micro-data plugin also facilitate JDBC use via the Spring JDBCTemplate. A Spring called SQL will be created that contains a JDBCTemplate, simply inject SQL into your classes. - - e.g. - - @Rest - @Path("/persistence") - public class PersistentResource { - - private final SQL dao; - - @Autowired - public PersistentResource(SQL dao) { - - this.dao = dao; - } - - @GET - @Produces("text/plain") - @Path("/create") - public String createEntity() { - dao.getJdbc().update("insert into t_jdbc VALUES (1,'hello','world',1)"); - - return "ok"; - } - - @GET - @Produces("application/json") - @Path("/get") - public JdbcEntity get() { - return dao.getJdbc(). queryForObject("select * from t_jdbc", new BeanPropertyRowMapper(JdbcEntity.class)); - } - - } diff --git a/micro-hibernate/src/main/java/com/aol/micro/server/spring/HibernatePlugin.java b/micro-hibernate/src/main/java/com/aol/micro/server/spring/HibernatePlugin.java deleted file mode 100644 index 1313ba5a5..000000000 --- a/micro-hibernate/src/main/java/com/aol/micro/server/spring/HibernatePlugin.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aol.micro.server.spring; - -import java.util.Optional; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.spring.datasource.JdbcConfig; -import com.aol.micro.server.spring.datasource.hibernate.HibernateConfig; -import com.aol.micro.server.spring.datasource.hibernate.SpringDataConfig; -import com.aol.micro.server.spring.datasource.jdbc.SQL; - -/** - * - * Collections of Spring configuration classes (Classes annotated with @Configuration) - * that configure various useful pieces of functionality - such as property file loading, - * datasources, scheduling etc - * - * @author johnmcclean - * - */ -public class HibernatePlugin implements Plugin { - - @Override - public Optional springDbConfigurer() { - return Optional.of(new HibernateSpringConfigurer()); - } - - @Override - public PSetX springClasses() { - return PSetX.of(JdbcConfig.class, SQL.class, SpringDataConfig.class, HibernateConfig.class); - } - - - -} diff --git a/micro-hibernate/src/main/java/com/aol/micro/server/spring/datasource/hibernate/HibernateConfig.java b/micro-hibernate/src/main/java/com/aol/micro/server/spring/datasource/hibernate/HibernateConfig.java deleted file mode 100644 index cada8a732..000000000 --- a/micro-hibernate/src/main/java/com/aol/micro/server/spring/datasource/hibernate/HibernateConfig.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.aol.micro.server.spring.datasource.hibernate; - -import javax.annotation.Resource; -import javax.sql.DataSource; - -import org.hibernate.SessionFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.orm.hibernate5.HibernateTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -import com.aol.micro.server.config.ConfigAccessor; -import com.aol.micro.server.spring.datasource.JdbcConfig; - -@Configuration -@EnableTransactionManagement -public class HibernateConfig { - - @Resource(name="mainEnv") - private JdbcConfig env; - @Resource(name="mainDataSource") - private DataSource dataSource; - - @Bean - public HibernateTransactionManager transactionManager() { - HibernateTransactionManager transactionManager = new HibernateTransactionManager(); - transactionManager.setSessionFactory(sessionFactory()); - return transactionManager; - } - - @Bean - public SessionFactory sessionFactory(){ - return HibernateSessionBuilder.builder() - .packages(new ConfigAccessor().get().getDataSources().get(new ConfigAccessor().get() - .getDefaultDataSourceName())) - .env(env) - .dataSource(dataSource) - .build().sessionFactory(); - } - - - - - -} diff --git a/micro-hibernate/src/main/java/com/aol/micro/server/spring/datasource/hibernate/SpringDataConfig.java b/micro-hibernate/src/main/java/com/aol/micro/server/spring/datasource/hibernate/SpringDataConfig.java deleted file mode 100644 index f2bf22b02..000000000 --- a/micro-hibernate/src/main/java/com/aol/micro/server/spring/datasource/hibernate/SpringDataConfig.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.spring.datasource.hibernate; - -import javax.annotation.Resource; -import javax.persistence.EntityManagerFactory; -import javax.sql.DataSource; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -import com.aol.micro.server.config.ConfigAccessor; -import com.aol.micro.server.spring.datasource.JdbcConfig; - -@Configuration -@EnableTransactionManagement -public class SpringDataConfig { - - @Resource(name = "mainEnv") - private JdbcConfig env; - @Resource(name = "mainDataSource") - private DataSource dataSource; - - @Bean - public EntityManagerFactory entityManagerFactory() { - - HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); - if (env.getGenerateDdl().equals("true")) { - vendorAdapter.setGenerateDdl(true); - } else { - vendorAdapter.setGenerateDdl(false); - } - - LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); - factory.setJpaVendorAdapter(vendorAdapter); - - factory.setPackagesToScan(new ConfigAccessor().get().getDataSources().get(new ConfigAccessor().get().getDefaultDataSourceName()) - .toArray(new String[0])); - factory.setDataSource(dataSource); - factory.afterPropertiesSet(); - - return factory.getObject(); - } - - @Bean - public PlatformTransactionManager transactionManager() { - - JpaTransactionManager txManager = new JpaTransactionManager(); - txManager.setEntityManagerFactory(entityManagerFactory()); - return txManager; - } -} diff --git a/micro-hibernate/src/main/java/com/oath/micro/server/spring/HibernatePlugin.java b/micro-hibernate/src/main/java/com/oath/micro/server/spring/HibernatePlugin.java new file mode 100644 index 000000000..08b42e101 --- /dev/null +++ b/micro-hibernate/src/main/java/com/oath/micro/server/spring/HibernatePlugin.java @@ -0,0 +1,36 @@ +package com.oath.micro.server.spring; + +import java.util.Optional; +import java.util.Set; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.spring.datasource.JdbcConfig; +import com.oath.micro.server.spring.datasource.hibernate.HibernateConfig; +import com.oath.micro.server.spring.datasource.jdbc.SQL; +import cyclops.reactive.collections.mutable.SetX; + +/** + * + * Collections of Spring configuration classes (Classes annotated with @Configuration) + * that configure various useful pieces of functionality - such as property file loading, + * datasources, scheduling etc + * + * @author johnmcclean + * + */ +public class HibernatePlugin implements Plugin { + + @Override + public Optional springDbConfigurer() { + return Optional.of(new HibernateSpringConfigurer()); + } + + @Override + public Set springClasses() { + return SetX.of(JdbcConfig.class, SQL.class, HibernateConfig.class); + } + + + +} diff --git a/micro-hibernate/src/main/java/com/aol/micro/server/spring/HibernateSpringConfigurer.java b/micro-hibernate/src/main/java/com/oath/micro/server/spring/HibernateSpringConfigurer.java similarity index 81% rename from micro-hibernate/src/main/java/com/aol/micro/server/spring/HibernateSpringConfigurer.java rename to micro-hibernate/src/main/java/com/oath/micro/server/spring/HibernateSpringConfigurer.java index 8aef4bad6..0fa9a5eda 100644 --- a/micro-hibernate/src/main/java/com/aol/micro/server/spring/HibernateSpringConfigurer.java +++ b/micro-hibernate/src/main/java/com/oath/micro/server/spring/HibernateSpringConfigurer.java @@ -1,5 +1,6 @@ -package com.aol.micro.server.spring; +package com.oath.micro.server.spring; +import java.util.Arrays; import java.util.Properties; import javax.sql.DataSource; @@ -11,9 +12,9 @@ import org.springframework.orm.hibernate5.HibernateTransactionManager; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.spring.datasource.JdbcConfig; -import com.aol.micro.server.spring.datasource.hibernate.HibernateSessionBuilder; +import com.oath.micro.server.config.Config; +import com.oath.micro.server.spring.datasource.JdbcConfig; +import com.oath.micro.server.spring.datasource.hibernate.HibernateSessionBuilder; public class HibernateSpringConfigurer implements SpringDBConfig { @@ -48,13 +49,13 @@ private JdbcConfig buildJdbcProperties(AnnotationConfigWebApplicationContext roo } private HibernateTransactionManager buildTransactionManager(String name, Config config, DataSource dataSource, JdbcConfig jdbc) { - return HibernateSessionBuilder.builder().packages(config.getDataSources().get(name)).dataSource(dataSource).env(jdbc).build() + return HibernateSessionBuilder.builder().packages(config.getDataSources().getOrElse(name, Arrays.asList())).dataSource(dataSource).env(jdbc).build() .transactionManager(); } private SessionFactory buildSession(String name, Config config, DataSource dataSource, JdbcConfig jdbc) { - return HibernateSessionBuilder.builder().packages(config.getDataSources().get(name)).dataSource(dataSource).env(jdbc).build() + return HibernateSessionBuilder.builder().packages(config.getDataSources().getOrElse(name,Arrays.asList())).dataSource(dataSource).env(jdbc).build() .sessionFactory(); } } diff --git a/micro-hibernate/src/main/java/com/oath/micro/server/spring/datasource/hibernate/HibernateConfig.java b/micro-hibernate/src/main/java/com/oath/micro/server/spring/datasource/hibernate/HibernateConfig.java new file mode 100644 index 000000000..300d94721 --- /dev/null +++ b/micro-hibernate/src/main/java/com/oath/micro/server/spring/datasource/hibernate/HibernateConfig.java @@ -0,0 +1,47 @@ +package com.oath.micro.server.spring.datasource.hibernate; + +import javax.annotation.Resource; +import javax.sql.DataSource; + +import org.hibernate.SessionFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.orm.hibernate5.HibernateTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import com.oath.micro.server.config.ConfigAccessor; +import com.oath.micro.server.spring.datasource.JdbcConfig; + +import java.util.Arrays; + +@Configuration +@EnableTransactionManagement +public class HibernateConfig { + + @Resource(name="mainEnv") + private JdbcConfig env; + @Resource(name="mainDataSource") + private DataSource dataSource; + + @Bean + public HibernateTransactionManager transactionManager() { + HibernateTransactionManager transactionManager = new HibernateTransactionManager(); + transactionManager.setSessionFactory(sessionFactory()); + return transactionManager; + } + + @Bean + public SessionFactory sessionFactory(){ + return HibernateSessionBuilder.builder() + .packages(new ConfigAccessor().get().getDataSources().getOrElse(new ConfigAccessor().get() + .getDefaultDataSourceName(), Arrays.asList())) + .env(env) + .dataSource(dataSource) + .build().sessionFactory(); + } + + + + + +} diff --git a/micro-hibernate/src/main/java/com/aol/micro/server/spring/datasource/hibernate/HibernateSessionBuilder.java b/micro-hibernate/src/main/java/com/oath/micro/server/spring/datasource/hibernate/HibernateSessionBuilder.java similarity index 90% rename from micro-hibernate/src/main/java/com/aol/micro/server/spring/datasource/hibernate/HibernateSessionBuilder.java rename to micro-hibernate/src/main/java/com/oath/micro/server/spring/datasource/hibernate/HibernateSessionBuilder.java index 66fa6761f..96ad3c1ec 100644 --- a/micro-hibernate/src/main/java/com/aol/micro/server/spring/datasource/hibernate/HibernateSessionBuilder.java +++ b/micro-hibernate/src/main/java/com/oath/micro/server/spring/datasource/hibernate/HibernateSessionBuilder.java @@ -1,12 +1,13 @@ -package com.aol.micro.server.spring.datasource.hibernate; +package com.oath.micro.server.spring.datasource.hibernate; import java.util.List; import java.util.Properties; import javax.sql.DataSource; +import com.oath.cyclops.util.ExceptionSoftener; import lombok.AllArgsConstructor; -import lombok.experimental.Builder; +import lombok.Builder; import org.hibernate.SessionFactory; import org.slf4j.Logger; @@ -14,8 +15,7 @@ import org.springframework.orm.hibernate5.HibernateTransactionManager; import org.springframework.orm.hibernate5.LocalSessionFactoryBean; -import com.aol.cyclops.util.ExceptionSoftener; -import com.aol.micro.server.spring.datasource.JdbcConfig; +import com.oath.micro.server.spring.datasource.JdbcConfig; @Builder @AllArgsConstructor @@ -42,12 +42,12 @@ public SessionFactory sessionFactory() { if (env.getDdlAuto() != null) p.setProperty("hibernate.hbm2ddl.auto", env.getDdlAuto()); - + if(env.getInitializationFile() != null) { p.setProperty("hibernate.hbm2ddl.import_files", env.getInitializationFile()); - + } - + logger.info("Hibernate properties [ hibernate.dialect : {} ; hibernate.hbm2ddl.auto : {} ]", env.getDialect(), env.getDdlAuto()); sessionFactoryBean.setHibernateProperties(p); diff --git a/micro-hibernate/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-hibernate/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 0159c36a2..000000000 --- a/micro-hibernate/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.spring.HibernatePlugin \ No newline at end of file diff --git a/micro-hibernate/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-hibernate/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..b4bd5461a --- /dev/null +++ b/micro-hibernate/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.spring.HibernatePlugin \ No newline at end of file diff --git a/micro-hibernate/src/test/java/app/hibernate/com/aol/micro/server/PersistentResource.java b/micro-hibernate/src/test/java/app/hibernate/com/aol/micro/server/PersistentResource.java deleted file mode 100644 index f7b282a55..000000000 --- a/micro-hibernate/src/test/java/app/hibernate/com/aol/micro/server/PersistentResource.java +++ /dev/null @@ -1,60 +0,0 @@ -package app.hibernate.com.aol.micro.server; - -import java.util.List; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.hibernate.Criteria; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.criterion.Example; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/persistence") -public class PersistentResource implements RestResource { - - - private final SessionFactory sessionFactory; - - - @Autowired - public PersistentResource(SessionFactory sessionFactory) { - - this.sessionFactory = sessionFactory; - } - - @GET - @Produces("text/plain") - @Path("/create") - public String createEntity() { - - final Session session = sessionFactory.openSession(); - session.save(HibernateEntity.builder() - .name("test") - .value("value").build()); - session.flush(); - return "ok"; - } - @GET - @Produces("application/json") - @Path("/get") - public List get(){ - final Session session = sessionFactory.openSession(); - - Criteria criteria = session.createCriteria(HibernateEntity.class) - .add(Example.create(HibernateEntity.builder() - .name("test") - .build())); - - return criteria.list(); - - } - - -} \ No newline at end of file diff --git a/micro-hibernate/src/test/java/app/hibernate/com/aol/micro/server/HibernateEntity.java b/micro-hibernate/src/test/java/app/hibernate/com/oath/micro/server/HibernateEntity.java similarity index 93% rename from micro-hibernate/src/test/java/app/hibernate/com/aol/micro/server/HibernateEntity.java rename to micro-hibernate/src/test/java/app/hibernate/com/oath/micro/server/HibernateEntity.java index 330c786a2..d4e127d74 100644 --- a/micro-hibernate/src/test/java/app/hibernate/com/aol/micro/server/HibernateEntity.java +++ b/micro-hibernate/src/test/java/app/hibernate/com/oath/micro/server/HibernateEntity.java @@ -1,4 +1,4 @@ -package app.hibernate.com.aol.micro.server; +package app.hibernate.com.oath.micro.server; import static javax.persistence.GenerationType.IDENTITY; @@ -13,7 +13,7 @@ import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; import lombok.Setter; -import lombok.experimental.Builder; +import lombok.Builder; @Entity @Table(name = "t_hibernate", uniqueConstraints = @UniqueConstraint(columnNames = { diff --git a/micro-hibernate/src/test/java/app/hibernate/com/aol/micro/server/HibernateRunnerTest.java b/micro-hibernate/src/test/java/app/hibernate/com/oath/micro/server/HibernateRunnerTest.java similarity index 77% rename from micro-hibernate/src/test/java/app/hibernate/com/aol/micro/server/HibernateRunnerTest.java rename to micro-hibernate/src/test/java/app/hibernate/com/oath/micro/server/HibernateRunnerTest.java index f42c86847..bba71e3d0 100644 --- a/micro-hibernate/src/test/java/app/hibernate/com/aol/micro/server/HibernateRunnerTest.java +++ b/micro-hibernate/src/test/java/app/hibernate/com/oath/micro/server/HibernateRunnerTest.java @@ -1,4 +1,4 @@ -package app.hibernate.com.aol.micro.server; +package app.hibernate.com.oath.micro.server; import static org.hamcrest.CoreMatchers.is; @@ -11,12 +11,12 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.testing.RestAgent; -@Microserver(entityScan="app.hibernate.com.aol.micro.server",properties={"db.connection.driver","org.hsqldb.jdbcDriver", +@Microserver(entityScan="app.hibernate.com.oath.micro.server",properties={"db.connection.driver","org.hsqldb.jdbcDriver", "db.connection.url","jdbc:hsqldb:mem:aname", "db.connection.username", "sa", "db.connection.dialect","org.hibernate.dialect.HSQLDialect", diff --git a/micro-hibernate/src/test/java/app/hibernate/com/oath/micro/server/PersistentResource.java b/micro-hibernate/src/test/java/app/hibernate/com/oath/micro/server/PersistentResource.java new file mode 100644 index 000000000..7b2dab678 --- /dev/null +++ b/micro-hibernate/src/test/java/app/hibernate/com/oath/micro/server/PersistentResource.java @@ -0,0 +1,63 @@ +package app.hibernate.com.oath.micro.server; + +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.hibernate.Criteria; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.criterion.Example; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/persistence") +public class PersistentResource implements RestResource { + + + private final SessionFactory sessionFactory; + + + @Autowired + public PersistentResource(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + @GET + @Produces("text/plain") + @Path("/create") + public String createEntity() { + + final Session session = sessionFactory.openSession(); + Transaction tx = session.beginTransaction(); + session.save(HibernateEntity.builder() + .name("test") + .value("value").build()); + session.flush(); + tx.commit(); + return "ok"; + } + + @GET + @Produces("application/json") + @Path("/get") + public List get() { + final Session session = sessionFactory.openSession(); + + Criteria criteria = session.createCriteria(HibernateEntity.class) + .add(Example.create(HibernateEntity.builder() + .name("test") + .build())); + + return criteria.list(); + + } + + +} diff --git a/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/HibernateEntityForDDLAutoCreate.java b/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/HibernateEntityForDDLAutoCreate.java index 8a0dbdcf4..178a82bfe 100644 --- a/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/HibernateEntityForDDLAutoCreate.java +++ b/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/HibernateEntityForDDLAutoCreate.java @@ -13,7 +13,7 @@ import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; import lombok.Setter; -import lombok.experimental.Builder; +import lombok.Builder; @Entity @Table(name = "t_jdbc", uniqueConstraints = @UniqueConstraint(columnNames = { diff --git a/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/JdbcEntity.java b/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/JdbcEntity.java index 7fddb6b7c..0e43b2d0b 100644 --- a/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/JdbcEntity.java +++ b/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/JdbcEntity.java @@ -4,7 +4,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import lombok.experimental.Builder; +import lombok.Builder; diff --git a/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/JdbcRunnerTest.java b/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/JdbcRunnerTest.java index 32e160a96..951c02d6d 100644 --- a/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/JdbcRunnerTest.java +++ b/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/JdbcRunnerTest.java @@ -10,10 +10,10 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.testing.RestAgent; @Microserver(entityScan="app.jdbc.com.aol.micro.server",properties={"db.connection.driver","org.hsqldb.jdbcDriver", "db.connection.url","jdbc:hsqldb:mem:aname", diff --git a/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/PersistentResource.java b/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/PersistentResource.java index 66c560794..9c405d78c 100644 --- a/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/PersistentResource.java +++ b/micro-hibernate/src/test/java/app/jdbc/com/aol/micro/server/PersistentResource.java @@ -7,8 +7,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.spring.datasource.jdbc.SQL; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.spring.datasource.jdbc.SQL; @Rest @Path("/persistence") diff --git a/micro-hibernate/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcEntity.java b/micro-hibernate/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcEntity.java deleted file mode 100644 index 5fd88b137..000000000 --- a/micro-hibernate/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcEntity.java +++ /dev/null @@ -1,27 +0,0 @@ -package app.pure.jdbc.com.aol.micro.server; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.experimental.Builder; - - - - -@Setter -@Getter -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class JdbcEntity implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - - private Long id; - private String name; - private String value; - private int version; - - -} diff --git a/micro-hibernate/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcRunnerTest.java b/micro-hibernate/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcRunnerTest.java deleted file mode 100644 index 612b9d9dd..000000000 --- a/micro-hibernate/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcRunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.pure.jdbc.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", - "db.connection.url","jdbc:hsqldb:mem:aname", - "db.connection.username", "sa", - }) -public class JdbcRunnerTest { - - private final AsyncRestClient listClient = new AsyncRestClient(1000,1000).withResponse(JdbcEntity.class); - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer(){ - - - server = new MicroserverApp(()->"jdbc-app"); - server.start(); - rest.get("http://localhost:8080/jdbc-app/persistence/gen"); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/jdbc-app/persistence/create"),is("ok")); - assertThat(listClient.get("http://localhost:8080/jdbc-app/persistence/get").get(),is(JdbcEntity.class)); - - } - - - -} diff --git a/micro-hibernate/src/test/java/app/pure/jdbc/com/aol/micro/server/PersistentResource.java b/micro-hibernate/src/test/java/app/pure/jdbc/com/aol/micro/server/PersistentResource.java deleted file mode 100644 index d6e7a8a82..000000000 --- a/micro-hibernate/src/test/java/app/pure/jdbc/com/aol/micro/server/PersistentResource.java +++ /dev/null @@ -1,50 +0,0 @@ -package app.pure.jdbc.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.BeanPropertyRowMapper; - -import app.pure.jdbc.com.aol.micro.server.JdbcEntity; - -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.spring.datasource.jdbc.SQL; - -@Rest -@Path("/persistence") -public class PersistentResource { - - private final SQL dao; - - @Autowired - public PersistentResource(SQL dao) { - - this.dao = dao; - } - @GET - @Produces("text/plain") - @Path("/gen") - public String gen() { - dao.getJdbc().execute("create table t_jdbc(id bigint,name varchar(255),value varchar(255),version int);"); - - return "ok"; - } - @GET - @Produces("text/plain") - @Path("/create") - public String createEntity() { - dao.getJdbc().update("insert into t_jdbc VALUES (1,'hello','world',1)"); - - return "ok"; - } - - @GET - @Produces("application/json") - @Path("/get") - public JdbcEntity get() { - return dao.getJdbc(). queryForObject("select * from t_jdbc", new BeanPropertyRowMapper(JdbcEntity.class)); - } - -} \ No newline at end of file diff --git a/micro-hibernate/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcEntity.java b/micro-hibernate/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcEntity.java new file mode 100644 index 000000000..c92fd662b --- /dev/null +++ b/micro-hibernate/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcEntity.java @@ -0,0 +1,27 @@ +package app.pure.jdbc.com.oath.micro.server; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.Builder; + + + + +@Setter +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class JdbcEntity implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + private String name; + private String value; + private int version; + + +} diff --git a/micro-hibernate/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcRunnerTest.java b/micro-hibernate/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcRunnerTest.java new file mode 100644 index 000000000..fe8483a12 --- /dev/null +++ b/micro-hibernate/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcRunnerTest.java @@ -0,0 +1,55 @@ +package app.pure.jdbc.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", + "db.connection.url","jdbc:hsqldb:mem:aname", + "db.connection.username", "sa", + }) +public class JdbcRunnerTest { + + private final AsyncRestClient listClient = new AsyncRestClient(1000,1000).withResponse(JdbcEntity.class); + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer(){ + + + server = new MicroserverApp(()->"jdbc-app"); + server.start(); + rest.get("http://localhost:8080/jdbc-app/persistence/gen"); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/jdbc-app/persistence/create"),is("ok")); + assertThat(listClient.get("http://localhost:8080/jdbc-app/persistence/get").get(),is(JdbcEntity.class)); + + } + + + +} diff --git a/micro-hibernate/src/test/java/app/pure/jdbc/com/oath/micro/server/PersistentResource.java b/micro-hibernate/src/test/java/app/pure/jdbc/com/oath/micro/server/PersistentResource.java new file mode 100644 index 000000000..869898590 --- /dev/null +++ b/micro-hibernate/src/test/java/app/pure/jdbc/com/oath/micro/server/PersistentResource.java @@ -0,0 +1,48 @@ +package app.pure.jdbc.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.BeanPropertyRowMapper; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.spring.datasource.jdbc.SQL; + +@Rest +@Path("/persistence") +public class PersistentResource { + + private final SQL dao; + + @Autowired + public PersistentResource(SQL dao) { + + this.dao = dao; + } + @GET + @Produces("text/plain") + @Path("/gen") + public String gen() { + dao.getJdbc().execute("create table t_jdbc(id bigint,name varchar(255),value varchar(255),version int);"); + + return "ok"; + } + @GET + @Produces("text/plain") + @Path("/create") + public String createEntity() { + dao.getJdbc().update("insert into t_jdbc VALUES (1,'hello','world',1)"); + + return "ok"; + } + + @GET + @Produces("application/json") + @Path("/get") + public JdbcEntity get() { + return dao.getJdbc(). queryForObject("select * from t_jdbc", new BeanPropertyRowMapper(JdbcEntity.class)); + } + +} \ No newline at end of file diff --git a/micro-hibernate/src/test/java/app/spring/data/jpa/com/aol/micro/server/PersistentResource.java b/micro-hibernate/src/test/java/app/spring/data/jpa/com/aol/micro/server/PersistentResource.java deleted file mode 100644 index 62101e2f6..000000000 --- a/micro-hibernate/src/test/java/app/spring/data/jpa/com/aol/micro/server/PersistentResource.java +++ /dev/null @@ -1,46 +0,0 @@ -package app.spring.data.jpa.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/persistence") -public class PersistentResource { - - - private final SpringDataRepository dao; - - @Autowired - public PersistentResource(SpringDataRepository dao) { - - this.dao = dao; - } - - @GET - @Produces("text/plain") - @Path("/create") - public String createEntity() { - - SpringDataEntity saved = dao.save(SpringDataEntity.builder() - .name("test") - .value("value").build()); - - return "ok"; - } - @GET - @Produces("application/json") - @Path("/get") - public Iterable get(){ - - return dao.findAll(); - - - } - - -} \ No newline at end of file diff --git a/micro-hibernate/src/test/java/app/spring/data/jpa/com/aol/micro/server/SpringDataRepository.java b/micro-hibernate/src/test/java/app/spring/data/jpa/com/aol/micro/server/SpringDataRepository.java deleted file mode 100644 index 0eb79b503..000000000 --- a/micro-hibernate/src/test/java/app/spring/data/jpa/com/aol/micro/server/SpringDataRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package app.spring.data.jpa.com.aol.micro.server; - -import org.springframework.data.repository.CrudRepository; -import org.springframework.stereotype.Repository; - - -public interface SpringDataRepository extends CrudRepository { - -} diff --git a/micro-hibernate/src/test/java/app/spring/data/jpa/com/oath/micro/server/PersistentResource.java b/micro-hibernate/src/test/java/app/spring/data/jpa/com/oath/micro/server/PersistentResource.java new file mode 100644 index 000000000..a17e42136 --- /dev/null +++ b/micro-hibernate/src/test/java/app/spring/data/jpa/com/oath/micro/server/PersistentResource.java @@ -0,0 +1,46 @@ +package app.spring.data.jpa.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/persistence") +public class PersistentResource { + + + private final SpringDataRepository dao; + + @Autowired + public PersistentResource(SpringDataRepository dao) { + + this.dao = dao; + } + + @GET + @Produces("text/plain") + @Path("/create") + public String createEntity() { + + SpringDataEntity saved = dao.save(SpringDataEntity.builder() + .name("test") + .value("value").build()); + + return "ok"; + } + @GET + @Produces("application/json") + @Path("/get") + public Iterable get(){ + + return dao.findAll(); + + + } + + +} \ No newline at end of file diff --git a/micro-hibernate/src/test/java/app/spring/data/jpa/com/aol/micro/server/SpringDataEntity.java b/micro-hibernate/src/test/java/app/spring/data/jpa/com/oath/micro/server/SpringDataEntity.java similarity index 93% rename from micro-hibernate/src/test/java/app/spring/data/jpa/com/aol/micro/server/SpringDataEntity.java rename to micro-hibernate/src/test/java/app/spring/data/jpa/com/oath/micro/server/SpringDataEntity.java index b847ca421..320b16b2d 100644 --- a/micro-hibernate/src/test/java/app/spring/data/jpa/com/aol/micro/server/SpringDataEntity.java +++ b/micro-hibernate/src/test/java/app/spring/data/jpa/com/oath/micro/server/SpringDataEntity.java @@ -1,4 +1,4 @@ -package app.spring.data.jpa.com.aol.micro.server; +package app.spring.data.jpa.com.oath.micro.server; import static javax.persistence.GenerationType.IDENTITY; @@ -13,7 +13,7 @@ import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; import lombok.Setter; -import lombok.experimental.Builder; +import lombok.Builder; @Entity @Table(name = "t_spring_data", uniqueConstraints = @UniqueConstraint(columnNames = { diff --git a/micro-hibernate/src/test/java/app/spring/data/jpa/com/oath/micro/server/SpringDataRepository.java b/micro-hibernate/src/test/java/app/spring/data/jpa/com/oath/micro/server/SpringDataRepository.java new file mode 100644 index 000000000..aabca1886 --- /dev/null +++ b/micro-hibernate/src/test/java/app/spring/data/jpa/com/oath/micro/server/SpringDataRepository.java @@ -0,0 +1,8 @@ +package app.spring.data.jpa.com.oath.micro.server; + +import org.springframework.data.repository.CrudRepository; + + +public interface SpringDataRepository extends CrudRepository { + +} diff --git a/micro-hibernate/src/test/java/app/spring/data/jpa/com/aol/micro/server/SpringDataTest.java b/micro-hibernate/src/test/java/app/spring/data/jpa/com/oath/micro/server/SpringDataTest.java similarity index 81% rename from micro-hibernate/src/test/java/app/spring/data/jpa/com/aol/micro/server/SpringDataTest.java rename to micro-hibernate/src/test/java/app/spring/data/jpa/com/oath/micro/server/SpringDataTest.java index c25f0a701..a57e9ad61 100644 --- a/micro-hibernate/src/test/java/app/spring/data/jpa/com/aol/micro/server/SpringDataTest.java +++ b/micro-hibernate/src/test/java/app/spring/data/jpa/com/oath/micro/server/SpringDataTest.java @@ -1,4 +1,4 @@ -package app.spring.data.jpa.com.aol.micro.server; +package app.spring.data.jpa.com.oath.micro.server; import static org.hamcrest.CoreMatchers.is; @@ -13,18 +13,19 @@ import org.junit.Test; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Config; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.testing.RestAgent; @Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", "db.connection.url","jdbc:hsqldb:mem:aname", "db.connection.username", "sa", "db.connection.dialect","org.hibernate.dialect.HSQLDialect", - "db.connection.ddl.auto","create-drop"}, entityScan="app.spring.data.jpa.com.aol.micro.server") + "db.connection.ddl.auto","create-drop"}, entityScan="app.spring.data.jpa.com.oath.micro.server") @EnableJpaRepositories +@Ignore public class SpringDataTest { private final AsyncRestClient> listClient = new AsyncRestClient(1000,1000).withGenericResponse(List.class, SpringDataEntity.class); diff --git a/micro-hibernate/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-hibernate/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-hibernate/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-hibernate/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-hibernate/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-hibernate/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-hikaricp/README.md b/micro-hikaricp/README.md new file mode 100644 index 000000000..22e3cd6f9 --- /dev/null +++ b/micro-hikaricp/README.md @@ -0,0 +1,53 @@ + # HikariCP plugin + +[micro-hikaricp example apps](https://github.com/aol/micro-server/tree/master/micro-hikaricp/src/test/java/app) + +Creates a DataSource Spring Bean with name "mainDataSource". This will be based on [HikariCP](http://brettwooldridge.github.io/HikariCP/ludicrous.html). + +## To use + + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-hikaricp/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-hikaricp) + +Simply add to the classpath + +Maven + + + com.oath.microservices + micro-hikaricp + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-hikaricp:x.yz' + +# Configuring a data source + +A datasource can be configured by setting the following properties in application.properties, instance.properties or via the Microserver annotation + + db.connection.driver: (e.g. (org.hsqldb.jdbcDriver) + db.connection.url: (e.g. jdbc:hsqldb:mem:aname) + db.connection.username: (e.g. admin) + db.connection.password: (e.g. password) + db.connection.dialect: (e.g. org.hibernate.dialect.HSQLDialect) + db.connection.hibernate.showsql: (e.g. true | false) + db.connection.ddl.auto: (e.g. create-drop) + hikaricp.db.connection.max.pool.size (e.g. 30) + hikaricp.db.connection.min.idle (e.g. 2) + hikaricp.db.connection.idle.timeout (e.g. 1800000) + +The Microserver annotation can also be used to set some default properties, or they can be set in an application.properties or instance.properties file ([see wiki for more details](https://github.com/aol/micro-server/wiki/Defining-Properties)). + + +The important properties for us to set are the datasource properties + + @Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", + "db.connection.url","jdbc:hsqldb:mem:aname", + "db.connection.username", "sa"}) + + public class MyMainClass { + + + } diff --git a/micro-hikaricp/build.gradle b/micro-hikaricp/build.gradle index 868314565..d5c32b9bc 100644 --- a/micro-hikaricp/build.gradle +++ b/micro-hikaricp/build.gradle @@ -1,72 +1,71 @@ description = 'micro-hikaricp' + dependencies { - - compile 'com.zaxxer:HikariCP:'+hikariCPVersion - compile project(':micro-core') - compile project(':micro-jdbc') - - testCompile project(':micro-client') - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') - testCompile group: 'org.hsqldb', name:'hsqldb', version:'2.0.0' + compile 'com.zaxxer:HikariCP:' + hikariCPVersion + compile project(':micro-core') + compile project(':micro-jdbc') + testCompile project(':micro-client') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') + testCompile group: 'org.hsqldb', name: 'hsqldb', version: '2.0.0' } modifyPom { - project { - name 'Microserver hikaricp' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver hikaricp' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-hikaricp' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } - groupId 'com.aol.microservices' - artifactId 'micro-hikaricp' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - developer { - id 'earlzero' - name 'Nikita Sapozhnikov' - email 'nikita.sapozhnikov@teamaol.com' - } - } - - } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-hikaricp/readme.md b/micro-hikaricp/readme.md deleted file mode 100644 index 0f90c3b49..000000000 --- a/micro-hikaricp/readme.md +++ /dev/null @@ -1,53 +0,0 @@ - # HikariCP plugin - -[micro-hikaricp example apps](https://github.com/aol/micro-server/tree/master/micro-hikaricp/src/test/java/app) - -Creates a DataSource Spring Bean with name "mainDataSource". This will be based on [HikariCP](http://brettwooldridge.github.io/HikariCP/ludicrous.html). - -## To use - - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-hikaricp/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-hikaricp) - -Simply add to the classpath - -Maven - - - com.aol.microservices - micro-hikaricp - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-hikaricp:x.yz' - -# Configuring a data source - -A datasource can be configured by setting the following properties in application.properties, instance.properties or via the Microserver annotation - - db.connection.driver: (e.g. (org.hsqldb.jdbcDriver) - db.connection.url: (e.g. jdbc:hsqldb:mem:aname) - db.connection.username: (e.g. admin) - db.connection.password: (e.g. password) - db.connection.dialect: (e.g. org.hibernate.dialect.HSQLDialect) - db.connection.hibernate.showsql: (e.g. true | false) - db.connection.ddl.auto: (e.g. create-drop) - hikaricp.db.connection.max.pool.size (e.g. 30) - hikaricp.db.connection.min.idle (e.g. 2) - hikaricp.db.connection.idle.timeout (e.g. 1800000) - -The Microserver annotation can also be used to set some default properties, or they can be set in an application.properties or instance.properties file ([see wiki for more details](https://github.com/aol/micro-server/wiki/Defining-Properties)). - - -The important properties for us to set are the datasource properties - - @Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", - "db.connection.url","jdbc:hsqldb:mem:aname", - "db.connection.username", "sa"}) - - public class MyMainClass { - - - } diff --git a/micro-hikaricp/src/main/java/com/aol/micro/server/spring/HikariCPPlugin.java b/micro-hikaricp/src/main/java/com/aol/micro/server/spring/HikariCPPlugin.java deleted file mode 100644 index 8a563d0b7..000000000 --- a/micro-hikaricp/src/main/java/com/aol/micro/server/spring/HikariCPPlugin.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aol.micro.server.spring; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.spring.datasource.HikariCPConfig; -import com.aol.micro.server.spring.datasource.HikariCPDataSourceBuilder; - -/** - * - * @author kewang - * - */ -public class HikariCPPlugin implements Plugin { - - @Override - public PSetX springClasses() { - return PSetX.of(HikariCPConfig.class, HikariCPDataSourceBuilder.class); - } - - - -} diff --git a/micro-hikaricp/src/main/java/com/oath/micro/server/spring/HikariCPPlugin.java b/micro-hikaricp/src/main/java/com/oath/micro/server/spring/HikariCPPlugin.java new file mode 100644 index 000000000..8589aaf1f --- /dev/null +++ b/micro-hikaricp/src/main/java/com/oath/micro/server/spring/HikariCPPlugin.java @@ -0,0 +1,25 @@ +package com.oath.micro.server.spring; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.spring.datasource.HikariCPConfig; +import com.oath.micro.server.spring.datasource.HikariCPDataSourceBuilder; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +/** + * + * @author kewang + * + */ +public class HikariCPPlugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of(HikariCPConfig.class, HikariCPDataSourceBuilder.class); + } + + + +} diff --git a/micro-hikaricp/src/main/java/com/aol/micro/server/spring/datasource/HikariCPConfig.java b/micro-hikaricp/src/main/java/com/oath/micro/server/spring/datasource/HikariCPConfig.java similarity index 87% rename from micro-hikaricp/src/main/java/com/aol/micro/server/spring/datasource/HikariCPConfig.java rename to micro-hikaricp/src/main/java/com/oath/micro/server/spring/datasource/HikariCPConfig.java index 66a068f7c..00188b31e 100644 --- a/micro-hikaricp/src/main/java/com/aol/micro/server/spring/datasource/HikariCPConfig.java +++ b/micro-hikaricp/src/main/java/com/oath/micro/server/spring/datasource/HikariCPConfig.java @@ -1,7 +1,7 @@ -package com.aol.micro.server.spring.datasource; +package com.oath.micro.server.spring.datasource; import lombok.Getter; -import lombok.experimental.Builder; +import lombok.Builder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -18,7 +18,7 @@ public class HikariCPConfig { @Autowired public HikariCPConfig(@Value("${hikaricp.db.connection.max.pool.size:30}") int maxPoolSize, @Value("${hikaricp.db.connection.min.idle:2}") int minimumIdle, - @Value("${hikaricp.db.connection.idle.timeout:1800000}") long idleTimeout) { + @Value("${hikaricp.db.connection.idle.timeout:1800000}") long idleTimeout) { this.maxPoolSize = maxPoolSize; this.minimumIdle = minimumIdle; this.idleTimeout = idleTimeout; diff --git a/micro-hikaricp/src/main/java/com/aol/micro/server/spring/datasource/HikariCPDataSourceBuilder.java b/micro-hikaricp/src/main/java/com/oath/micro/server/spring/datasource/HikariCPDataSourceBuilder.java similarity index 92% rename from micro-hikaricp/src/main/java/com/aol/micro/server/spring/datasource/HikariCPDataSourceBuilder.java rename to micro-hikaricp/src/main/java/com/oath/micro/server/spring/datasource/HikariCPDataSourceBuilder.java index 6a72c225f..4cc1e26ab 100644 --- a/micro-hikaricp/src/main/java/com/aol/micro/server/spring/datasource/HikariCPDataSourceBuilder.java +++ b/micro-hikaricp/src/main/java/com/oath/micro/server/spring/datasource/HikariCPDataSourceBuilder.java @@ -1,11 +1,11 @@ -package com.aol.micro.server.spring.datasource; +package com.oath.micro.server.spring.datasource; import javax.annotation.Resource; import javax.sql.DataSource; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; -import lombok.experimental.Builder; +import lombok.Builder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -17,7 +17,7 @@ @NoArgsConstructor @AllArgsConstructor public class HikariCPDataSourceBuilder { - + @Resource(name = "mainEnv") private JdbcConfig mainEnv; diff --git a/micro-hikaricp/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-hikaricp/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 59492eea5..000000000 --- a/micro-hikaricp/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.spring.HikariCPPlugin \ No newline at end of file diff --git a/micro-hikaricp/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-hikaricp/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..478fe9735 --- /dev/null +++ b/micro-hikaricp/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.spring.HikariCPPlugin \ No newline at end of file diff --git a/micro-hikaricp/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcEntity.java b/micro-hikaricp/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcEntity.java deleted file mode 100644 index 5fd88b137..000000000 --- a/micro-hikaricp/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcEntity.java +++ /dev/null @@ -1,27 +0,0 @@ -package app.pure.jdbc.com.aol.micro.server; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.experimental.Builder; - - - - -@Setter -@Getter -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class JdbcEntity implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - - private Long id; - private String name; - private String value; - private int version; - - -} diff --git a/micro-hikaricp/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcRunnerTest.java b/micro-hikaricp/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcRunnerTest.java deleted file mode 100644 index ec6b573b7..000000000 --- a/micro-hikaricp/src/test/java/app/pure/jdbc/com/aol/micro/server/JdbcRunnerTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package app.pure.jdbc.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", - "db.connection.url","jdbc:hsqldb:mem:aname", - "db.connection.username", "sa", - }) -public class JdbcRunnerTest { - - private final AsyncRestClient listClient = new AsyncRestClient(1000,1000).withResponse(JdbcEntity.class); - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer(){ - - - server = new MicroserverApp(()->"jdbc-app"); - server.start(); - rest.get("http://localhost:8080/jdbc-app/persistence/gen"); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException { - - assertThat(rest.get("http://localhost:8080/jdbc-app/persistence/create"),is("ok")); - assertThat(listClient.get("http://localhost:8080/jdbc-app/persistence/get").get(),is(JdbcEntity.class)); - - - } - - - -} diff --git a/micro-hikaricp/src/test/java/app/pure/jdbc/com/aol/micro/server/PersistentResource.java b/micro-hikaricp/src/test/java/app/pure/jdbc/com/aol/micro/server/PersistentResource.java deleted file mode 100644 index b826e9cd5..000000000 --- a/micro-hikaricp/src/test/java/app/pure/jdbc/com/aol/micro/server/PersistentResource.java +++ /dev/null @@ -1,48 +0,0 @@ -package app.pure.jdbc.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.BeanPropertyRowMapper; - -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.spring.datasource.jdbc.SQL; - -@Rest -@Path("/persistence") -public class PersistentResource { - - private final SQL dao; - - @Autowired - public PersistentResource(SQL dao) { - - this.dao = dao; - } - @GET - @Produces("text/plain") - @Path("/gen") - public String gen() { - dao.getJdbc().execute("create table t_jdbc(id bigint,name varchar(255),value varchar(255),version int);"); - - return "ok"; - } - @GET - @Produces("text/plain") - @Path("/create") - public String createEntity() { - dao.getJdbc().update("insert into t_jdbc VALUES (1,'hello','world',1)"); - - return "ok"; - } - - @GET - @Produces("application/json") - @Path("/get") - public JdbcEntity get() { - return dao.getJdbc(). queryForObject("select * from t_jdbc", new BeanPropertyRowMapper(JdbcEntity.class)); - } - -} \ No newline at end of file diff --git a/micro-hikaricp/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcEntity.java b/micro-hikaricp/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcEntity.java new file mode 100644 index 000000000..c92fd662b --- /dev/null +++ b/micro-hikaricp/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcEntity.java @@ -0,0 +1,27 @@ +package app.pure.jdbc.com.oath.micro.server; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.Builder; + + + + +@Setter +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class JdbcEntity implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + private String name; + private String value; + private int version; + + +} diff --git a/micro-hikaricp/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcRunnerTest.java b/micro-hikaricp/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcRunnerTest.java new file mode 100644 index 000000000..08c384ca7 --- /dev/null +++ b/micro-hikaricp/src/test/java/app/pure/jdbc/com/oath/micro/server/JdbcRunnerTest.java @@ -0,0 +1,56 @@ +package app.pure.jdbc.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", + "db.connection.url","jdbc:hsqldb:mem:aname", + "db.connection.username", "sa", + }) +public class JdbcRunnerTest { + + private final AsyncRestClient listClient = new AsyncRestClient(1000,1000).withResponse(JdbcEntity.class); + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer(){ + + + server = new MicroserverApp(()->"jdbc-app"); + server.start(); + rest.get("http://localhost:8080/jdbc-app/persistence/gen"); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + assertThat(rest.get("http://localhost:8080/jdbc-app/persistence/create"),is("ok")); + assertThat(listClient.get("http://localhost:8080/jdbc-app/persistence/get").get(),is(JdbcEntity.class)); + + + } + + + +} diff --git a/micro-hikaricp/src/test/java/app/pure/jdbc/com/oath/micro/server/PersistentResource.java b/micro-hikaricp/src/test/java/app/pure/jdbc/com/oath/micro/server/PersistentResource.java new file mode 100644 index 000000000..869898590 --- /dev/null +++ b/micro-hikaricp/src/test/java/app/pure/jdbc/com/oath/micro/server/PersistentResource.java @@ -0,0 +1,48 @@ +package app.pure.jdbc.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.BeanPropertyRowMapper; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.spring.datasource.jdbc.SQL; + +@Rest +@Path("/persistence") +public class PersistentResource { + + private final SQL dao; + + @Autowired + public PersistentResource(SQL dao) { + + this.dao = dao; + } + @GET + @Produces("text/plain") + @Path("/gen") + public String gen() { + dao.getJdbc().execute("create table t_jdbc(id bigint,name varchar(255),value varchar(255),version int);"); + + return "ok"; + } + @GET + @Produces("text/plain") + @Path("/create") + public String createEntity() { + dao.getJdbc().update("insert into t_jdbc VALUES (1,'hello','world',1)"); + + return "ok"; + } + + @GET + @Produces("application/json") + @Path("/get") + public JdbcEntity get() { + return dao.getJdbc(). queryForObject("select * from t_jdbc", new BeanPropertyRowMapper(JdbcEntity.class)); + } + +} \ No newline at end of file diff --git a/micro-hikaricp/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-hikaricp/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-hikaricp/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-hikaricp/src/test/java/com/aol/micro/server/HikariCPConfigTest.java b/micro-hikaricp/src/test/java/com/oath/micro/server/HikariCPConfigTest.java similarity index 85% rename from micro-hikaricp/src/test/java/com/aol/micro/server/HikariCPConfigTest.java rename to micro-hikaricp/src/test/java/com/oath/micro/server/HikariCPConfigTest.java index 6f8730511..a62aa6951 100644 --- a/micro-hikaricp/src/test/java/com/aol/micro/server/HikariCPConfigTest.java +++ b/micro-hikaricp/src/test/java/com/oath/micro/server/HikariCPConfigTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server; +package com.oath.micro.server; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; @@ -7,7 +7,7 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.spring.datasource.HikariCPConfig; +import com.oath.micro.server.spring.datasource.HikariCPConfig; public class HikariCPConfigTest { diff --git a/micro-hikaricp/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-hikaricp/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-hikaricp/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-ip-tracker/README.md b/micro-ip-tracker/README.md new file mode 100644 index 000000000..e0eed401c --- /dev/null +++ b/micro-ip-tracker/README.md @@ -0,0 +1,49 @@ +# IP Tracker Plugin + +[micro-ip-tracker example apps](https://github.com/aol/micro-server/tree/master/micro-ip-tracker/src/test/java/app) + +Capture the IP address on incoming REST Requests via a filter. + +The IP Address is stored in a thread local variable & available via QueryIPRetriever.getIPAddress(); + +```java + String ip = QueryIPRetriever.getIpAddress(); +``` + +## Configuration + +The IP Tracker will pull client IP Addresses forwarded via a vip. By default the following headers are checked + + X-LB-Client-IP + X-Forwarded-For + +To add an additional header use the property + + + load.balancer.ip.forwarding.header= + +By default all incoming requests are tracked, an array of endpoints can be speficied via the property ip.tracker.mappings + + ip.tracker.mappings=/*,/path1/* + + +## To use + +Simply add to the classpath + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-ip-tracker/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-ip-tracker) + + + + +### Maven + + + com.oath.microservices + micro-ip-tracker + x.yx + + +### Gradle + + compile 'com.oath.microservices:micro-ip-tracker:x.yz' diff --git a/micro-ip-tracker/build.gradle b/micro-ip-tracker/build.gradle index 1145369de..597aeebe8 100644 --- a/micro-ip-tracker/build.gradle +++ b/micro-ip-tracker/build.gradle @@ -1,58 +1,58 @@ description = 'micro-ip-tracker' + dependencies { - - compile project(':micro-core') - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') - testCompile project(':micro-jackson-configuration') + compile project(':micro-core') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') + testCompile project(':micro-jackson-configuration') } modifyPom { - project { - name 'Microserver ip tracker' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-ip-tracker' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - } - - } + project { + name 'Microserver ip tracker' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-ip-tracker' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-ip-tracker/readme.md b/micro-ip-tracker/readme.md deleted file mode 100644 index cd76e047a..000000000 --- a/micro-ip-tracker/readme.md +++ /dev/null @@ -1,49 +0,0 @@ -# IP Tracker Plugin - -[micro-ip-tracker example apps](https://github.com/aol/micro-server/tree/master/micro-ip-tracker/src/test/java/app) - -Capture the IP address on incoming REST Requests via a filter. - -The IP Address is stored in a thread local variable & available via QueryIPRetriever.getIPAddress(); - -```java - String ip = QueryIPRetriever.getIpAddress(); -``` - -## Configuration - -The IP Tracker will pull client IP Addresses forwarded via a vip. By default the following headers are checked - - X-LB-Client-IP - X-Forwarded-For - -To add an additional header use the property - - - load.balancer.ip.forwarding.header= - -By default all incoming requests are tracked, an array of endpoints can be speficied via the property ip.tracker.mappings - - ip.tracker.mappings=/*,/path1/* - - -## To use - -Simply add to the classpath - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-ip-tracker/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-ip-tracker) - - - - -### Maven - - - com.aol.microservices - micro-ip-tracker - x.yx - - -### Gradle - - compile 'com.aol.microservices:micro-ip-tracker:x.yz' diff --git a/micro-ip-tracker/src/main/java/com/aol/micro/server/ip/tracker/IPTrackerPlugin.java b/micro-ip-tracker/src/main/java/com/aol/micro/server/ip/tracker/IPTrackerPlugin.java deleted file mode 100644 index cde7587bc..000000000 --- a/micro-ip-tracker/src/main/java/com/aol/micro/server/ip/tracker/IPTrackerPlugin.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.aol.micro.server.ip.tracker; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; - - - - -public class IPTrackerPlugin implements Plugin{ - - @Override - public PSetX springClasses() { - return PSetX.of(QueryIPRetriever.class); - - } - - - - -} diff --git a/micro-ip-tracker/src/main/java/com/oath/micro/server/ip/tracker/BeanConfiguration.java b/micro-ip-tracker/src/main/java/com/oath/micro/server/ip/tracker/BeanConfiguration.java new file mode 100644 index 000000000..645d08396 --- /dev/null +++ b/micro-ip-tracker/src/main/java/com/oath/micro/server/ip/tracker/BeanConfiguration.java @@ -0,0 +1,36 @@ +package com.oath.micro.server.ip.tracker; + +import javax.servlet.Filter; + +import cyclops.control.Either; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +import com.oath.micro.server.auto.discovery.FilterConfiguration; + +@Configuration +public class BeanConfiguration { + @Value("${load.balancer.ip.forwarding.header:X-LB-Client-IP}") + String ipForwardingHeaderValue; + @Value("${ip.tracker.mappings:/*}") + String[] mappingsValue; + + @Bean + public FilterConfiguration ipTracker(){ + return new FilterConfiguration(){ + + @Override + public String[] getMapping() { + return mappingsValue; + } + + @Override + public Either, Filter> getFilter() { + return Either.right(new QueryIPRetriever(ipForwardingHeaderValue, mappingsValue)); + } + + }; + } +} diff --git a/micro-ip-tracker/src/main/java/com/oath/micro/server/ip/tracker/IPTrackerPlugin.java b/micro-ip-tracker/src/main/java/com/oath/micro/server/ip/tracker/IPTrackerPlugin.java new file mode 100644 index 000000000..36b2d2ab0 --- /dev/null +++ b/micro-ip-tracker/src/main/java/com/oath/micro/server/ip/tracker/IPTrackerPlugin.java @@ -0,0 +1,20 @@ +package com.oath.micro.server.ip.tracker; + +import com.oath.micro.server.Plugin; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + + +public class IPTrackerPlugin implements Plugin{ + + @Override + public Set springClasses() { + return SetX.of(BeanConfiguration.class); + + } + + + + +} diff --git a/micro-ip-tracker/src/main/java/com/aol/micro/server/ip/tracker/QueryIPRetriever.java b/micro-ip-tracker/src/main/java/com/oath/micro/server/ip/tracker/QueryIPRetriever.java similarity index 80% rename from micro-ip-tracker/src/main/java/com/aol/micro/server/ip/tracker/QueryIPRetriever.java rename to micro-ip-tracker/src/main/java/com/oath/micro/server/ip/tracker/QueryIPRetriever.java index a60c4a855..3a2a3657d 100644 --- a/micro-ip-tracker/src/main/java/com/aol/micro/server/ip/tracker/QueryIPRetriever.java +++ b/micro-ip-tracker/src/main/java/com/oath/micro/server/ip/tracker/QueryIPRetriever.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.ip.tracker; +package com.oath.micro.server.ip.tracker; import java.io.IOException; import java.util.Optional; @@ -13,27 +13,23 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; -import com.aol.micro.server.auto.discovery.FilterConfiguration; - @Component -public class QueryIPRetriever implements FilterConfiguration,Filter { +public class QueryIPRetriever implements Filter { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private static String ipForwardingHeader; + private String ipForwardingHeader; + + private String[] mappings; - private static String[] mappings; - @Autowired - public QueryIPRetriever(@Value("${load.balancer.ip.forwarding.header:X-LB-Client-IP}") String ipForwardingHeaderValue, - @Value("${ip.tracker.mappings:/*}") String[] mappingsValue){ + public QueryIPRetriever(String ipForwardingHeaderValue, + String[] mappingsValue){ ipForwardingHeader = ipForwardingHeaderValue; mappings = mappingsValue; } @@ -103,11 +99,7 @@ private boolean isBlank(final String str) { return true; } - @Override - public String[] getMapping() { - return mappings; - } - + @Override public void init(FilterConfig filterConfig) throws ServletException { diff --git a/micro-ip-tracker/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-ip-tracker/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 2656b2d58..000000000 --- a/micro-ip-tracker/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.ip.tracker.IPTrackerPlugin \ No newline at end of file diff --git a/micro-ip-tracker/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-ip-tracker/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..a200a6cb9 --- /dev/null +++ b/micro-ip-tracker/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.ip.tracker.IPTrackerPlugin \ No newline at end of file diff --git a/micro-ip-tracker/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java b/micro-ip-tracker/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java deleted file mode 100644 index 700a2c778..000000000 --- a/micro-ip-tracker/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java +++ /dev/null @@ -1,18 +0,0 @@ -package app.simple.com.aol.micro.server; - -import java.util.Arrays; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; - -public class SimpleApp { - - public static void main(String[] args){ - - new MicroserverApp(()-> "simple-app").run(); - } - - -} diff --git a/micro-ip-tracker/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java b/micro-ip-tracker/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java deleted file mode 100644 index f18021199..000000000 --- a/micro-ip-tracker/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.simple.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class SimpleRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("127.0.0.1")); - - - } - - - -} diff --git a/micro-ip-tracker/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java b/micro-ip-tracker/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java deleted file mode 100644 index 9966694cb..000000000 --- a/micro-ip-tracker/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java +++ /dev/null @@ -1,40 +0,0 @@ -package app.simple.com.aol.micro.server; - -import java.io.InputStream; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; -import org.glassfish.jersey.media.multipart.FormDataParam; - -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.ip.tracker.QueryIPRetriever; - -@Rest -@Path("/status") -public class SimpleStatusResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return QueryIPRetriever.getIpAddress(); - } - - @POST - @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces(MediaType.TEXT_PLAIN) - @Path("/file") - public String create( - @FormDataParam("file") InputStream fileInputStream, - @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { - - return "done"; - } -} \ No newline at end of file diff --git a/micro-ip-tracker/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java b/micro-ip-tracker/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java new file mode 100644 index 000000000..e82a92291 --- /dev/null +++ b/micro-ip-tracker/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java @@ -0,0 +1,13 @@ +package app.simple.com.oath.micro.server; + +import com.oath.micro.server.MicroserverApp; + +public class SimpleApp { + + public static void main(String[] args){ + + new MicroserverApp(()-> "simple-app").run(); + } + + +} diff --git a/micro-ip-tracker/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java b/micro-ip-tracker/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java new file mode 100644 index 000000000..f3bc236b5 --- /dev/null +++ b/micro-ip-tracker/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java @@ -0,0 +1,55 @@ +package app.simple.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class SimpleRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("127.0.0.1")); + + + } + + + +} diff --git a/micro-ip-tracker/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java b/micro-ip-tracker/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java new file mode 100644 index 000000000..01a9fb88a --- /dev/null +++ b/micro-ip-tracker/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java @@ -0,0 +1,40 @@ +package app.simple.com.oath.micro.server; + +import java.io.InputStream; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.ip.tracker.QueryIPRetriever; + +@Rest +@Path("/status") +public class SimpleStatusResource { + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + return QueryIPRetriever.getIpAddress(); + } + + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.TEXT_PLAIN) + @Path("/file") + public String create( + @FormDataParam("file") InputStream fileInputStream, + @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { + + return "done"; + } +} \ No newline at end of file diff --git a/micro-ip-tracker/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-ip-tracker/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-ip-tracker/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-ip-tracker/src/test/java/com/aol/micro/server/ip/tracker/QueryIPRetrieverTest.java b/micro-ip-tracker/src/test/java/com/oath/micro/server/ip/tracker/QueryIPRetrieverTest.java similarity index 99% rename from micro-ip-tracker/src/test/java/com/aol/micro/server/ip/tracker/QueryIPRetrieverTest.java rename to micro-ip-tracker/src/test/java/com/oath/micro/server/ip/tracker/QueryIPRetrieverTest.java index f58e2783a..0cbacb997 100644 --- a/micro-ip-tracker/src/test/java/com/aol/micro/server/ip/tracker/QueryIPRetrieverTest.java +++ b/micro-ip-tracker/src/test/java/com/oath/micro/server/ip/tracker/QueryIPRetrieverTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.ip.tracker; +package com.oath.micro.server.ip.tracker; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; diff --git a/micro-ip-tracker/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-ip-tracker/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-ip-tracker/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-jackson-configuration/README.md b/micro-jackson-configuration/README.md new file mode 100644 index 000000000..178c49cc3 --- /dev/null +++ b/micro-jackson-configuration/README.md @@ -0,0 +1,60 @@ +# Jackson & Jackons Configuration Plugin + +[micro-jackson-configuration example apps](https://github.com/aol/micro-server/tree/master/micro-grizzly/src/test/java/app/jackson) + + +Add Jackson Serialization to Microserver apps & add custom configurations as neccessary. + +Includes serializers and deserializers for pCollections. + +## Configurable Properties + +properties = default + + +jackons.seriliazation=NON_NULL + + +## Creating your own configuration extensions bean + +To customize your Jackson configuration create a Spring bean that implements com.aol.micro.server.jackson.JacksonMapperConfigurator, it accepts the Jackson Mapper as it is being built. + +For example to set Fail on Null For Primitives (or any other Serialization / Deserialization setting) + +```java + +@Component +public class MapperExtension implements JacksonMapperConfigurator { + + @Override + public void accept(ObjectMapper t) { + t.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true); + + } + +} + +``` + +## NB Custom Jackson Configuration inside a Spring Context + +Custom extensions are only guaranteed to be available once the configurations have run inside a Spring context. I.e. - to use custom extensions with AsyncRestClient or RestClient in micro-client, please create instances as Spring Beans (or at least don't instantiate your instances until Spring has completed initialisation). (Default configuration will be available via the new keyword). + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-jackson-configuration/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-jackson-configuration) + +Simply add to the classpath + +Maven +```xml + + com.oath.microservices + micro-jackson-configuration + x.yz + +`` +Gradle +```groovy + compile 'com.oath.microservices:micro-jackson-configuration:x.yz' +``` diff --git a/micro-jackson-configuration/build.gradle b/micro-jackson-configuration/build.gradle index b59394f63..2edaaa295 100644 --- a/micro-jackson-configuration/build.gradle +++ b/micro-jackson-configuration/build.gradle @@ -1,55 +1,56 @@ description = 'micro-jackson-configuration' + dependencies { - compile project(':micro-core') - + compile project(':micro-core') + compile("com.oath.cyclops:cyclops-jackson-integration:$cyclopsVersion") } modifyPom { - project { - name 'Microserver Jackson Configuration' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-jackson-configuration' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - } - - } + project { + name 'Microserver Jackson Configuration' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-jackson-configuration' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-jackson-configuration/readme.md b/micro-jackson-configuration/readme.md deleted file mode 100644 index 1927b1605..000000000 --- a/micro-jackson-configuration/readme.md +++ /dev/null @@ -1,58 +0,0 @@ -# Jackson & Jackons Configuration Plugin - -[micro-jackson-configuration example apps](https://github.com/aol/micro-server/tree/master/micro-grizzly/src/test/java/app/jackson) - - -Add Jackson Serialization to Microserver apps & add custom configurations as neccessary. - -## Configurable Properties - -properties = default - - -jackons.seriliazation=NON_NULL - - -## Creating your own configuration extensions bean - -To customize your Jackson configuration create a Spring bean that implements com.aol.micro.server.jackson.JacksonMapperConfigurator, it accepts the Jackson Mapper as it is being built. - -For example to set Fail on Null For Primitives (or any other Serialization / Deserialization setting) - -```java - -@Component -public class MapperExtension implements JacksonMapperConfigurator { - - @Override - public void accept(ObjectMapper t) { - t.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true); - - } - -} - -``` - -## NB Custom Jackson Configuration inside a Spring Context - -Custom extensions are only guaranteed to be available once the configurations have run inside a Spring context. I.e. - to use custom extensions with AsyncRestClient or RestClient in micro-client, please create instances as Spring Beans (or at least don't instantiate your instances until Spring has completed initialisation). (Default configuration will be available via the new keyword). - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-jackson-configuration/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-jackson-configuration) - -Simply add to the classpath - -Maven -```xml - - com.aol.microservices - micro-jackson-configuration - x.yz - -`` -Gradle -```groovy - compile 'com.aol.microservices:micro-jackson-configuration:x.yz' -``` diff --git a/micro-jackson-configuration/src/main/java/com/aol/micro/server/jackson/JacksonPlugin.java b/micro-jackson-configuration/src/main/java/com/aol/micro/server/jackson/JacksonPlugin.java deleted file mode 100644 index 619484bb8..000000000 --- a/micro-jackson-configuration/src/main/java/com/aol/micro/server/jackson/JacksonPlugin.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.aol.micro.server.jackson; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.rest.jackson.JacksonFeature; - -public class JacksonPlugin implements Plugin { - - @Override - public PSetX> jaxRsResources() { - - return PSetX.of(JacksonFeature.class); - - } - - @Override - public PSetX springClasses() { - - return PSetX.of(CoreJacksonConfigurator.class,JacksonConfigurers.class); - - } - -} diff --git a/micro-jackson-configuration/src/main/java/com/aol/micro/server/jackson/CoreJacksonConfigurator.java b/micro-jackson-configuration/src/main/java/com/oath/micro/server/jackson/CoreJacksonConfigurator.java similarity index 86% rename from micro-jackson-configuration/src/main/java/com/aol/micro/server/jackson/CoreJacksonConfigurator.java rename to micro-jackson-configuration/src/main/java/com/oath/micro/server/jackson/CoreJacksonConfigurator.java index 51a96f625..ba5f7300d 100644 --- a/micro-jackson-configuration/src/main/java/com/aol/micro/server/jackson/CoreJacksonConfigurator.java +++ b/micro-jackson-configuration/src/main/java/com/oath/micro/server/jackson/CoreJacksonConfigurator.java @@ -1,13 +1,13 @@ -package com.aol.micro.server.jackson; +package com.oath.micro.server.jackson; import java.util.Optional; +import com.oath.cyclops.jackson.CyclopsModule; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.micro.server.PluginLoader; +import com.oath.micro.server.PluginLoader; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; @@ -33,6 +33,7 @@ public void accept(ObjectMapper mapper) { .forEach(m -> mapper.registerModule(m)); mapper.registerModule(new Jdk8Module()); + mapper.registerModule(new CyclopsModule()); } } diff --git a/micro-jackson-configuration/src/main/java/com/aol/micro/server/jackson/JacksonConfigurers.java b/micro-jackson-configuration/src/main/java/com/oath/micro/server/jackson/JacksonConfigurers.java similarity index 84% rename from micro-jackson-configuration/src/main/java/com/aol/micro/server/jackson/JacksonConfigurers.java rename to micro-jackson-configuration/src/main/java/com/oath/micro/server/jackson/JacksonConfigurers.java index da9eaf097..b4f22b3ea 100644 --- a/micro-jackson-configuration/src/main/java/com/aol/micro/server/jackson/JacksonConfigurers.java +++ b/micro-jackson-configuration/src/main/java/com/oath/micro/server/jackson/JacksonConfigurers.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.jackson; +package com.oath.micro.server.jackson; import java.util.List; @@ -7,7 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.aol.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.rest.jackson.JacksonUtil; @Component public class JacksonConfigurers { diff --git a/micro-jackson-configuration/src/main/java/com/aol/micro/server/jackson/JacksonMapperConfigurator.java b/micro-jackson-configuration/src/main/java/com/oath/micro/server/jackson/JacksonMapperConfigurator.java similarity index 81% rename from micro-jackson-configuration/src/main/java/com/aol/micro/server/jackson/JacksonMapperConfigurator.java rename to micro-jackson-configuration/src/main/java/com/oath/micro/server/jackson/JacksonMapperConfigurator.java index 09cf69177..261cc59d5 100644 --- a/micro-jackson-configuration/src/main/java/com/aol/micro/server/jackson/JacksonMapperConfigurator.java +++ b/micro-jackson-configuration/src/main/java/com/oath/micro/server/jackson/JacksonMapperConfigurator.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.jackson; +package com.oath.micro.server.jackson; import java.util.function.Consumer; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/micro-jackson-configuration/src/main/java/com/oath/micro/server/jackson/JacksonPlugin.java b/micro-jackson-configuration/src/main/java/com/oath/micro/server/jackson/JacksonPlugin.java new file mode 100644 index 000000000..9b4f8c23d --- /dev/null +++ b/micro-jackson-configuration/src/main/java/com/oath/micro/server/jackson/JacksonPlugin.java @@ -0,0 +1,31 @@ +package com.oath.micro.server.jackson; + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.rest.jackson.JacksonFeature; +import com.fasterxml.jackson.databind.Module; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +public class JacksonPlugin implements Plugin { + + @Override + public Set> jaxRsResources() { + + return SetX.of(JacksonFeature.class); + + } + + @Override + public Set springClasses() { + + return SetX.of(CoreJacksonConfigurator.class, JacksonConfigurers.class); + + } + + @Override + public Set jacksonModules() { + return SetX.of(); + } + +} diff --git a/micro-jackson-configuration/src/main/java/com/aol/micro/server/rest/jackson/JacksonFeature.java b/micro-jackson-configuration/src/main/java/com/oath/micro/server/rest/jackson/JacksonFeature.java similarity index 86% rename from micro-jackson-configuration/src/main/java/com/aol/micro/server/rest/jackson/JacksonFeature.java rename to micro-jackson-configuration/src/main/java/com/oath/micro/server/rest/jackson/JacksonFeature.java index e71ddf93f..c3f932723 100644 --- a/micro-jackson-configuration/src/main/java/com/aol/micro/server/rest/jackson/JacksonFeature.java +++ b/micro-jackson-configuration/src/main/java/com/oath/micro/server/rest/jackson/JacksonFeature.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.rest.jackson; +package com.oath.micro.server.rest.jackson; import java.util.Map; @@ -7,9 +7,8 @@ import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.MessageBodyWriter; -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.PluginLoader; +import com.oath.micro.server.Plugin; +import com.oath.micro.server.PluginLoader; import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; diff --git a/micro-jackson-configuration/src/main/java/com/aol/micro/server/rest/jackson/JacksonUtil.java b/micro-jackson-configuration/src/main/java/com/oath/micro/server/rest/jackson/JacksonUtil.java similarity index 81% rename from micro-jackson-configuration/src/main/java/com/aol/micro/server/rest/jackson/JacksonUtil.java rename to micro-jackson-configuration/src/main/java/com/oath/micro/server/rest/jackson/JacksonUtil.java index 6feb1b43d..9694820b8 100644 --- a/micro-jackson-configuration/src/main/java/com/aol/micro/server/rest/jackson/JacksonUtil.java +++ b/micro-jackson-configuration/src/main/java/com/oath/micro/server/rest/jackson/JacksonUtil.java @@ -1,20 +1,21 @@ -package com.aol.micro.server.rest.jackson; +package com.oath.micro.server.rest.jackson; import java.util.Arrays; import java.util.List; import java.util.Optional; +import com.oath.cyclops.util.ExceptionSoftener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.aol.cyclops.control.AnyM; -import com.aol.cyclops.util.ExceptionSoftener; -import com.aol.micro.server.jackson.CoreJacksonConfigurator; -import com.aol.micro.server.jackson.JacksonMapperConfigurator; + +import com.oath.micro.server.jackson.CoreJacksonConfigurator; +import com.oath.micro.server.jackson.JacksonMapperConfigurator; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.type.TypeReference; public final class JacksonUtil { @@ -94,6 +95,15 @@ public static T convertFromJson(final String jsonString, final JavaType type return null; } + + public static T convertFromJson(String json, final TypeReference type) { + try { + return JacksonUtil.getMapper().readValue(json, type); + } catch (final Exception ex) { + ExceptionSoftener.throwSoftenedException(ex); + } + return null; + } public static Object serializeToJsonLogFailure(Object value) { try { diff --git a/micro-jackson-configuration/src/main/java/com/aol/micro/server/rest/providers/ObjectMapperProvider.java b/micro-jackson-configuration/src/main/java/com/oath/micro/server/rest/providers/ObjectMapperProvider.java similarity index 80% rename from micro-jackson-configuration/src/main/java/com/aol/micro/server/rest/providers/ObjectMapperProvider.java rename to micro-jackson-configuration/src/main/java/com/oath/micro/server/rest/providers/ObjectMapperProvider.java index 3cd259af2..acd8e858f 100644 --- a/micro-jackson-configuration/src/main/java/com/aol/micro/server/rest/providers/ObjectMapperProvider.java +++ b/micro-jackson-configuration/src/main/java/com/oath/micro/server/rest/providers/ObjectMapperProvider.java @@ -1,11 +1,11 @@ -package com.aol.micro.server.rest.providers; +package com.oath.micro.server.rest.providers; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; -import com.aol.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.rest.jackson.JacksonUtil; import com.fasterxml.jackson.databind.ObjectMapper; @Provider diff --git a/micro-jackson-configuration/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-jackson-configuration/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 6d7a2d9d5..000000000 --- a/micro-jackson-configuration/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.jackson.JacksonPlugin \ No newline at end of file diff --git a/micro-jackson-configuration/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-jackson-configuration/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..e17965f72 --- /dev/null +++ b/micro-jackson-configuration/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.jackson.JacksonPlugin \ No newline at end of file diff --git a/micro-jackson-configuration/src/test/java/com/aol/micro/server/rest/JacksonUtilTest.java b/micro-jackson-configuration/src/test/java/com/aol/micro/server/rest/JacksonUtilTest.java deleted file mode 100644 index 9451f895b..000000000 --- a/micro-jackson-configuration/src/test/java/com/aol/micro/server/rest/JacksonUtilTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.aol.micro.server.rest; - - -import static junit.framework.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.Getter; -import lombok.Setter; - -import org.junit.Test; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - - -public class JacksonUtilTest { - - - @Test - public void generateSampleRequest() { - - DummyQueryRequest request = new DummyQueryRequest(); - request.getData().add("blah"); - - assertTrue(JacksonUtil.serializeToJson(request).contains("strData")); - - } - - - @Test - public void serialiseAndDeserialise(){ - DummyQueryRequest request = new DummyQueryRequest(); - request.getData().add("blah"); - String requestStr = (String) JacksonUtil.serializeToJsonLogFailure(request); - DummyQueryRequest requestDeserialised = JacksonUtil.convertFromJson(requestStr, DummyQueryRequest.class); - assertTrue(request.getData().contains("blah")); - } - - -} - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlRootElement(name = "queryRequest") -@XmlType(name = "") -class DummyQueryRequest { - - @XmlElement(name = "strData") - @Getter - @Setter - private List data = new ArrayList(); - - -} - diff --git a/micro-jackson-configuration/src/test/java/com/aol/micro/server/rest/MyEntity.java b/micro-jackson-configuration/src/test/java/com/aol/micro/server/rest/MyEntity.java deleted file mode 100644 index b6a7a0ec7..000000000 --- a/micro-jackson-configuration/src/test/java/com/aol/micro/server/rest/MyEntity.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.aol.micro.server.rest; - -import lombok.EqualsAndHashCode; -import lombok.Getter; - -@EqualsAndHashCode -@Getter -public class MyEntity { - - private final String name ="myEntity"; - -} diff --git a/micro-jackson-configuration/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-jackson-configuration/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index 99c4717a1..000000000 --- a/micro-jackson-configuration/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.aol.micro.server.testing; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - public Response postString(String url, String payload) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(payload,MediaType.APPLICATION_JSON)); - } - - -} diff --git a/micro-jackson-configuration/src/test/java/com/oath/micro/server/rest/JacksonUtilTest.java b/micro-jackson-configuration/src/test/java/com/oath/micro/server/rest/JacksonUtilTest.java new file mode 100644 index 000000000..fd66ec7f4 --- /dev/null +++ b/micro-jackson-configuration/src/test/java/com/oath/micro/server/rest/JacksonUtilTest.java @@ -0,0 +1,76 @@ +package com.oath.micro.server.rest; + +import static junit.framework.Assert.assertTrue; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import cyclops.reactive.collections.immutable.LinkedListX; +import cyclops.data.Seq; +import org.junit.Ignore; +import org.junit.Test; + + + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +import lombok.Getter; +import lombok.Setter; + +public class JacksonUtilTest { + + @Test + public void generateSampleRequest() { + + DummyQueryRequest request = new DummyQueryRequest(); + request.getData() + .add("blah"); + + assertTrue(JacksonUtil.serializeToJson(request) + .contains("strData")); + + } + + @Test + public void serialiseAndDeserialise() { + DummyQueryRequest request = new DummyQueryRequest(); + request.getData() + .add("blah"); + String requestStr = (String) JacksonUtil.serializeToJsonLogFailure(request); + DummyQueryRequest requestDeserialised = JacksonUtil.convertFromJson(requestStr, DummyQueryRequest.class); + assertTrue(request.getData() + .contains("blah")); + } + + @Test + public void serializeToPersistentList() { + + LinkedListX list = LinkedListX.of(1, 2, 3, 4); + String jsonString = JacksonUtil.serializeToJson(list); + + Seq stack = JacksonUtil.convertFromJson(jsonString, Seq.class); + + assertThat(stack, equalTo(list)); + } + +} + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "queryRequest") +@XmlType(name = "") +class DummyQueryRequest { + + @XmlElement(name = "strData") + @Getter + @Setter + private List data = new ArrayList(); + +} diff --git a/micro-jackson-configuration/src/test/java/com/oath/micro/server/rest/MyEntity.java b/micro-jackson-configuration/src/test/java/com/oath/micro/server/rest/MyEntity.java new file mode 100644 index 000000000..c691212ff --- /dev/null +++ b/micro-jackson-configuration/src/test/java/com/oath/micro/server/rest/MyEntity.java @@ -0,0 +1,12 @@ +package com.oath.micro.server.rest; + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@EqualsAndHashCode +@Getter +public class MyEntity { + + private final String name ="myEntity"; + +} diff --git a/micro-jackson-configuration/src/test/java/com/aol/micro/server/rest/providers/ObjectMapperProviderTest.java b/micro-jackson-configuration/src/test/java/com/oath/micro/server/rest/providers/ObjectMapperProviderTest.java similarity index 80% rename from micro-jackson-configuration/src/test/java/com/aol/micro/server/rest/providers/ObjectMapperProviderTest.java rename to micro-jackson-configuration/src/test/java/com/oath/micro/server/rest/providers/ObjectMapperProviderTest.java index de29bb468..0edc72365 100644 --- a/micro-jackson-configuration/src/test/java/com/aol/micro/server/rest/providers/ObjectMapperProviderTest.java +++ b/micro-jackson-configuration/src/test/java/com/oath/micro/server/rest/providers/ObjectMapperProviderTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.rest.providers; +package com.oath.micro.server.rest.providers; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -6,7 +6,7 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.rest.jackson.JacksonUtil; public class ObjectMapperProviderTest { diff --git a/micro-jackson-configuration/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-jackson-configuration/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..adf56edef --- /dev/null +++ b/micro-jackson-configuration/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,64 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + public Response postString(String url, String payload) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(payload,MediaType.APPLICATION_JSON)); + } + + +} diff --git a/micro-javaslang/build.gradle b/micro-javaslang/build.gradle deleted file mode 100644 index a3f9a93d4..000000000 --- a/micro-javaslang/build.gradle +++ /dev/null @@ -1,66 +0,0 @@ -repositories { - mavenCentral() - -} -description = 'micro-javaslang' -dependencies { - - compile 'com.aol.cyclops:cyclops-javaslang:'+cyclopsVersion - compile project(':micro-jackson-configuration') - compile "io.javaslang:javaslang-jackson:$javaslangDatatypeVersion" - compile project(':micro-core') - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') - -} - - -modifyPom { - project { - name 'Microserver javaslang' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-javaslang' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - } - - } -} - -extraArchive { - sources = true - tests = true - javadoc = true -} - -nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' -} - diff --git a/micro-javaslang/readme.md b/micro-javaslang/readme.md deleted file mode 100644 index 5a0d8b83a..000000000 --- a/micro-javaslang/readme.md +++ /dev/null @@ -1,196 +0,0 @@ -# Javaslang Plugin for Microserver - -[micro-javaslang example apps](https://github.com/aol/micro-server/tree/master/micro-javaslang/src/test/java/app) - -This plugin - -1. Configures Jackson for Javaslang serialisation / deserialisation, so Javaslang types can be used as input and output to jax-rs Resources -2. Add cyclops-javaslang to your project which enables conversion between JDK / Javaslang / Guava / Jool / simple-react types and adds features such as for-comprehensions to Javaslang. -3. Integrates with micro-client, Rest clients (RestClient, AsyncRestClient and NIORestClient) automatically pick up Javaslang mappings -4. Adds some reactive programming support for Javaslang Streams namely - a. JavaslangReactive mixin allows creating Javaslang reactive-streams Publishers and Subsribers simple - b. JavaslangPipes and JavaslangReactive provide integration with simple-react - c. Ability to push data into a Javaslang Stream across threads via JavaslangPipes - - - - -## To use - -Simply add this plugin to the classpath - do remember to also add a Server and jax-rs provider (adding micro-grizzly-with-jersey to your classpath too - is a good bet!) - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-javaslang/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-javaslang) - -Maven - - - com.aol.microservices - micro-javaslang - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-javaslang:x.yz' - -## Depends on - -micro-jackson-configuration -micro-core - -## Examples - -### JavaslangPipes - - ```java - - Queue queue = QueueFactories.boundedNonBlockingQueue(1000); //set up an Agrona backed wait-free queue - queue.add("world"); //add some data to the queue - JavaslangPipes.register("myQueue",queue); //register the queue - - //on a separate thread process data streaming from the queue - JavaslangPipes.stream("myQueue") - .map(this:process) - .forEach(this:save); - -``` - -### Simple App with Javaslang Lists and Sets - - ```java -@Microserver -@Path("/javaslang") -@Rest -public class JavaslangApp { - - - public static void main(String[] args){ - new MicroserverApp(() -> "javaslang-app").start(); - - } - - - @GET - @Produces("application/json") - @Path("/ping") - public ImmutableJavaslangEntity ping() { - return ImmutableJavaslangEntity.builder().value("value") - .list(List.ofAll("hello", "world")) - .mapOfSets(HashMap.empty().put("key1",HashSet.ofAll(Arrays.asList(1, 2, 3)))) - .build(); - } - - - @XmlAccessorType(XmlAccessType.FIELD) - @XmlType(name = "") - @XmlRootElement(name = "immutable") - @Getter - @AllArgsConstructor - @Builder - public static class ImmutableJavaslangEntity { - - private final String value; - private final List list; - private final Map mapOfSets; - - - public ImmutableJavaslangEntity() { - this(null,null,null); - } - - } - -} -``` - -Running the app and browsing to http://localhost:8080/javaslang-app/javaslang/ping - - ```json -{ - "value": "value", - "list": [ - "hello", - "world" - ], - "mapOfSets": { - "key1": [ - 1, - 2, - 3 - ] - } -} - ``` - -### for-comprehension example - - Javaslang List and JDK8 CompletableFuture - - ```java - public void cfList(){ - - CompletableFuture future = CompletableFuture.supplyAsync(this::loadData); - CompletableFuture> results1 = Do.add(future) - .add(List.of("first","second")) - .yield( loadedData -> localData-> loadedData + ":" + localData ) - .unwrap(); - - System.out.println(results1.join()); - - } - private String loadData(){ - return "loaded"; - } - ``` - -### reactive-streams publisher example - - ```java -public class ReactiveStreamsPublisherTest implements JavaslangReactive { - - @Test - public void publish(){ - - Stream javaslangStream = this.publish(LazyFutureStream.of(1,2,3)); - - assertThat(javaslangStream.toList(),equalTo(List.ofAll(1,2,3))); - } -} - ``` - -### reactive-streams subscriber example - -```java - public class ReactiveStreamsSubscriberTest implements JavaslangReactive { - - - @Test - public void subscribe(){ - Stream stream = Stream.ofAll(1,2,3); - CyclopsSubscriber sub = SequenceM.subscriber(); - this.subsribe(stream, sub); - - assertThat(sub.sequenceM().toList(),equalTo(Arrays.asList(1,2,3))); - } -} - ``` - -### reactive-streams subscriber example on a separate thread - - - ```java - public class ReactiveStreamsAsyncSubscriberTest implements JavaslangReactive { - - - - @Test - public void subscribeAsync(){ - Stream stream = Stream.ofAll(1,2,3); - CyclopsSubscriber sub = SequenceM.subscriber(); - this.subsribe(stream, sub,Executors.newFixedThreadPool(1)); - - assertThat(sub.sequenceM().toList(),equalTo(Arrays.asList(1,2,3))); - } -} -``` - diff --git a/micro-javaslang/src/main/java/com/aol/micro/server/javaslang/JavaslangPlugin.java b/micro-javaslang/src/main/java/com/aol/micro/server/javaslang/JavaslangPlugin.java deleted file mode 100644 index 4ae97eb81..000000000 --- a/micro-javaslang/src/main/java/com/aol/micro/server/javaslang/JavaslangPlugin.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.aol.micro.server.javaslang; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.fasterxml.jackson.databind.Module; - -import javaslang.jackson.datatype.JavaslangModule; - -/** - * - * Collections of Spring configuration classes (Classes annotated with @Configuration) - * that configure various useful pieces of functionality - such as property file loading, - * datasources, scheduling etc - * - * @author johnmcclean - * - */ -public class JavaslangPlugin implements Plugin{ - - - @Override - public PSetX jacksonModules(){ - return PSetX.of(new JavaslangModule()); - } - - - -} diff --git a/micro-javaslang/src/main/java/com/aol/micro/server/javaslang/reactive/JavaslangReactive.java b/micro-javaslang/src/main/java/com/aol/micro/server/javaslang/reactive/JavaslangReactive.java deleted file mode 100644 index d6f72c1ee..000000000 --- a/micro-javaslang/src/main/java/com/aol/micro/server/javaslang/reactive/JavaslangReactive.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.aol.micro.server.javaslang.reactive; - - -import org.reactivestreams.Publisher; -import org.reactivestreams.Subscriber; - -import com.aol.cyclops.control.LazyReact; -import com.aol.cyclops.javaslang.Javaslang; -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.cyclops.types.stream.reactive.SeqSubscriber; - -import javaslang.Value; -import javaslang.collection.Stream; -import javaslang.collection.Traversable; - -/** - * Mixin / Trait for Reactive behaviour via simple-react - * - * @author johnmcclean - * - */ -public class JavaslangReactive { - - - - static LazyFutureStream futureStream(Traversable seq, LazyReact lazyReact){ - return lazyReact.fromIterable(seq); - } - - - - /** - * Publish a reactive-streams publisher to a new Javaslang Stream - * - * @param publisher to publish - * @return Stream subscribed to publisher - */ - public static Stream publishStream(Publisher publisher){ - SeqSubscriber sub= SeqSubscriber.subscriber(); - publisher.subscribe(sub); - return Stream.ofAll(sub.stream()); - } - public static void subsribeToValue(Value s, Subscriber sub){ - Javaslang.value(s).subscribe(sub); - - } - /** - * Have a reactive-stream subscriber subscribe to a Javaslang Stream. - * - * @param s Stream to subscribe to - * @param sub Subscriber - */ - public static void subsribeToTraversable(Traversable s, Subscriber sub){ - Javaslang.traversable(s).subscribe(sub); - - } - -} diff --git a/micro-javaslang/src/main/java/com/aol/micro/server/javaslang/reactive/JavaslangSubscriber.java b/micro-javaslang/src/main/java/com/aol/micro/server/javaslang/reactive/JavaslangSubscriber.java deleted file mode 100644 index cf819ac12..000000000 --- a/micro-javaslang/src/main/java/com/aol/micro/server/javaslang/reactive/JavaslangSubscriber.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.aol.micro.server.javaslang.reactive; - -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; - -import com.aol.cyclops.types.stream.reactive.SeqSubscriber; - -import javaslang.collection.Array; -import javaslang.collection.HashSet; -import javaslang.collection.List; -import javaslang.collection.Set; -import javaslang.collection.Stream; - -public class JavaslangSubscriber implements Subscriber{ - /** - * A reactive-streams subscriber than can generate Javaslang traversable types - * - * @return JavaslangSubscriber - */ - public static JavaslangSubscriber subscriber(){ - return new JavaslangSubscriber(); - } - SeqSubscriber sub = SeqSubscriber.subscriber(); - - - public Stream stream(){ - return Stream.ofAll(sub.stream()); - } - public List list(){ - return List.ofAll(sub.stream()); - } - public Array array(){ - return Array.ofAll(sub.stream()); - } - public Set set(){ - return HashSet.ofAll(sub.stream()); - } - @Override - public void onSubscribe(Subscription s) { - sub.onSubscribe(s); - - } - @Override - public void onNext(T t) { - sub.onNext(t); - - } - @Override - public void onError(Throwable t) { - sub.onError(t); - - } - @Override - public void onComplete() { - sub.onComplete(); - } - -} \ No newline at end of file diff --git a/micro-javaslang/src/main/java/com/aol/micro/server/javaslang/reactive/JavaslangValueSubscriber.java b/micro-javaslang/src/main/java/com/aol/micro/server/javaslang/reactive/JavaslangValueSubscriber.java deleted file mode 100644 index 14862a802..000000000 --- a/micro-javaslang/src/main/java/com/aol/micro/server/javaslang/reactive/JavaslangValueSubscriber.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.aol.micro.server.javaslang.reactive; - -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; - -import com.aol.cyclops.control.Xor; -import com.aol.cyclops.javaslang.FromJDK; -import com.aol.cyclops.types.stream.reactive.ValueSubscriber; - -import javaslang.control.Either; -import javaslang.control.Option; -import javaslang.control.Try; - -public class JavaslangValueSubscriber implements Subscriber{ - - /** - * A reactive-streams subscriber that can generate a Javaslang value type - * - * @return JavaslangValueSubscriber - */ - public static JavaslangValueSubscriber subscriber(){ - return new JavaslangValueSubscriber(); - } - ValueSubscriber sub = ValueSubscriber.subscriber(); - - public Option option(){ - return FromJDK.option(sub.toOptional()); - } - public Try tryValue(){ - Xor xor = sub.toXor(); - return xor.visit(e->Try.failure(e),t->Try.success(t)); - } - public Either either(){ - Xor xor = sub.toXor(); - return xor.visit(e->Either.left(e),t->Either.right(t)); - } - @Override - public void onSubscribe(Subscription s) { - sub.onSubscribe(s); - - } - @Override - public void onNext(T t) { - sub.onNext(t); - - } - @Override - public void onError(Throwable t) { - sub.onError(t); - - } - @Override - public void onComplete() { - sub.onComplete(); - } - -} \ No newline at end of file diff --git a/micro-javaslang/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-javaslang/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index e84199533..000000000 --- a/micro-javaslang/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.javaslang.JavaslangPlugin \ No newline at end of file diff --git a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java b/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java deleted file mode 100644 index 2aa2e03bc..000000000 --- a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.ArrayList; - -import javaslang.collection.List; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -@Component -@Path("/alt-status") -public class AltAppResource implements AltAppRestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public List ping(ImmutableEntity entity) { - return entity.getList(); - } - -} diff --git a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java b/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java deleted file mode 100644 index 8cb2643e3..000000000 --- a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface AltAppRestResource extends RestResource { - -} diff --git a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java b/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java deleted file mode 100644 index bc73c2862..000000000 --- a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.Arrays; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.EmbeddedModule; - -@Microserver(basePackages = { "app.embedded.com.aol.micro.server" }) -public class EmbeddedAppLocalMain { - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( - EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")).start(); - - - - } - - -} diff --git a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java b/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java deleted file mode 100644 index fab27489e..000000000 --- a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java +++ /dev/null @@ -1,113 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import javaslang.collection.List; -import javaslang.jackson.datatype.JavaslangModule; - -import javax.ws.rs.NotFoundException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.EmbeddedModule; -import com.aol.micro.server.rest.jackson.JacksonUtil; -import com.aol.micro.server.testing.RestAgent; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - - -public class EmbeddedAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer(){ - server = new MicroserverApp(EmbeddedAppLocalMain.class, - EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")); - server.start(); - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException, JsonProcessingException{ - - assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); - ObjectMapper mapper = new ObjectMapper(); - mapper.registerModule(new JavaslangModule()); - String json = mapper.writer().writeValueAsString(List.of(List.of(1))); - - System.out.println(mapper.writer().writeValueAsString(new ImmutableEntity("value",List.of("hello","world")))); - - System.out.println(JacksonUtil.serializeToJson(new ImmutableEntity("value",List.of("hello","world")))); -assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value",List.of("hello","world")),List.class), - hasItem("hello")); - - } - - - @Test - public void nonBlockingRestClientTest(){ - assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"),is("-*test!-*test!")); - } - - CompletableFuture toCompletableFuture( - final ListenableFuture listenableFuture - ) { - //create an instance of CompletableFuture - CompletableFuture completable = new CompletableFuture() { - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - // propagate cancel to the listenable future - boolean result = listenableFuture.cancel(mayInterruptIfRunning); - super.cancel(mayInterruptIfRunning); - return result; - } - }; - - // add callback - listenableFuture.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(T result) { - completable.complete(result); - } - - @Override - public void onFailure(Throwable t) { - completable.completeExceptionally(t); - } - }); - return completable; - } - - @Test(expected=NotFoundException.class) - public void confirmAltAppCantUseTestAppResources(){ - - assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); - - } - @Test(expected=NotFoundException.class) - public void confirmTestAppCantUseAltAppResources(){ - - assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",List.of("hello","world")),List.class), - hasItem("hello")); - - } -} diff --git a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java b/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java deleted file mode 100644 index ad65178f1..000000000 --- a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java +++ /dev/null @@ -1,31 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import javaslang.collection.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - - - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableEntity { - - private final String value; - private final List list; - - public ImmutableEntity() { - this(null,null); - } - -} diff --git a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java b/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java deleted file mode 100644 index 9a882b3e6..000000000 --- a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java +++ /dev/null @@ -1,47 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.micro.server.testing.RestAgent; - -import javaslang.collection.List; -@Component -@Path("/test-status") -public class TestAppResource implements TestAppRestResource { - - private final SimpleReact simpleReact = new SimpleReact(); - private final RestAgent template = new RestAgent(); - private final List urls = List.of("http://localhost:8081/alternative-app/alt-status/ping", - "http://localhost:8080/test-app/test-status/ping", - "http://localhost:8082/simple-app/status/ping", - "http://localhost:8080/test-app/test-status/ping"); - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - @GET - @Produces("text/plain") - @Path("/rest-calls") - public String restCallResult(){ - - return LazyFutureStream.lazyFutureStreamFromIterable(urls) - .map(it ->template.get(it)) - .then(it -> "*"+it) - .peek(loadedAndModified -> System.out.println(loadedAndModified)) - .block().stream().reduce("", (acc,next) -> acc+"-"+next); - - } - -} diff --git a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java b/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java deleted file mode 100644 index 3133fd8cc..000000000 --- a/micro-javaslang/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface TestAppRestResource extends RestResource { - -} diff --git a/micro-javaslang/src/test/java/app/example/javaslang/JavaslangApp.java b/micro-javaslang/src/test/java/app/example/javaslang/JavaslangApp.java deleted file mode 100644 index 698b937d3..000000000 --- a/micro-javaslang/src/test/java/app/example/javaslang/JavaslangApp.java +++ /dev/null @@ -1,69 +0,0 @@ -package app.example.javaslang; - -import java.util.Arrays; - -import javaslang.collection.HashMap; -import javaslang.collection.HashSet; -import javaslang.collection.List; -import javaslang.collection.Map; -import javaslang.collection.Set; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.experimental.Builder; -import lombok.Getter; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.config.Microserver; - -@Microserver -@Path("/javaslang") -@Rest -public class JavaslangApp { - - - public static void main(String[] args){ - new MicroserverApp(() -> "javaslang-app").start(); - - } - - - @GET - @Produces("application/json") - @Path("/ping") - public ImmutableJavaslangEntity ping() { - return ImmutableJavaslangEntity.builder().value("value") - .list(List.of("hello", "world")) - .mapOfSets(HashMap.empty().put("key1",HashSet.ofAll(Arrays.asList(1, 2, 3)))) - .build(); - } - - - @XmlAccessorType(XmlAccessType.FIELD) - @XmlType(name = "") - @XmlRootElement(name = "immutable") - @Getter - @AllArgsConstructor - @Builder - public static class ImmutableJavaslangEntity { - - private final String value; - private final List list; - private final Map mapOfSets; - - - public ImmutableJavaslangEntity() { - this(null,null,null); - } - - } - -} diff --git a/micro-javaslang/src/test/java/app/javaslang/com/aol/micro/server/ImmutableJavaslangEntity.java b/micro-javaslang/src/test/java/app/javaslang/com/aol/micro/server/ImmutableJavaslangEntity.java deleted file mode 100644 index b59dbba87..000000000 --- a/micro-javaslang/src/test/java/app/javaslang/com/aol/micro/server/ImmutableJavaslangEntity.java +++ /dev/null @@ -1,33 +0,0 @@ -package app.javaslang.com.aol.micro.server; - -import javaslang.collection.List; -import javaslang.collection.Map; -import javaslang.collection.Set; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableJavaslangEntity { - - private final String value; - private final List list; - private final Map mapOfSets; - - - public ImmutableJavaslangEntity() { - this(null,null,null); - } - -} diff --git a/micro-javaslang/src/test/java/app/javaslang/com/aol/micro/server/JavaslangAppResource.java b/micro-javaslang/src/test/java/app/javaslang/com/aol/micro/server/JavaslangAppResource.java deleted file mode 100644 index 9ef11bfa3..000000000 --- a/micro-javaslang/src/test/java/app/javaslang/com/aol/micro/server/JavaslangAppResource.java +++ /dev/null @@ -1,29 +0,0 @@ -package app.javaslang.com.aol.micro.server; - -import javaslang.collection.List; -import javaslang.control.Option; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.auto.discovery.Rest; -@Rest -@Path("/status") -public class JavaslangAppResource { - - @POST - @Produces("application/json") - @Path("/ping") - - public List ping( ImmutableJavaslangEntity entity) { - return entity.getList(); - } - @POST - @Produces("application/json") - @Path("/optional") - public Option optional(JavaslangEntity entity) { - return entity.getName(); - } - -} diff --git a/micro-javaslang/src/test/java/app/javaslang/com/aol/micro/server/JavaslangAppTest.java b/micro-javaslang/src/test/java/app/javaslang/com/aol/micro/server/JavaslangAppTest.java deleted file mode 100644 index c3c86936c..000000000 --- a/micro-javaslang/src/test/java/app/javaslang/com/aol/micro/server/JavaslangAppTest.java +++ /dev/null @@ -1,96 +0,0 @@ -package app.javaslang.com.aol.micro.server; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.SimpleReactStream; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.jackson.JacksonUtil; -import com.aol.micro.server.testing.RestAgent; - -import javaslang.collection.HashMap; -import javaslang.collection.HashSet; -import javaslang.collection.List; -import javaslang.collection.Set; -import javaslang.control.Option; - -@Microserver(basePackages = { "app.guava.com.aol.micro.server" }) -public class JavaslangAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - ImmutableJavaslangEntity entity; - JavaslangEntity present; - JavaslangEntity absent; - - SimpleReact simpleReact = new SimpleReact(); - SimpleReactStream stream; - - @Before - public void startServer() { - stream = simpleReact.ofAsync( - () -> server = new MicroserverApp(JavaslangAppTest.class, - () -> "guava-app")).then(server -> server.start()); - - - entity = ImmutableJavaslangEntity.builder().value("value") - .list(List.of("hello", "world")) - .mapOfSets(HashMap.empty().put("key1",HashSet.ofAll(Arrays.asList(1, 2, 3)))) - .build(); - - JacksonUtil.convertFromJson(JacksonUtil.serializeToJson(entity), - ImmutableJavaslangEntity.class); - - present = JavaslangEntity.builder().name(Option.of("test")).build(); - - - JacksonUtil.convertFromJson(JacksonUtil.serializeToJson(present), - Option.class); - absent = JavaslangEntity.builder().name(Option.none()).build(); - } - - @After - public void stopServer() { - server.stop(); - } - - @Test @Ignore //option not supported yet - public void confirmExpectedUrlsPresentTest() throws InterruptedException, - ExecutionException { - - stream.block(); - - assertThat((List) rest.post( - "http://localhost:8080/guava-app/status/ping", entity, - List.class), hasItem("hello")); - - } - - @Test @Ignore //option not supported yet - public void confirmOptionalConversionWorking() throws InterruptedException, - ExecutionException { - - stream.block(); - - assertThat(rest.post("http://localhost:8080/guava-app/status/optional", - present, String.class), is("\"test\"")); - - assertThat(rest.post("http://localhost:8080/guava-app/status/optional", - absent, String.class), is("null")); - - } - -} diff --git a/micro-javaslang/src/test/java/app/javaslang/com/aol/micro/server/JavaslangEntity.java b/micro-javaslang/src/test/java/app/javaslang/com/aol/micro/server/JavaslangEntity.java deleted file mode 100644 index a19fabd26..000000000 --- a/micro-javaslang/src/test/java/app/javaslang/com/aol/micro/server/JavaslangEntity.java +++ /dev/null @@ -1,27 +0,0 @@ -package app.javaslang.com.aol.micro.server; - -import javaslang.control.Option; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "optional") -@Getter -@AllArgsConstructor -@Builder -public class JavaslangEntity { - - private final Option name; - - public JavaslangEntity(){ - name = Option.none(); - } -} diff --git a/micro-javaslang/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java b/micro-javaslang/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java deleted file mode 100644 index 73840fbea..000000000 --- a/micro-javaslang/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java +++ /dev/null @@ -1,25 +0,0 @@ -package app.validation.com.aol.micro.server; - -import javax.validation.constraints.NotNull; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import app.javaslang.com.aol.micro.server.ImmutableJavaslangEntity; - -import com.aol.micro.server.auto.discovery.RestResource; -@Component -@Path("/status") -public class ValidationAppResource implements RestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public ImmutableJavaslangEntity ping( @NotNull ImmutableJavaslangEntity entity) { - return entity; - } - - -} diff --git a/micro-javaslang/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java b/micro-javaslang/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java deleted file mode 100644 index f86d2fa63..000000000 --- a/micro-javaslang/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java +++ /dev/null @@ -1,88 +0,0 @@ -package app.validation.com.aol.micro.server; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.BadRequestException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.SimpleReactStream; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.jackson.JacksonUtil; -import com.aol.micro.server.testing.RestAgent; - -import app.javaslang.com.aol.micro.server.ImmutableJavaslangEntity; -import javaslang.collection.HashMap; -import javaslang.collection.HashSet; -import javaslang.collection.List; -import javaslang.collection.Set; - - -@Microserver(basePackages = { "app.validation.com.aol.micro.server" }) -public class ValidationAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - ImmutableJavaslangEntity entity; - - - SimpleReact simpleReact = new SimpleReact(); - SimpleReactStream stream; - - @Before - public void startServer() { - stream = simpleReact.ofAsync( - () -> server = new MicroserverApp(ValidationAppTest.class, - () -> "validation-app")).then(server -> server.start()); - - entity = ImmutableJavaslangEntity.builder().value("value") - .list(List.of("hello", "world")) - .mapOfSets(HashMap.empty().put("key1",HashSet.ofAll(Arrays.asList(1, 2, 3)))) - .build(); - - String json = JacksonUtil.serializeToJson(entity); - - ImmutableJavaslangEntity entity = JacksonUtil.convertFromJson(json, ImmutableJavaslangEntity.class); - - - } - - @After - public void stopServer() { - server.stop(); - } - - - @Test(expected=BadRequestException.class) - public void confirmError() throws InterruptedException, - ExecutionException { - - stream.block(); - rest.post( - "http://localhost:8080/validation-app/status/ping", null, - ImmutableJavaslangEntity.class); - - - } - @Test - public void confirmNoError() throws InterruptedException, - ExecutionException { - - stream.block(); - rest.post( - "http://localhost:8080/validation-app/status/ping", entity, - ImmutableJavaslangEntity.class); - - - } - - - -} diff --git a/micro-javaslang/src/test/java/com/aol/micro/server/reactive/JavaslangSubscriberTest.java b/micro-javaslang/src/test/java/com/aol/micro/server/reactive/JavaslangSubscriberTest.java deleted file mode 100644 index 522f183e3..000000000 --- a/micro-javaslang/src/test/java/com/aol/micro/server/reactive/JavaslangSubscriberTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.aol.micro.server.reactive; - -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; - -import org.junit.Test; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.micro.server.javaslang.reactive.JavaslangSubscriber; - -import javaslang.collection.Array; -import javaslang.collection.List; -import javaslang.collection.Stream; - -public class JavaslangSubscriberTest { - @Test - public void streamTest() { - JavaslangSubscriber sub = JavaslangSubscriber.subscriber(); - ReactiveSeq.of(1, 2, 3).subscribe(sub); - - Stream maybe = sub.stream(); - assertThat(maybe.toJavaList(), equalTo(Arrays.asList(1,2,3))); - } - @Test - public void listTest() { - JavaslangSubscriber sub = JavaslangSubscriber.subscriber(); - ReactiveSeq.of(1, 2, 3).subscribe(sub); - - List maybe = sub.list(); - assertThat(maybe.toJavaList(), equalTo(Arrays.asList(1,2,3))); - } - @Test - public void arrayTest() { - JavaslangSubscriber sub = JavaslangSubscriber.subscriber(); - ReactiveSeq.of(1, 2, 3).subscribe(sub); - - Array maybe = sub.array(); - assertThat(maybe.toJavaList(), equalTo(Arrays.asList(1,2,3))); - } - -} diff --git a/micro-javaslang/src/test/java/com/aol/micro/server/reactive/JavaslangValueSubscriberTest.java b/micro-javaslang/src/test/java/com/aol/micro/server/reactive/JavaslangValueSubscriberTest.java deleted file mode 100644 index 1a00d821c..000000000 --- a/micro-javaslang/src/test/java/com/aol/micro/server/reactive/JavaslangValueSubscriberTest.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.aol.micro.server.reactive; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.instanceOf; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; - -import java.util.NoSuchElementException; - -import org.junit.Test; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.javaslang.Javaslang; -import com.aol.micro.server.javaslang.reactive.JavaslangReactive; -import com.aol.micro.server.javaslang.reactive.JavaslangValueSubscriber; - -import javaslang.control.Either; -import javaslang.control.Option; -import javaslang.control.Try; -import javaslang.control.Try.NonFatalException; - -public class JavaslangValueSubscriberTest { - @Test - public void maybeTest() { - JavaslangValueSubscriber sub = JavaslangValueSubscriber.subscriber(); - ReactiveSeq.of(1, 2, 3).subscribe(sub); - - Option maybe = sub.option(); - assertThat(maybe.get(), equalTo(1)); - } - - @Test - public void maybePublisherTest() { - JavaslangValueSubscriber sub = JavaslangValueSubscriber.subscriber(); - Javaslang.value(Option.of(1)).subscribe(sub); - - Option maybe = sub.option(); - assertThat(maybe.get(), equalTo(1)); - } - - @Test - public void maybePublisherTest2() { - JavaslangValueSubscriber sub = JavaslangValueSubscriber.subscriber(); - JavaslangReactive.subsribeToValue(Option.of(1), sub); - - Option maybe = sub.option(); - assertThat(maybe.get(), equalTo(1)); - } - - @Test - public void maybeNonePublisherTest() { - JavaslangValueSubscriber sub = JavaslangValueSubscriber.subscriber(); - JavaslangReactive.subsribeToValue(Option.none(), sub); - - Option maybe = sub.option(); - assertFalse(maybe.isDefined()); - } - - @Test - public void eitherPublisherTest() { - JavaslangValueSubscriber sub = JavaslangValueSubscriber.subscriber(); - Javaslang.value(Either.right(1)).subscribe(sub); - - Either maybe = sub.either(); - assertThat(maybe.get(), equalTo(1)); - } - - @Test - public void eitherPublisherErrorTest() { - JavaslangValueSubscriber sub = JavaslangValueSubscriber.subscriber(); - JavaslangReactive.subsribeToValue(Either.left(1), sub); - - Either xor = sub.either(); - assertThat(xor.swap().get(), instanceOf(NoSuchElementException.class)); - } - - @Test - public void eitherLeftPublisherErrorTest() { - JavaslangValueSubscriber sub = JavaslangValueSubscriber.subscriber(); - Javaslang.value(Either. left(1)).subscribe(sub); - - Either xor = sub.either().swap(); - assertThat(xor.get(), instanceOf(NoSuchElementException.class)); - } - - @Test - public void tryPublisherTest() { - JavaslangValueSubscriber sub = JavaslangValueSubscriber.subscriber(); - Javaslang.value(Try.success(1)).subscribe(sub); - - Try maybe = sub.tryValue(); - assertThat(maybe.get(), equalTo(1)); - } - - @Test - public void tryPublisherErrorTest() { - JavaslangValueSubscriber sub = JavaslangValueSubscriber.subscriber(); - JavaslangReactive.subsribeToValue(Either.left(1), sub); - - Try xor = sub.tryValue(); - assertThat(xor.getCause(), instanceOf(NoSuchElementException.class)); - } - - @Test - public void tryLeftPublisherErrorTest() { - JavaslangValueSubscriber sub = JavaslangValueSubscriber.subscriber(); - Javaslang.value(Either. left(1)).subscribe(sub); - - Try xor = sub.tryValue(); - assertThat(xor.getCause(), instanceOf(NoSuchElementException.class)); - } -} diff --git a/micro-javaslang/src/test/java/com/aol/micro/server/reactive/ReactiveStreamsTest.java b/micro-javaslang/src/test/java/com/aol/micro/server/reactive/ReactiveStreamsTest.java deleted file mode 100644 index 158b00f26..000000000 --- a/micro-javaslang/src/test/java/com/aol/micro/server/reactive/ReactiveStreamsTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.aol.micro.server.reactive; - -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.Executors; - -import org.junit.Test; - -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.micro.server.javaslang.reactive.JavaslangReactive; -import com.aol.micro.server.javaslang.reactive.JavaslangSubscriber; - -import javaslang.collection.List; -import javaslang.collection.Stream; - -public class ReactiveStreamsTest { - - @Test - public void publish(){ - - Stream javaslangStream = JavaslangReactive.publishStream(LazyFutureStream.of(1,2,3)); - - assertThat(javaslangStream.toList(),equalTo(List.of(1,2,3))); - } - @Test - public void subscribe(){ - Stream stream = Stream.of(1,2,3); - JavaslangSubscriber sub = JavaslangSubscriber.subscriber(); - JavaslangReactive.subsribeToTraversable(stream, sub); - - assertThat(sub.list().toJavaList(),equalTo(Arrays.asList(1,2,3))); - } - -} diff --git a/micro-javaslang/src/test/java/com/aol/micro/server/rest/JacksonUtilTest.java b/micro-javaslang/src/test/java/com/aol/micro/server/rest/JacksonUtilTest.java deleted file mode 100644 index 8d13d29c5..000000000 --- a/micro-javaslang/src/test/java/com/aol/micro/server/rest/JacksonUtilTest.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.aol.micro.server.rest; - - -import static junit.framework.Assert.assertTrue; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.ArrayList; - -import javaslang.collection.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import jersey.repackaged.com.google.common.collect.ImmutableList; -import lombok.Getter; -import lombok.Setter; - -import org.junit.Test; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - - -public class JacksonUtilTest { - - @Test - public void testGenerics(){ - String s = JacksonUtil.serializeToJson(List.of(new MyEntity())); - List list = JacksonUtil.convertFromJson(s, JacksonUtil.getMapper().getTypeFactory().constructParametricType(List.class,MyEntity.class)); - assertThat(list.get(0),is(new MyEntity())); - - } - @Test - public void generateSampleRequest() { - - DummyQueryRequest request = new DummyQueryRequest(); - request.getData().add("blah"); - - assertTrue(JacksonUtil.serializeToJson(request).contains("strData")); - - } - - - @Test - public void serialiseAndDeserialise(){ - DummyQueryRequest request = new DummyQueryRequest(); - request.getData().add("blah"); - String requestStr = (String) JacksonUtil.serializeToJsonLogFailure(request); - DummyQueryRequest requestDeserialised = JacksonUtil.convertFromJson(requestStr, DummyQueryRequest.class); - assertTrue(request.getData().contains("blah")); - } - - -} - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlRootElement(name = "queryRequest") -@XmlType(name = "") -class DummyQueryRequest { - - @XmlElement(name = "strData") - @Getter - @Setter - private java.util.List data = new ArrayList(); - - -} - diff --git a/micro-javaslang/src/test/java/com/aol/micro/server/rest/MyEntity.java b/micro-javaslang/src/test/java/com/aol/micro/server/rest/MyEntity.java deleted file mode 100644 index b6a7a0ec7..000000000 --- a/micro-javaslang/src/test/java/com/aol/micro/server/rest/MyEntity.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.aol.micro.server.rest; - -import lombok.EqualsAndHashCode; -import lombok.Getter; - -@EqualsAndHashCode -@Getter -public class MyEntity { - - private final String name ="myEntity"; - -} diff --git a/micro-javaslang/src/test/java/com/aol/micro/server/rest/RestContextListenerTest.java b/micro-javaslang/src/test/java/com/aol/micro/server/rest/RestContextListenerTest.java deleted file mode 100644 index cebe8e618..000000000 --- a/micro-javaslang/src/test/java/com/aol/micro/server/rest/RestContextListenerTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.aol.micro.server.rest; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; - -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.rest.jersey.JerseyRestApplication; -import com.aol.micro.server.rest.jersey.JerseySpringIntegrationContextListener; -import com.aol.micro.server.servers.model.ServerData; - -public class RestContextListenerTest { - - private JerseySpringIntegrationContextListener restContextListener; - private ServletStatusResource statsResource; - - @Before - public void setUp() { - statsResource = new ServletStatusResource(); - ServerData serverData = new ServerData(8080, Arrays.asList(statsResource), null, "baseUrl", () -> "test"); - restContextListener = new JerseySpringIntegrationContextListener(serverData); - } - - @Test - public void testContextInitialized() { - restContextListener.contextInitialized(null); - assertThat(JerseyRestApplication.getResourcesMap().get("test").get(0), is(statsResource)); - } - - @Test - public void testContextDestroyed() { - restContextListener.contextDestroyed(null); - } - -} diff --git a/micro-javaslang/src/test/java/com/aol/micro/server/rest/ServletStatusResource.java b/micro-javaslang/src/test/java/com/aol/micro/server/rest/ServletStatusResource.java deleted file mode 100644 index c5e3cf667..000000000 --- a/micro-javaslang/src/test/java/com/aol/micro/server/rest/ServletStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aol.micro.server.rest; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/servlet") -public class ServletStatusResource implements RestResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-javaslang/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-javaslang/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index e69b546c9..000000000 --- a/micro-javaslang/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; -import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider(); - provider.setMapper(JacksonUtil.getMapper()); - client.register(provider); - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider(); - provider.setMapper(JacksonUtil.getMapper()); - client.register(provider); - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider(); - provider.setMapper(JacksonUtil.getMapper()); - client.register(provider); - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - String json = JacksonUtil.serializeToJson(payload); - //return request.post(Entity.entity(json,MediaType.APPLICATION_JSON), type); - String str = request.post(Entity.entity(json,MediaType.APPLICATION_JSON), String.class); - return JacksonUtil.convertFromJson(str, type); - } - - -} diff --git a/micro-jdbc/README.md b/micro-jdbc/README.md new file mode 100644 index 000000000..22e55c8c5 --- /dev/null +++ b/micro-jdbc/README.md @@ -0,0 +1,91 @@ +# JDBC plugin + +[micro-jdbc example apps](https://github.com/aol/micro-server/tree/master/micro-dbcp/src/test/java/app/pure/jdbc/com/aol/micro/server) + +Adds Spring JDBC. +This plugin needs either micro-hikaricp or micro-dbcp2 plugin at runtime to provide a DataSource (bean name for qualify / inject purposes is mainDataSource) + +## To use + + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-data/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-jdbc) + +Simply add to the classpath + +Maven + + + com.oath.microservices + micro-jdbc + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-jdbc:x.yz' + +# Configuring a data source + +A datasource can be configured by setting the following properties in application.properties, instance.properties or via the Microserver annotation + + db.connection.driver: (e.g. (org.hsqldb.jdbcDriver) + db.connection.url: (e.g. jdbc:hsqldb:mem:aname) + db.connection.username: (e.g. admin) + db.connection.password: (e.g. password) + db.connection.dialect: (e.g. org.hibernate.dialect.HSQLDialect) + db.connection.hibernate.showsql: (e.g. true | false) + db.connection.ddl.auto: (e.g. create-drop) + +The Microserver annotation can also be used to set some default properties, or they can be set in an application.properties or instance.properties file ([see wiki for more details](https://github.com/aol/micro-server/wiki/Defining-Properties)). + + +The important properties for us to set are the datasource properties + + @Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", + "db.connection.url","jdbc:hsqldb:mem:aname", + "db.connection.username", "sa"}) + + public class MyMainClass { + + + } + + + + # Plain ol' JDBC + +[JDBC Template Exmaple App](https://github.com/aol/micro-server/tree/master/micro-data/src/test/java/app/jdbc/com/aol/micro/server) + +The micro-data plugin also facilitate JDBC use via the Spring JDBCTemplate. A Spring called SQL will be created that contains a JDBCTemplate, simply inject SQL into your classes. + + e.g. + + @Rest + @Path("/persistence") + public class PersistentResource { + + private final SQL dao; + + @Autowired + public PersistentResource(SQL dao) { + + this.dao = dao; + } + + @GET + @Produces("text/plain") + @Path("/create") + public String createEntity() { + dao.getJdbc().update("insert into t_jdbc VALUES (1,'hello','world',1)"); + + return "ok"; + } + + @GET + @Produces("application/json") + @Path("/get") + public JdbcEntity get() { + return dao.getJdbc(). queryForObject("select * from t_jdbc", new BeanPropertyRowMapper(JdbcEntity.class)); + } + + } diff --git a/micro-jdbc/build.gradle b/micro-jdbc/build.gradle index 33fafe1a4..7c7dcd4f6 100644 --- a/micro-jdbc/build.gradle +++ b/micro-jdbc/build.gradle @@ -1,72 +1,71 @@ description = 'micro-jdbc' -dependencies { - compile 'org.springframework.data:spring-data-jpa:'+springDataJPA - compile group: 'org.springframework', name: 'spring-jdbc', version:"${springVersion}" - - compile project(':micro-core') - testCompile project(':micro-client') - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') - testCompile group: 'org.hsqldb', name:'hsqldb', version:'2.0.0' +dependencies { + compile 'org.springframework.data:spring-data-jpa:' + springDataJPA + compile group: 'org.springframework', name: 'spring-jdbc', version: "${springVersion}" + compile project(':micro-core') + testCompile project(':micro-client') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') + testCompile group: 'org.hsqldb', name: 'hsqldb', version: '2.0.0' } modifyPom { - project { - name 'Microserver jdbc' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver jdbc' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-jdbc' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } - groupId 'com.aol.microservices' - artifactId 'micro-jdbc' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - developer { - id 'earlzero' - name 'Nikita Sapozhnikov' - email 'nikita.sapozhnikov@teamaol.com' - } - } - - } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-jdbc/readme.md b/micro-jdbc/readme.md deleted file mode 100644 index 9149c132b..000000000 --- a/micro-jdbc/readme.md +++ /dev/null @@ -1,91 +0,0 @@ - # JDBC plugin - -[micro-jdbc example apps](https://github.com/aol/micro-server/tree/master/micro-dbcp/src/test/java/app/pure/jdbc/com/aol/micro/server) - -Adds Spring JDBC. -This plugin needs either micro-hikaricp or micro-dbcp2 plugin at runtime to provide mainDataSource - -## To use - - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-data/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-jdbc) - -Simply add to the classpath - -Maven - - - com.aol.microservices - micro-jdbc - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-jdbc:x.yz' - -# Configuring a data source - -A datasource can be configured by setting the following properties in application.properties, instance.properties or via the Microserver annotation - - db.connection.driver: (e.g. (org.hsqldb.jdbcDriver) - db.connection.url: (e.g. jdbc:hsqldb:mem:aname) - db.connection.username: (e.g. admin) - db.connection.password: (e.g. password) - db.connection.dialect: (e.g. org.hibernate.dialect.HSQLDialect) - db.connection.hibernate.showsql: (e.g. true | false) - db.connection.ddl.auto: (e.g. create-drop) - -The Microserver annotation can also be used to set some default properties, or they can be set in an application.properties or instance.properties file ([see wiki for more details](https://github.com/aol/micro-server/wiki/Defining-Properties)). - - -The important properties for us to set are the datasource properties - - @Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", - "db.connection.url","jdbc:hsqldb:mem:aname", - "db.connection.username", "sa"}) - - public class MyMainClass { - - - } - - - - # Plain ol' JDBC - -[JDBC Template Exmaple App](https://github.com/aol/micro-server/tree/master/micro-data/src/test/java/app/jdbc/com/aol/micro/server) - -The micro-data plugin also facilitate JDBC use via the Spring JDBCTemplate. A Spring called SQL will be created that contains a JDBCTemplate, simply inject SQL into your classes. - - e.g. - - @Rest - @Path("/persistence") - public class PersistentResource { - - private final SQL dao; - - @Autowired - public PersistentResource(SQL dao) { - - this.dao = dao; - } - - @GET - @Produces("text/plain") - @Path("/create") - public String createEntity() { - dao.getJdbc().update("insert into t_jdbc VALUES (1,'hello','world',1)"); - - return "ok"; - } - - @GET - @Produces("application/json") - @Path("/get") - public JdbcEntity get() { - return dao.getJdbc(). queryForObject("select * from t_jdbc", new BeanPropertyRowMapper(JdbcEntity.class)); - } - - } diff --git a/micro-jdbc/src/main/java/com/aol/micro/server/spring/JdbcPlugin.java b/micro-jdbc/src/main/java/com/aol/micro/server/spring/JdbcPlugin.java deleted file mode 100644 index a2b9fe259..000000000 --- a/micro-jdbc/src/main/java/com/aol/micro/server/spring/JdbcPlugin.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.aol.micro.server.spring; - -import java.util.Optional; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.spring.datasource.JdbcConfig; -import com.aol.micro.server.spring.datasource.jdbc.SQL; - -/** - * - * Collections of Spring configuration classes (Classes annotated with @Configuration) - * that configure various useful pieces of functionality - such as property file loading, - * datasources, scheduling etc - * - * @author johnmcclean - * - */ -public class JdbcPlugin implements Plugin { - - @Override - public Optional springDbConfigurer() { - return Optional.of(new SpringConfigurer()); - } - - @Override - public PSetX springClasses() { - return PSetX.of(JdbcConfig.class, SQL.class); - } - - -} diff --git a/micro-jdbc/src/main/java/com/oath/micro/server/spring/JdbcPlugin.java b/micro-jdbc/src/main/java/com/oath/micro/server/spring/JdbcPlugin.java new file mode 100644 index 000000000..03401ee11 --- /dev/null +++ b/micro-jdbc/src/main/java/com/oath/micro/server/spring/JdbcPlugin.java @@ -0,0 +1,34 @@ +package com.oath.micro.server.spring; + +import java.util.Optional; +import java.util.Set; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.spring.datasource.JdbcConfig; +import com.oath.micro.server.spring.datasource.jdbc.SQL; +import cyclops.reactive.collections.mutable.SetX; + +/** + * + * Collections of Spring configuration classes (Classes annotated with @Configuration) + * that configure various useful pieces of functionality - such as property file loading, + * datasources, scheduling etc + * + * @author johnmcclean + * + */ +public class JdbcPlugin implements Plugin { + + @Override + public Optional springDbConfigurer() { + return Optional.of(new SpringConfigurer()); + } + + @Override + public Set springClasses() { + return SetX.of(JdbcConfig.class, SQL.class); + } + + +} diff --git a/micro-jdbc/src/main/java/com/aol/micro/server/spring/SpringConfigurer.java b/micro-jdbc/src/main/java/com/oath/micro/server/spring/SpringConfigurer.java similarity index 87% rename from micro-jdbc/src/main/java/com/aol/micro/server/spring/SpringConfigurer.java rename to micro-jdbc/src/main/java/com/oath/micro/server/spring/SpringConfigurer.java index 2c0f4e946..b9ab65152 100644 --- a/micro-jdbc/src/main/java/com/aol/micro/server/spring/SpringConfigurer.java +++ b/micro-jdbc/src/main/java/com/oath/micro/server/spring/SpringConfigurer.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.spring; +package com.oath.micro.server.spring; import java.util.Properties; @@ -9,8 +9,8 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.spring.datasource.JdbcConfig; +import com.oath.micro.server.config.Config; +import com.oath.micro.server.spring.datasource.JdbcConfig; public class SpringConfigurer implements SpringDBConfig { diff --git a/micro-jdbc/src/main/java/com/oath/micro/server/spring/datasource/DataSourceBuilder.java b/micro-jdbc/src/main/java/com/oath/micro/server/spring/datasource/DataSourceBuilder.java new file mode 100644 index 000000000..5c7e985b7 --- /dev/null +++ b/micro-jdbc/src/main/java/com/oath/micro/server/spring/datasource/DataSourceBuilder.java @@ -0,0 +1,8 @@ +package com.oath.micro.server.spring.datasource; + +import javax.sql.DataSource; + +public interface DataSourceBuilder { + + public DataSource buildDataSource(String classname, String url, String username, String password, int maxPoolsize); +} diff --git a/micro-jdbc/src/main/java/com/aol/micro/server/spring/datasource/JdbcConfig.java b/micro-jdbc/src/main/java/com/oath/micro/server/spring/datasource/JdbcConfig.java similarity index 92% rename from micro-jdbc/src/main/java/com/aol/micro/server/spring/datasource/JdbcConfig.java rename to micro-jdbc/src/main/java/com/oath/micro/server/spring/datasource/JdbcConfig.java index ccdcb897f..20698d566 100644 --- a/micro-jdbc/src/main/java/com/aol/micro/server/spring/datasource/JdbcConfig.java +++ b/micro-jdbc/src/main/java/com/oath/micro/server/spring/datasource/JdbcConfig.java @@ -1,17 +1,17 @@ -package com.aol.micro.server.spring.datasource; +package com.oath.micro.server.spring.datasource; import java.util.Properties; import lombok.Getter; -import lombok.experimental.Builder; +import lombok.Builder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import com.aol.micro.server.config.ConfigAccessor; -import com.aol.micro.server.utility.UsefulStaticMethods; +import com.oath.micro.server.config.ConfigAccessor; +import com.oath.micro.server.utility.UsefulStaticMethods; @Getter @Builder @@ -30,7 +30,7 @@ public class JdbcConfig { private final String name; private final String generateDdl; private final String initializationFile; - + public JdbcConfig(@Value("${db.connection.driver:}") String driverClassName, @Value("${db.connection.url:}") String url, @Value("${db.connection.username:}") String username, @Value("${db.connection.password:}") String password, @Value("${db.connection.hibernate.showsql:false}") String showSql, @Value("${db.connection.dialect:}") String dialect, @@ -55,7 +55,7 @@ public JdbcConfig(@Value("${db.connection.driver:}") String driverClassName, @Va this.showSql = UsefulStaticMethods.either(showSql, extract("connection.showsql")); this.dialect = UsefulStaticMethods.either(dialect, extract("connection.dialect")); this.ddlAuto = UsefulStaticMethods.either(ddlAuto, extract("connection.ddl.auto")); - this.generateDdl = UsefulStaticMethods.either(generateDdl, extract("connection.generate.ddl")); + this.generateDdl = UsefulStaticMethods.either(generateDdl, extract("connection.generate.ddl")); this.initializationFile = initializationFile; } diff --git a/micro-jdbc/src/main/java/com/aol/micro/server/spring/datasource/jdbc/SQL.java b/micro-jdbc/src/main/java/com/oath/micro/server/spring/datasource/jdbc/SQL.java similarity index 89% rename from micro-jdbc/src/main/java/com/aol/micro/server/spring/datasource/jdbc/SQL.java rename to micro-jdbc/src/main/java/com/oath/micro/server/spring/datasource/jdbc/SQL.java index ac265291d..1776be760 100644 --- a/micro-jdbc/src/main/java/com/aol/micro/server/spring/datasource/jdbc/SQL.java +++ b/micro-jdbc/src/main/java/com/oath/micro/server/spring/datasource/jdbc/SQL.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.spring.datasource.jdbc; +package com.oath.micro.server.spring.datasource.jdbc; import org.springframework.beans.factory.annotation.Qualifier; import javax.sql.DataSource; diff --git a/micro-jdbc/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-jdbc/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 02e59124f..000000000 --- a/micro-jdbc/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.spring.JdbcPlugin \ No newline at end of file diff --git a/micro-jdbc/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-jdbc/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..34113ee92 --- /dev/null +++ b/micro-jdbc/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.spring.JdbcPlugin \ No newline at end of file diff --git a/micro-jdbc/src/test/java/com/aol/micro/server/JdbcConfigTest.java b/micro-jdbc/src/test/java/com/oath/micro/server/JdbcConfigTest.java similarity index 88% rename from micro-jdbc/src/test/java/com/aol/micro/server/JdbcConfigTest.java rename to micro-jdbc/src/test/java/com/oath/micro/server/JdbcConfigTest.java index dba8f3d52..10d283646 100644 --- a/micro-jdbc/src/test/java/com/aol/micro/server/JdbcConfigTest.java +++ b/micro-jdbc/src/test/java/com/oath/micro/server/JdbcConfigTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server; +package com.oath.micro.server; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; @@ -9,8 +9,8 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.spring.datasource.JdbcConfig; +import com.oath.micro.server.config.Config; +import com.oath.micro.server.spring.datasource.JdbcConfig; public class JdbcConfigTest { diff --git a/micro-jersey/README.md b/micro-jersey/README.md new file mode 100644 index 000000000..b9ac1871a --- /dev/null +++ b/micro-jersey/README.md @@ -0,0 +1,54 @@ +# Jersey jax-rs Plugin + +[Example Jersey Apps](https://github.com/aol/micro-server/tree/master/micro-grizzly/src/test/java/app) + +Plugin that allows the Jersey to be used as the jax-rs implementation with Microserver. (micro-jersey does not include a webserver (such as micro-grizzly, or JSON serializer / deserializer such as micro-jackson-configuration. See micro-grizzly-with-jersey for an end-to-end solution). + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-jersey/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-jersey) + +Simply add to the classpath + +Maven + ```xml + + + com.oath.microservices + micro-jersey + x.yz + + +``` +Gradle +```groovy + compile 'com.oath.microservices:micro-jersey:x.yz' +``` + +## Baked in async NIO based REST + +Return any reactive-streams Publisher from your REST end point to make them execute asynchronously automatically. + +E.g. Using Future from [cyclops-react](cyclops-react.io) +```java + @GET + public Future myEndPoint(){ + return Future.of(()->{ + sleep(); + return "hello world!"; + }, Executors.newFixedThreadPool(1)); + } +``` + +Would be equivalent to the following code + +```java + @GET + public void myEndPoint(@Suspended AsyncResponse asyncResponse){ + Future.of(()->{ + sleep(); + asyncResponse.resume("hello world!"); + return 1; + }, Executors.newFixedThreadPool(1)); +} +``` diff --git a/micro-jersey/build.gradle b/micro-jersey/build.gradle index 936315311..954292ef9 100644 --- a/micro-jersey/build.gradle +++ b/micro-jersey/build.gradle @@ -1,79 +1,75 @@ description = 'micro-grizzly' + dependencies { - - compile project(':micro-core') - - - compile group: 'org.glassfish.jersey.core', name: 'jersey-server', version:"$jerseyVersion" - compile(group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version:"$jerseyVersion") { - exclude(module: 'jackson-xc') - exclude(module: 'jackson-core-asl') - exclude(module: 'jackson-jaxrs') - exclude(module: 'jackson-mapper-asl') - } - compile group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version:"$jerseyVersion" - - compile "org.glassfish.jersey.media:jersey-media-multipart:$jerseyVersion" - compile "org.glassfish.jersey.ext:jersey-spring3:$jerseyVersion" - compile "org.glassfish.jersey.ext:jersey-bean-validation:$jerseyVersion" - testCompile group: 'org.glassfish.jersey.core', name: 'jersey-client', version:"$jerseyVersion" - testCompile project(':micro-jackson-configuration') - + compile project(':micro-core') + compile group: 'org.glassfish.jersey.core', name: 'jersey-server', version: "$jerseyVersion" + compile(group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: "$jerseyVersion") { + exclude(module: 'jackson-xc') + exclude(module: 'jackson-core-asl') + exclude(module: 'jackson-jaxrs') + exclude(module: 'jackson-mapper-asl') + } + compile group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version: "$jerseyVersion" -} + compile "org.glassfish.jersey.media:jersey-media-multipart:$jerseyVersion" + compile "org.glassfish.jersey.ext:jersey-spring4:$jerseyVersion" + compile "org.glassfish.jersey.ext:jersey-bean-validation:$jerseyVersion" + testCompile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: "$jerseyVersion" + testCompile project(':micro-jackson-configuration') +} + modifyPom { - project { - name 'Microserver Jersey' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver Jersey' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-jersey' + version "$version" + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } - groupId 'com.aol.microservices' - artifactId 'micro-jersey' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - } - - } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-jersey/readme.md b/micro-jersey/readme.md deleted file mode 100644 index 3d5163701..000000000 --- a/micro-jersey/readme.md +++ /dev/null @@ -1,26 +0,0 @@ -# Jersey jax-rs Plugin - -[Example Jersey Apps](https://github.com/aol/micro-server/tree/master/micro-grizzly/src/test/java/app) - -Plugin that allows the Jersey to be used as the jax-rs implementation with Microserver. (micro-jersey does not include a webserver (such as micro-grizzly, or JSON serializer / deserializer such as micro-jackson-configuration. See micro-grizzly-with-jersey for an end-to-end solution). - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-jersey/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-jersey) - -Simply add to the classpath - -Maven - ```xml - - - com.aol.microservices - micro-jersey - x.yz - - -``` -Gradle -```groovy - compile 'com.aol.microservices:micro-jersey:x.yz' -``` \ No newline at end of file diff --git a/micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/ConfigureMainServlet.java b/micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/ConfigureMainServlet.java deleted file mode 100644 index 55b09ba68..000000000 --- a/micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/ConfigureMainServlet.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.aol.micro.server.rest.jersey; - -import java.util.HashMap; - -import org.glassfish.jersey.servlet.ServletContainer; - -import com.aol.micro.server.rest.RestConfiguration; -import com.aol.micro.server.servers.ServerThreadLocalVariables; - -public class ConfigureMainServlet { - public RestConfiguration servletConfig() { - - return new RestConfiguration(new CustomJerseyServlet(ServerThreadLocalVariables.getContext().get()),"Jersey Spring Web Application","jersey.config.server.provider.packages",new HashMap<>()); - - } -} diff --git a/micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/JerseyPlugin.java b/micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/JerseyPlugin.java deleted file mode 100644 index 07c3493c6..000000000 --- a/micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/JerseyPlugin.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.aol.micro.server.rest.jersey; - -import java.util.Map; -import java.util.Optional; -import java.util.function.Function; - -import javax.servlet.ServletContextListener; -import javax.ws.rs.core.FeatureContext; - -import org.glassfish.jersey.CommonProperties; - -import com.aol.cyclops.data.collections.extensions.persistent.PMapX; -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.cyclops.data.collections.extensions.standard.MapXs; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.rest.RestConfiguration; -import com.aol.micro.server.servers.model.ServerData; - - -public class JerseyPlugin implements Plugin{ - - @Override - public Optional restServletConfiguration(){ - return Optional.of(new ConfigureMainServlet().servletConfig()); - } - @Override - public Function> jacksonFeatureProperties(){ - return context->PMapX.fromMap(MapXs.of( CommonProperties.MOXY_JSON_FEATURE_DISABLE + '.' - + context.getConfiguration().getRuntimeType().name().toLowerCase(),true)); - } - - @Override - public Optional jaxWsRsApplication(){ - return Optional.of(JerseyRestApplication.class.getCanonicalName()); - } - @Override - public PSetX> servletContextListeners(){ - Function f = serverData ->new JerseySpringIntegrationContextListener(serverData); - return PSetX.of(f); - - } - -} diff --git a/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/AsyncBinder.java b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/AsyncBinder.java new file mode 100644 index 000000000..0284a7bcb --- /dev/null +++ b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/AsyncBinder.java @@ -0,0 +1,18 @@ +package com.oath.micro.server.rest.jersey; + +import org.glassfish.hk2.utilities.binding.AbstractBinder; +import org.glassfish.jersey.server.spi.internal.ResourceMethodDispatcher; +import org.glassfish.jersey.server.spi.internal.ResourceMethodInvocationHandlerProvider; + +import javax.inject.Singleton; + + +public class AsyncBinder extends AbstractBinder { + + @Override + protected void configure() { + bind(AsyncInvocationHandler.AsyncResourceMethodInvocationHandlerProvider.class) + .to(ResourceMethodInvocationHandlerProvider.class) + .in(Singleton.class); + } +} diff --git a/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/AsyncInvocationHandler.java b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/AsyncInvocationHandler.java new file mode 100644 index 000000000..8a2aef2ce --- /dev/null +++ b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/AsyncInvocationHandler.java @@ -0,0 +1,62 @@ +package com.oath.micro.server.rest.jersey; + +import cyclops.reactive.Spouts; +import org.glassfish.jersey.internal.inject.InjectionManager; +import org.glassfish.jersey.server.AsyncContext; +import org.glassfish.jersey.server.internal.LocalizationMessages; +import org.glassfish.jersey.server.model.Invocable; +import org.glassfish.jersey.server.spi.internal.ResourceMethodInvocationHandlerProvider; +import org.reactivestreams.Publisher; + +import javax.inject.Inject; +import javax.inject.Provider; +import javax.ws.rs.ProcessingException; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.core.Response; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; + +public class AsyncInvocationHandler implements InvocationHandler { + + @Inject + protected Provider contextProvider; + + @Inject + protected Provider containerRequestProvider; + + @Override + public Object invoke(Object proxy, Method method, Object[] args) { + final AsyncContext context = contextProvider.get(); + if (!context.suspend()) { + throw new ProcessingException(LocalizationMessages.ERROR_SUSPENDING_ASYNC_REQUEST()); + } + final ContainerRequestContext requestContext = containerRequestProvider.get(); + + try { + Publisher pub =(Publisher)method.invoke(proxy,args); + Spouts.from(pub).onEmptySwitch(()->Spouts.of(Response.noContent().build())) + .forEach(1,context::resume, context::resume); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + + return null; + } + public static class AsyncResourceMethodInvocationHandlerProvider implements ResourceMethodInvocationHandlerProvider{ + @Inject + private InjectionManager injectionManager; + + @Override + public InvocationHandler create(Invocable method) { + Class returnType = method.getRawResponseType(); + if(Publisher.class.isAssignableFrom(returnType) & !Collection.class.isAssignableFrom(returnType)){ + return injectionManager.createAndInitialize(AsyncInvocationHandler.class); + } + return null; + } + } +} diff --git a/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/ConfigureMainServlet.java b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/ConfigureMainServlet.java new file mode 100644 index 000000000..4d254a5c8 --- /dev/null +++ b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/ConfigureMainServlet.java @@ -0,0 +1,14 @@ +package com.oath.micro.server.rest.jersey; + +import java.util.HashMap; + +import com.oath.micro.server.rest.RestConfiguration; +import com.oath.micro.server.servers.ServerThreadLocalVariables; + +public class ConfigureMainServlet { + public RestConfiguration servletConfig() { + + return new RestConfiguration(new CustomJerseyServlet(ServerThreadLocalVariables.getContext().get()),"Jersey Spring Web Application","jersey.config.server.provider.packages",new HashMap<>()); + + } +} diff --git a/micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/CustomJerseyServlet.java b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/CustomJerseyServlet.java similarity index 81% rename from micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/CustomJerseyServlet.java rename to micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/CustomJerseyServlet.java index afa4a3300..5e46f31d9 100644 --- a/micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/CustomJerseyServlet.java +++ b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/CustomJerseyServlet.java @@ -1,10 +1,10 @@ -package com.aol.micro.server.rest.jersey; +package com.oath.micro.server.rest.jersey; import javax.servlet.ServletException; import org.glassfish.jersey.servlet.ServletContainer; -import com.aol.micro.server.servers.ServerThreadLocalVariables; +import com.oath.micro.server.servers.ServerThreadLocalVariables; public class CustomJerseyServlet extends ServletContainer{ diff --git a/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/JerseyPlugin.java b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/JerseyPlugin.java new file mode 100644 index 000000000..8825d05df --- /dev/null +++ b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/JerseyPlugin.java @@ -0,0 +1,45 @@ +package com.oath.micro.server.rest.jersey; + +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; + +import javax.servlet.ServletContextListener; +import javax.ws.rs.core.FeatureContext; + +import cyclops.reactive.collections.mutable.MapX; +import cyclops.reactive.collections.mutable.SetX; +import cyclops.reactive.companion.MapXs; +import org.glassfish.jersey.CommonProperties; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.rest.RestConfiguration; +import com.oath.micro.server.servers.model.ServerData; + + +public class JerseyPlugin implements Plugin{ + + @Override + public Optional restServletConfiguration(){ + return Optional.of(new ConfigureMainServlet().servletConfig()); + } + @Override + public Function> jacksonFeatureProperties(){ + return context-> MapX.fromMap(MapXs.of( CommonProperties.MOXY_JSON_FEATURE_DISABLE + '.' + + context.getConfiguration().getRuntimeType().name().toLowerCase(),true)); + } + + @Override + public Optional jaxWsRsApplication(){ + return Optional.of(JerseyRestApplication.class.getCanonicalName()); + } + @Override + public Set> servletContextListeners(){ + Function f = serverData ->new JerseySpringIntegrationContextListener(serverData); + return SetX.of(f); + + } + +} diff --git a/micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/JerseyRestApplication.java b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/JerseyRestApplication.java similarity index 84% rename from micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/JerseyRestApplication.java rename to micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/JerseyRestApplication.java index 2a5dfe330..1c387758c 100644 --- a/micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/JerseyRestApplication.java +++ b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/JerseyRestApplication.java @@ -1,4 +1,14 @@ -package com.aol.micro.server.rest.jersey; +package com.oath.micro.server.rest.jersey; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.module.JaxRsProvider; +import com.oath.micro.server.servers.ServerThreadLocalVariables; +import lombok.Getter; +import org.glassfish.jersey.message.GZipEncoder; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.ServerProperties; +import org.glassfish.jersey.server.filter.EncodingFilter; import java.util.List; import java.util.Map; @@ -7,16 +17,6 @@ import java.util.concurrent.ConcurrentMap; import java.util.function.Consumer; -import lombok.Getter; - -import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.server.ServerProperties; - -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.module.JaxRsProvider; -import com.aol.micro.server.servers.ServerThreadLocalVariables; - public class JerseyRestApplication extends ResourceConfig { @Getter @@ -51,6 +51,11 @@ public JerseyRestApplication(List allResources,List packages, Li register(next.getClass()); } } + + register(EncodingFilter.class); //Server encoding filter class + register(GZipEncoder.class); + + register(new AsyncBinder()); if (serverProperties.isEmpty()) { property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true); diff --git a/micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/JerseySpringIntegrationContextListener.java b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/JerseySpringIntegrationContextListener.java similarity index 83% rename from micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/JerseySpringIntegrationContextListener.java rename to micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/JerseySpringIntegrationContextListener.java index 1a5f7d349..c33fcdf3a 100644 --- a/micro-jersey/src/main/java/com/aol/micro/server/rest/jersey/JerseySpringIntegrationContextListener.java +++ b/micro-jersey/src/main/java/com/oath/micro/server/rest/jersey/JerseySpringIntegrationContextListener.java @@ -1,9 +1,10 @@ -package com.aol.micro.server.rest.jersey; +package com.oath.micro.server.rest.jersey; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; -import com.aol.micro.server.servers.model.ServerData; +import com.oath.micro.server.servers.model.ServerData; +import cyclops.reactive.collections.mutable.ListX; public class JerseySpringIntegrationContextListener implements ServletContextListener { @@ -20,7 +21,7 @@ public void contextDestroyed(ServletContextEvent arg0) { @Override public void contextInitialized(ServletContextEvent arg0) { - JerseyRestApplication.getResourcesMap().put(serverData.getModule().getContext(), serverData.getResources()); + JerseyRestApplication.getResourcesMap().put(serverData.getModule().getContext(), ListX.fromIterable(serverData.getResources())); JerseyRestApplication.getPackages().put(serverData.getModule().getContext(), serverData.getModule().getDefaultJaxRsPackages()); JerseyRestApplication.getResourcesClasses().put(serverData.getModule().getContext(), serverData.getModule().getDefaultResources()); JerseyRestApplication.getResourceConfigManager().put(serverData.getModule().getContext(), serverData.getModule().getResourceConfigManager()); diff --git a/micro-jersey/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-jersey/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 1c8614375..000000000 --- a/micro-jersey/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.rest.jersey.JerseyPlugin \ No newline at end of file diff --git a/micro-jersey/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-jersey/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..2416a38a5 --- /dev/null +++ b/micro-jersey/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.rest.jersey.JerseyPlugin \ No newline at end of file diff --git a/micro-jersey/src/test/java/com/aol/micro/server/rest/jersey/JerseyRestApplicationTest.java b/micro-jersey/src/test/java/com/aol/micro/server/rest/jersey/JerseyRestApplicationTest.java deleted file mode 100644 index 31e45ab05..000000000 --- a/micro-jersey/src/test/java/com/aol/micro/server/rest/jersey/JerseyRestApplicationTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.aol.micro.server.rest.jersey; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.stream.Collectors; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import com.aol.micro.server.rest.jackson.JacksonFeature; -import com.aol.micro.server.servers.ServerThreadLocalVariables; -public class JerseyRestApplicationTest { - - - @Before - public void setup(){ - ServerThreadLocalVariables.getContext().set(Thread.currentThread().getName()); - JerseyRestApplication.getResourcesMap().put(Thread.currentThread().getName(), Arrays.asList(new ServletStatusResource())); - JerseyRestApplication.getPackages().put(Thread.currentThread().getName(), Arrays.asList()); - JerseyRestApplication.getResourcesClasses().put(Thread.currentThread().getName(), Arrays.asList(JacksonFeature.class)); - JerseyRestApplication.getServerPropertyMap().put(Thread.currentThread().getName(), new HashMap<>()); - } - - @Test - public void testDefaultConstructor() { - JerseyRestApplication app = new JerseyRestApplication(); - assertTrue(app.isRegistered(ServletStatusResource.class)); - assertThat( app.getApplication().getClasses().stream().map(c -> c.getName()).collect(Collectors.toSet()),hasItem("com.aol.micro.server.rest.jackson.JacksonFeature".intern())); - - } - - @Test - public void testDefaultConstructorCleared() { - JerseyRestApplication.getResourcesMap().clear(); - ServerThreadLocalVariables.getContext().set(Thread.currentThread().getName()); - JerseyRestApplication app = new JerseyRestApplication(); - assertThat(app.getApplication().getClasses().stream().map(c -> c.getName()).collect(Collectors.toSet()),hasItem("com.aol.micro.server.rest.jackson.JacksonFeature")); - assertFalse(app.isRegistered(ServletStatusResource.class)); - - } - - @Test @Ignore //fix up after spring / jersey integration - public void testConstructor() { - JerseyRestApplication.getResourcesMap().clear(); - JerseyRestApplication app = new JerseyRestApplication(Arrays.asList(new ServletStatusResource()), - Arrays.asList(),Arrays.asList(JacksonFeature.class), new HashMap<>()); - assertThat(app.getApplication().getClasses().size(),is(1)); - assertTrue(app.isRegistered(ServletStatusResource.class)); - } - - - - - - - -} diff --git a/micro-jersey/src/test/java/com/aol/micro/server/rest/jersey/RestContextListenerTest.java b/micro-jersey/src/test/java/com/aol/micro/server/rest/jersey/RestContextListenerTest.java deleted file mode 100644 index 70a13ee81..000000000 --- a/micro-jersey/src/test/java/com/aol/micro/server/rest/jersey/RestContextListenerTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.aol.micro.server.rest.jersey; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; - -import org.junit.Before; -import org.junit.Test; - - -import com.aol.micro.server.rest.jersey.JerseyRestApplication; -import com.aol.micro.server.rest.jersey.JerseySpringIntegrationContextListener; -import com.aol.micro.server.servers.model.ServerData; - -public class RestContextListenerTest { - - private JerseySpringIntegrationContextListener restContextListener; - private ServletStatusResource statsResource; - - @Before - public void setUp() { - statsResource = new ServletStatusResource(); - ServerData serverData = new ServerData(8080, Arrays.asList(statsResource), null, "baseUrl", () -> "test"); - restContextListener = new JerseySpringIntegrationContextListener(serverData); - } - - @Test - public void testContextInitialized() { - restContextListener.contextInitialized(null); - assertThat(JerseyRestApplication.getResourcesMap().get("test").get(0), is(statsResource)); - } - - @Test - public void testContextDestroyed() { - restContextListener.contextDestroyed(null); - } - -} diff --git a/micro-jersey/src/test/java/com/aol/micro/server/rest/jersey/ServletStatusResource.java b/micro-jersey/src/test/java/com/aol/micro/server/rest/jersey/ServletStatusResource.java deleted file mode 100644 index 5c8cf972e..000000000 --- a/micro-jersey/src/test/java/com/aol/micro/server/rest/jersey/ServletStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aol.micro.server.rest.jersey; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/servlet") -public class ServletStatusResource implements RestResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-jersey/src/test/java/com/oath/micro/server/rest/jersey/JerseyRestApplicationTest.java b/micro-jersey/src/test/java/com/oath/micro/server/rest/jersey/JerseyRestApplicationTest.java new file mode 100644 index 000000000..9ac3f9f34 --- /dev/null +++ b/micro-jersey/src/test/java/com/oath/micro/server/rest/jersey/JerseyRestApplicationTest.java @@ -0,0 +1,71 @@ +package com.oath.micro.server.rest.jersey; + +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.stream.Collectors; + +import org.glassfish.jersey.message.GZipEncoder; +import org.glassfish.jersey.server.filter.EncodingFilter; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.oath.micro.server.rest.jackson.JacksonFeature; +import com.oath.micro.server.servers.ServerThreadLocalVariables; +public class JerseyRestApplicationTest { + + + @Before + public void setup(){ + ServerThreadLocalVariables.getContext().set(Thread.currentThread().getName()); + JerseyRestApplication.getResourcesMap().put(Thread.currentThread().getName(), Arrays.asList(new ServletStatusResource())); + JerseyRestApplication.getPackages().put(Thread.currentThread().getName(), Arrays.asList()); + JerseyRestApplication.getResourcesClasses().put(Thread.currentThread().getName(), Arrays.asList(JacksonFeature.class)); + JerseyRestApplication.getServerPropertyMap().put(Thread.currentThread().getName(), new HashMap<>()); + } + + @Test + public void testDefaultConstructor() { + JerseyRestApplication app = new JerseyRestApplication(); + assertTrue(app.isRegistered(ServletStatusResource.class)); + assertThat( app.getApplication().getClasses().stream().map(c -> c.getName()).collect(Collectors.toSet()),hasItem("com.oath.micro.server.rest.jackson.JacksonFeature".intern())); + + } + + @Test + public void testDefaultConstructorCleared() { + JerseyRestApplication.getResourcesMap().clear(); + ServerThreadLocalVariables.getContext().set(Thread.currentThread().getName()); + JerseyRestApplication app = new JerseyRestApplication(); + assertThat(app.getApplication().getClasses().stream().map(c -> c.getName()).collect(Collectors.toSet()),hasItem("com.oath.micro.server.rest.jackson.JacksonFeature")); + assertFalse(app.isRegistered(ServletStatusResource.class)); + + } + + @Test @Ignore //fix up after spring / jersey integration + public void testConstructor() { + JerseyRestApplication.getResourcesMap().clear(); + JerseyRestApplication app = new JerseyRestApplication(Arrays.asList(new ServletStatusResource()), + Arrays.asList(),Arrays.asList(JacksonFeature.class), new HashMap<>()); + assertThat(app.getApplication().getClasses().size(),is(1)); + assertTrue(app.isRegistered(ServletStatusResource.class)); + } + + @Test + public void testGZipRegistration() { + JerseyRestApplication app = new JerseyRestApplication(); + assertTrue(app.isRegistered(GZipEncoder.class)); + assertTrue(app.isRegistered(EncodingFilter.class)); + } + + + + + +} diff --git a/micro-jersey/src/test/java/com/aol/micro/server/rest/jersey/JerseySpringIntegrationContextListenerTest.java b/micro-jersey/src/test/java/com/oath/micro/server/rest/jersey/JerseySpringIntegrationContextListenerTest.java similarity index 78% rename from micro-jersey/src/test/java/com/aol/micro/server/rest/jersey/JerseySpringIntegrationContextListenerTest.java rename to micro-jersey/src/test/java/com/oath/micro/server/rest/jersey/JerseySpringIntegrationContextListenerTest.java index f99d1f7ef..48660bdc2 100644 --- a/micro-jersey/src/test/java/com/aol/micro/server/rest/jersey/JerseySpringIntegrationContextListenerTest.java +++ b/micro-jersey/src/test/java/com/oath/micro/server/rest/jersey/JerseySpringIntegrationContextListenerTest.java @@ -1,15 +1,16 @@ -package com.aol.micro.server.rest.jersey; +package com.oath.micro.server.rest.jersey; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import java.util.Arrays; +import cyclops.reactive.collections.immutable.LinkedListX; import org.junit.Before; import org.junit.Test; -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.micro.server.servers.model.ServerData; +import com.oath.micro.server.servers.model.ServerData; public class JerseySpringIntegrationContextListenerTest { @@ -17,7 +18,7 @@ public class JerseySpringIntegrationContextListenerTest { ServerData serverData; @Before public void setup (){ - serverData = ServerData.builder().module(()->"hello").resources(PStackX.of()).build(); + serverData = ServerData.builder().module(()->"hello").resources(LinkedListX.of()).build(); listener = new JerseySpringIntegrationContextListener(serverData); } @@ -27,7 +28,7 @@ public void testContextInitialized() { listener.contextInitialized(null); assertThat(JerseyRestApplication.getResourcesMap().get(serverData.getModule().getContext()) - , is(serverData.getResources())); + , equalTo(Arrays.asList())); assertThat(JerseyRestApplication.getPackages().get(serverData.getModule().getContext()),is( serverData.getModule().getDefaultJaxRsPackages())); assertThat(JerseyRestApplication.getResourcesClasses().get(serverData.getModule().getContext()), is(serverData.getModule().getDefaultResources())); diff --git a/micro-jersey/src/test/java/com/oath/micro/server/rest/jersey/RestContextListenerTest.java b/micro-jersey/src/test/java/com/oath/micro/server/rest/jersey/RestContextListenerTest.java new file mode 100644 index 000000000..a958e1090 --- /dev/null +++ b/micro-jersey/src/test/java/com/oath/micro/server/rest/jersey/RestContextListenerTest.java @@ -0,0 +1,37 @@ +package com.oath.micro.server.rest.jersey; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Test; + + +import com.oath.micro.server.servers.model.ServerData; + +public class RestContextListenerTest { + + private JerseySpringIntegrationContextListener restContextListener; + private ServletStatusResource statsResource; + + @Before + public void setUp() { + statsResource = new ServletStatusResource(); + ServerData serverData = new ServerData(8080, Arrays.asList(statsResource), null, "baseUrl", () -> "test"); + restContextListener = new JerseySpringIntegrationContextListener(serverData); + } + + @Test + public void testContextInitialized() { + restContextListener.contextInitialized(null); + assertThat(JerseyRestApplication.getResourcesMap().get("test").get(0), is(statsResource)); + } + + @Test + public void testContextDestroyed() { + restContextListener.contextDestroyed(null); + } + +} diff --git a/micro-jersey/src/test/java/com/oath/micro/server/rest/jersey/ServletStatusResource.java b/micro-jersey/src/test/java/com/oath/micro/server/rest/jersey/ServletStatusResource.java new file mode 100644 index 000000000..b1f22ef75 --- /dev/null +++ b/micro-jersey/src/test/java/com/oath/micro/server/rest/jersey/ServletStatusResource.java @@ -0,0 +1,22 @@ +package com.oath.micro.server.rest.jersey; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/servlet") +public class ServletStatusResource implements RestResource { + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-jmx-metrics/README.md b/micro-jmx-metrics/README.md new file mode 100644 index 000000000..994c0cb3b --- /dev/null +++ b/micro-jmx-metrics/README.md @@ -0,0 +1,38 @@ +# JMX Metrics + + +This plugin expose JMX metrics to metricRegistry, so they can be sent to datadog using by micro-metrics-datadog + +See also [micro-metrics-datadog](https://github.com/aol/micro-server/tree/master/micro-metrics-datadog) + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-jmx-metrics/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-jmx-metrics) + +Simply add to the classpath + +Maven +```xml + + com.oath.microservices + micro-jmx-metrics + x.yz + +``` +Gradle +```groovy + compile 'com.oath.microservices:micro-jmx-metrics:x.yz' +``` + +Metrics reported by this plugin: +* jvm.heap_memory - heap memory used +* jvm.heap_memory_committed - heap memory committed +* jvm.heap_memory_init - heap memory init +* jvm.heap_memory_max - heap memory max +* jvm.non_heap_memory - non-heap memory used +* jvm.non_heap_memory_committed - non-heap memory committed +* jvm.non_heap_memory_init - non-heap memory init +* jvm.non_heap_memory_max - non-heap memory max +* jvm.thread_count - number of threads. + +Property jmx.metrics.excluded may be set to comma-separated list of those metrics. Metrics included in this list will not be reported to datadog. diff --git a/micro-jmx-metrics/build.gradle b/micro-jmx-metrics/build.gradle new file mode 100644 index 000000000..30f6e988b --- /dev/null +++ b/micro-jmx-metrics/build.gradle @@ -0,0 +1,64 @@ +description = 'micro-jmx-metrics' + +dependencies { + + compile('com.ryantenney.metrics:metrics-spring:' + springMetricsVersion) { + exclude(module: 'org.springframework') + exclude(group: 'io.dropwizard.metrics', module: 'metrics-core') + } + + compile("io.dropwizard.metrics:metrics-core:3.2.2") + + compile("com.oath.cyclops:cyclops:$cyclopsVersion") + compile project(':micro-core') + + testCompile project(':micro-grizzly-with-jersey') +} + +modifyPom { + project { + name 'Microserver jmx metrics' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2016' + + groupId 'com.oath.microservices' + artifactId 'micro-jmx-metrics' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } + } +} + +extraArchive { + sources = true + tests = true + javadoc = true +} + +nexus { + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' +} diff --git a/micro-jmx-metrics/src/main/java/com/oath/micro/server/application/metrics/jmx/JmxMetricsAcquirer.java b/micro-jmx-metrics/src/main/java/com/oath/micro/server/application/metrics/jmx/JmxMetricsAcquirer.java new file mode 100644 index 000000000..7ef5e1936 --- /dev/null +++ b/micro-jmx-metrics/src/main/java/com/oath/micro/server/application/metrics/jmx/JmxMetricsAcquirer.java @@ -0,0 +1,152 @@ +package com.oath.micro.server.application.metrics.jmx; + +import java.lang.management.ManagementFactory; +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; + +import javax.annotation.PostConstruct; +import javax.management.AttributeNotFoundException; +import javax.management.InstanceNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.ReflectionException; +import javax.management.openmbean.CompositeData; + +import cyclops.reactive.collections.mutable.MapX; +import cyclops.reactive.collections.mutable.SetX; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + + +import com.codahale.metrics.Gauge; +import com.codahale.metrics.Metric; +import com.codahale.metrics.MetricRegistry; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Component +public class JmxMetricsAcquirer { + + private static final Logger logger = LoggerFactory.getLogger(JmxMetricsAcquirer.class); + + private final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); + + private final Map metricDescriptions; + + private final int period; + + private final TimeUnit timeUnit; + + private final MetricRegistry metricRegistry; + + @AllArgsConstructor + @Getter + private class MetricDescription { + private final ObjectName objectName; + private final String name; + private final Function converter; + } + + private Function memoryConverter(String name) { + return o -> { + CompositeData cd = (CompositeData) o; + return (long) cd.get(name); + }; + } + + private Function threadsConverter() { + return o -> { + Number n = (Number) o; + return n.longValue(); + }; + } + + private Map createMetricDescriptions(String excludedString) { + MapX metricDescription = MapX.empty(); + + ObjectName memory; + try { + memory = new ObjectName("java.lang:type=Memory"); + + final ObjectName threads = new ObjectName("java.lang:type=Threading"); + + metricDescription.put("jvm.heap_memory", + new MetricDescription(memory, "HeapMemoryUsage", memoryConverter("used"))); + + metricDescription.put("jvm.heap_memory_committed", + new MetricDescription(memory, "HeapMemoryUsage", memoryConverter("committed"))); + + metricDescription.put("jvm.heap_memory_init", + new MetricDescription(memory, "HeapMemoryUsage", memoryConverter("init"))); + + metricDescription.put("jvm.heap_memory_max", + new MetricDescription(memory, "HeapMemoryUsage", memoryConverter("max"))); + + metricDescription.put("jvm.non_heap_memory", + new MetricDescription(memory, "NonHeapMemoryUsage", memoryConverter("used"))); + + metricDescription.put("jvm.non_heap_memory_committed", + new MetricDescription(memory, "NonHeapMemoryUsage", memoryConverter("committed"))); + + metricDescription.put("jvm.non_heap_memory_init", + new MetricDescription(memory, "NonHeapMemoryUsage", memoryConverter("init"))); + + metricDescription.put("jvm.non_heap_memory_max", + new MetricDescription(memory, "NonHeapMemoryUsage", memoryConverter("max"))); + + metricDescription.put("jvm.thread_count", + new MetricDescription(threads, "ThreadCount", threadsConverter())); + + } catch (MalformedObjectNameException e) { + logger.info("Can't initialize jmx metrics", e); + } + + SetX excluded = SetX.fromIterable(Arrays.asList(excludedString.split(","))); + + return metricDescription.filter(t -> !excluded.contains(t._1())); + } + + @Autowired + public JmxMetricsAcquirer(MetricRegistry metricRegistry, @Value("${datadog.report.period:1}") int period, + @Value("${datadog.report.timeunit:SECONDS}") TimeUnit timeUnit, + @Value("${jmx.metrics.excluded:}") String excluded) { + this.metricRegistry = metricRegistry; + this.period = period; + this.timeUnit = timeUnit; + this.metricDescriptions = createMetricDescriptions(excluded); + } + + @PostConstruct + public void init() { + for (Map.Entry metric : metricDescriptions.entrySet()) { + + Metric m = new Gauge() { + + @Override + public Long getValue() { + MetricDescription desc = metric.getValue(); + Object o; + try { + o = server.getAttribute(desc.getObjectName(), desc.getName()); + return metric.getValue().getConverter().apply(o); + } catch (AttributeNotFoundException | InstanceNotFoundException | MBeanException + | ReflectionException e) { + return null; + } + + } + }; + + metricRegistry.register(MetricRegistry.name(JmxMetricsAcquirer.class, metric.getKey(), metric.getKey()), m); + } + } + +} diff --git a/micro-jmx-metrics/src/main/java/com/oath/micro/server/application/metrics/jmx/JmxMetricsPlugin.java b/micro-jmx-metrics/src/main/java/com/oath/micro/server/application/metrics/jmx/JmxMetricsPlugin.java new file mode 100644 index 000000000..94f4262ba --- /dev/null +++ b/micro-jmx-metrics/src/main/java/com/oath/micro/server/application/metrics/jmx/JmxMetricsPlugin.java @@ -0,0 +1,15 @@ +package com.oath.micro.server.application.metrics.jmx; + +import com.oath.micro.server.Plugin; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +public class JmxMetricsPlugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of(JmxMetricsAcquirer.class); + } + +} diff --git a/micro-jmx-metrics/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-jmx-metrics/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..395e4f80a --- /dev/null +++ b/micro-jmx-metrics/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.application.metrics.jmx.JmxMetricsPlugin diff --git a/micro-jmx-metrics/src/test/java/com/oath/micro/server/application/metrics/jmx/JmxMetricsAcquirerTest.java b/micro-jmx-metrics/src/test/java/com/oath/micro/server/application/metrics/jmx/JmxMetricsAcquirerTest.java new file mode 100644 index 000000000..0d7ae5990 --- /dev/null +++ b/micro-jmx-metrics/src/test/java/com/oath/micro/server/application/metrics/jmx/JmxMetricsAcquirerTest.java @@ -0,0 +1,31 @@ +package com.oath.micro.server.application.metrics.jmx; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import java.util.concurrent.TimeUnit; + +import org.junit.Test; + +import com.codahale.metrics.MetricRegistry; + +public class JmxMetricsAcquirerTest { + + @Test + public void test() { + + MetricRegistry metricRegistry = mock(MetricRegistry.class); + + JmxMetricsAcquirer acquirer = new JmxMetricsAcquirer(metricRegistry, 1, TimeUnit.SECONDS, + "jvm.heap_memory_max,jvm.non_heap_memory_max"); + + acquirer.init(); + + verify(metricRegistry, times(0)).register(eq("jvm.heap_memory_max"), any()); + verify(metricRegistry, times(0)).register(eq("jvm.non_heap_memory_max"), any()); + + } +} diff --git a/micro-log-streamer/README.md b/micro-log-streamer/README.md new file mode 100644 index 000000000..5e86ebde7 --- /dev/null +++ b/micro-log-streamer/README.md @@ -0,0 +1,81 @@ +# Log Streamer plugin for Microserver + +[micro-log-streamer example apps](https://github.com/aol/micro-server/tree/master/micro-log-streamer/src/test/java/app) + +The micro-log-streamer plugin allows log files from a service to be streamed & tailed remotely via a REST endpoint. + +A target log file must be configured by the property + + log.tailer.file.location + +Optionally defining a Spring bean that implements com.aol.micro.server.log.LogLookup will allow an unrestricted number of alias' for accessible files to be defined. + +Clients can't access log files (or other files) directly, only the files configured by engineers building the service. + + +## Examples + +### Streaming the primary configured file + +To listen to the stream of data being added to our primary configured log file + +```java +new ReactiveRequest(10, 10).getTextStream("http://myhost:8080/my-app/log-tail/stream") + .forEach(System.out::println) +``` + +Or via curl +``` +curl -v http://myhost:8080/my-app/log-tail/stream +``` + +### Streaming the files using alias + + +To listen to the stream of data being added to one of our configured log files + + +```java +@Component +public class CustomAliases implements LogLookup { + + private final Map configuredAliases; + + public File lookup(String alias){ + return configuredAliases.get(alias); + } + +} +``` + +```java +new ReactiveRequest(10, 10).getTextStream("http://myhost:8080/my-app/log-tail/stream-file?alias=custom") + .forEach(System.out::println) +``` + + +Or via curl +``` +curl -v http://myhost:8080/my-app/log-tail/stream-file?alias-custom +``` + +## To use + + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-reactive/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-reactive) + +Simply add to the classpath + +Maven + ```xml + + com.oath.microservices + micro-log-streamer + x.yz + + ``` +Gradle + ```groovy + compile 'com.oath.microservices:micro-log-streamer:x.yz' + ``` + diff --git a/micro-log-streamer/build.gradle b/micro-log-streamer/build.gradle new file mode 100644 index 000000000..ac13e107b --- /dev/null +++ b/micro-log-streamer/build.gradle @@ -0,0 +1,60 @@ +description = 'micro-log-streamer' + +dependencies { + + compile project(':micro-reactive') + compile 'commons-io:commons-io:' + commonsIOVersion + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') + testCompile project(':micro-jackson-configuration') +} + +modifyPom { + project { + name 'Microserver log streamer' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2016' + + groupId 'com.oath.microservices' + artifactId 'micro-log-streamer' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + } + + } +} + +extraArchive { + sources = true + tests = true + javadoc = true +} + +nexus { + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' +} + diff --git a/micro-log-streamer/src/main/java/com/oath/micro/server/log/LogLookup.java b/micro-log-streamer/src/main/java/com/oath/micro/server/log/LogLookup.java new file mode 100644 index 000000000..70891c4cf --- /dev/null +++ b/micro-log-streamer/src/main/java/com/oath/micro/server/log/LogLookup.java @@ -0,0 +1,8 @@ +package com.oath.micro.server.log; + +import java.io.File; + +public interface LogLookup { + + public File lookup(String alias); +} diff --git a/micro-log-streamer/src/main/java/com/oath/micro/server/log/LogTailer.java b/micro-log-streamer/src/main/java/com/oath/micro/server/log/LogTailer.java new file mode 100644 index 000000000..a2444bacc --- /dev/null +++ b/micro-log-streamer/src/main/java/com/oath/micro/server/log/LogTailer.java @@ -0,0 +1,45 @@ +package com.oath.micro.server.log; + +import java.io.File; +import java.util.Optional; + +import org.apache.commons.io.input.Tailer; +import org.apache.commons.io.input.TailerListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class LogTailer { + private final String fileLocation; + private final Optional logLookup; + + @Autowired(required = false) + public LogTailer(@Value("${log.tailer.file.location:}") String fileLocation) { + this.fileLocation = fileLocation; + this.logLookup = Optional.empty(); + } + + @Autowired(required = false) + public LogTailer(@Value("${log.tailer.file.location:}") String fileLocation, LogLookup logLookup) { + this.fileLocation = fileLocation; + this.logLookup = Optional.of(logLookup); + } + + public void tail(TailerListener listener) { + + File file = new File( + fileLocation); + Tailer tailer = Tailer.create(file, listener, 10); + + tailer.run(); + } + + public void tail(TailerListener listener, String alias) { + File file = logLookup.map(l -> l.lookup(alias)) + .orElse(new File( + fileLocation)); + Tailer tailer = Tailer.create(file, listener, 10); + tailer.run(); + } +} diff --git a/micro-log-streamer/src/main/java/com/oath/micro/server/log/LogTailerPlugin.java b/micro-log-streamer/src/main/java/com/oath/micro/server/log/LogTailerPlugin.java new file mode 100644 index 000000000..7189da968 --- /dev/null +++ b/micro-log-streamer/src/main/java/com/oath/micro/server/log/LogTailerPlugin.java @@ -0,0 +1,17 @@ +package com.oath.micro.server.log; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.log.rest.LogStreamer; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +public class LogTailerPlugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of(LogTailer.class, LogStreamer.class); + } + +} diff --git a/micro-log-streamer/src/main/java/com/oath/micro/server/log/rest/LogStreamer.java b/micro-log-streamer/src/main/java/com/oath/micro/server/log/rest/LogStreamer.java new file mode 100644 index 000000000..dc1867def --- /dev/null +++ b/micro-log-streamer/src/main/java/com/oath/micro/server/log/rest/LogStreamer.java @@ -0,0 +1,149 @@ +package com.oath.micro.server.log.rest; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; + +import org.apache.commons.io.input.Tailer; +import org.apache.commons.io.input.TailerListener; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.CommonRestResource; +import com.oath.micro.server.auto.discovery.SingletonRestResource; +import com.oath.micro.server.log.LogTailer; + +import lombok.AllArgsConstructor; + +@Path("/log-tail") +@Component +public class LogStreamer implements CommonRestResource, SingletonRestResource { + + private final LogTailer tailer; + + public LogStreamer(LogTailer tailer) { + this.tailer = tailer; + } + + @GET + @Produces(MediaType.TEXT_PLAIN) + @Path("/stream-file") + public Response streamTarget(@QueryParam("alias") String alias) { + StreamingOutput stream = new StreamingOutput() { + @Override + public void write(OutputStream os) throws IOException, WebApplicationException { + Writer writer = new BufferedWriter( + new OutputStreamWriter( + + os)); + + LogListener listener = new LogListener( + writer); + + tailer.tail(listener, alias); + + } + }; + return Response.ok(stream) + .build(); + } + + @GET + @Produces(MediaType.TEXT_PLAIN) + @Path("/stream") + public Response stream() { + StreamingOutput stream = new StreamingOutput() { + @Override + public void write(OutputStream os) throws IOException, WebApplicationException { + Writer writer = new BufferedWriter( + new OutputStreamWriter( + + os)); + + LogListener listener = new LogListener( + writer); + + tailer.tail(listener); + + } + }; + return Response.ok(stream) + .build(); + } + + @AllArgsConstructor + static class LogListener implements TailerListener { + private final Writer writer; + private volatile Tailer tailer; + + @Override + public void init(Tailer tailer) { + + this.tailer = tailer; + } + + @Override + public void fileNotFound() { + try { + writer.write("File not found!"); + writer.flush(); + } catch (IOException e) { + tailer.stop(); + } + + } + + @Override + public void fileRotated() { + try { + writer.flush(); + } catch (IOException e) { + tailer.stop(); + } + } + + @Override + public void handle(String line) { + + try { + System.out.println("Writing :" + line); + writer.write(line); + writer.write("\n"); + // writer.flush(); + } catch (IOException e) { + tailer.stop(); + } + + } + + @Override + public void handle(Exception ex) { + + try { + writer.write("Error " + ex.getMessage()); + writer.write("/n"); + writer.flush(); + } catch (IOException e) { + tailer.stop(); + } + } + + private LogListener(Writer writer) { + + this.writer = writer; + this.tailer = null; + } + + } + +} \ No newline at end of file diff --git a/micro-log-streamer/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-log-streamer/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..fa28aa4a4 --- /dev/null +++ b/micro-log-streamer/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.log.LogTailerPlugin \ No newline at end of file diff --git a/micro-log-streamer/src/test/java/app/com/oath/micro/server/log/LogTest.java b/micro-log-streamer/src/test/java/app/com/oath/micro/server/log/LogTest.java new file mode 100644 index 000000000..4c9d57c98 --- /dev/null +++ b/micro-log-streamer/src/test/java/app/com/oath/micro/server/log/LogTest.java @@ -0,0 +1,75 @@ +package app.com.oath.micro.server.log; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +import org.apache.commons.io.FileUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.reactive.rest.ReactiveRequest; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { "log.tailer.file.location", "/tmp/tailer-test-file" }) +public class LogTest implements RestResource { + + RestAgent rest = new RestAgent(); + File testFile = new File( + "/tmp/tailer-test-file"); + + MicroserverApp server; + + static String lastRecieved = null; + + @Before + public void startServer() throws IOException { + lastRecieved = null; + + testFile.delete(); + server = new MicroserverApp( + () -> "log-app"); + server.start(); + FileUtils.write(testFile, "hello world", "UTF-8", false); + new Thread( + () -> { + for (int i = 0; i < 1_000; i++) { + try { + FileUtils.write(testFile, "new line " + i + "\n", "UTF-8", true); + Thread.sleep(1); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }).start(); + } + + @After + public void stopServer() { + server.stop(); + } + + + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + int read = new ReactiveRequest( + 10000, 10000).getTextStream("http://localhost:8080/log-app/log-tail/stream") + .limit(5) + .toList() + .size(); + + assertThat(read, equalTo(5)); + + } + +} \ No newline at end of file diff --git a/micro-log-streamer/src/test/java/app/com/oath/micro/server/log/alias/CustomAlias.java b/micro-log-streamer/src/test/java/app/com/oath/micro/server/log/alias/CustomAlias.java new file mode 100644 index 000000000..07ef7d5ed --- /dev/null +++ b/micro-log-streamer/src/test/java/app/com/oath/micro/server/log/alias/CustomAlias.java @@ -0,0 +1,26 @@ +package app.com.oath.micro.server.log.alias; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.log.LogLookup; + +@Component +public class CustomAlias implements LogLookup { + + private final Map configuredAliases = new HashMap() { + { + put("custom1", new File( + "/tmp/tailer-test-file2")); + } + }; + + @Override + public File lookup(String alias) { + return configuredAliases.get(alias); + } + +} diff --git a/micro-log-streamer/src/test/java/app/com/oath/micro/server/log/alias/CustomAliasLogTest.java b/micro-log-streamer/src/test/java/app/com/oath/micro/server/log/alias/CustomAliasLogTest.java new file mode 100644 index 000000000..98784d26e --- /dev/null +++ b/micro-log-streamer/src/test/java/app/com/oath/micro/server/log/alias/CustomAliasLogTest.java @@ -0,0 +1,75 @@ +package app.com.oath.micro.server.log.alias; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +import org.apache.commons.io.FileUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.reactive.rest.ReactiveRequest; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties = { "log.tailer.file.location", "/tmp/tailer-test-file" }) +public class CustomAliasLogTest implements RestResource { + + RestAgent rest = new RestAgent(); + File testFile = new File( + "/tmp/tailer-test-file2"); + + MicroserverApp server; + + static String lastRecieved = null; + + @Before + public void startServer() throws IOException { + lastRecieved = null; + + testFile.delete(); + server = new MicroserverApp( + () -> "log-app"); + server.start(); + FileUtils.write(testFile, "hello world", "UTF-8", false); + new Thread( + () -> { + for (int i = 0; i < 1_000; i++) { + try { + FileUtils.write(testFile, "new line " + i + "\n", "UTF-8", true); + Thread.sleep(1); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }).start(); + } + + @After + public void stopServer() { + server.stop(); + } + + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + int read = new ReactiveRequest( + 10000, + 10000).getTextStream("http://localhost:8080/log-app/log-tail/stream-file?alias=custom1") + .limit(5) + .toList() + .size(); + + assertThat(read, equalTo(5)); + + } + +} \ No newline at end of file diff --git a/micro-log-streamer/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-log-streamer/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-log-streamer/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-log4j/README.md b/micro-log4j/README.md new file mode 100644 index 000000000..7d45d4cfa --- /dev/null +++ b/micro-log4j/README.md @@ -0,0 +1,71 @@ +# Log4j plugin for Microserver + +[Example micro-log4j Apps](https://github.com/aol/micro-server/tree/master/micro-log4j/src/test/java/app) + +micro-log4j plugin can be used in two ways: + +1. Rest resources provided by this plugin can be used to manually control logging levels +2. Log4jRootLoggerChecker can be used to automatically bring logging level to a specified one for rootLogger + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-log4j/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-log4j) + +Simply add to the classpath + +Maven +```xml + + com.oath.microservices + micro-log4j + x.yz + +``` +Gradle +```groovy + compile 'com.oath.microservices:micro-log4j:x.yz' +``` + +# Configuration endpoints + +## For Root Logger + +* /log4j/rootlogger/get/level +* /log4j/rootlogger/change/to/all +* /log4j/rootlogger/change/to/debug +* /log4j/rootlogger/change/to/error +* /log4j/rootlogger/change/to/fatal +* /log4j/rootlogger/change/to/info +* /log4j/rootlogger/change/to/of +* /log4j/rootlogger/change/to/trace +* /log4j/rootlogger/change/to/warn + +## For a 'targetable' logger + +* /log4j/logger/get/level/{loggerName} +* /log4j/rootlogger/change/to/all/{loggerName} +* /log4j/rootlogger/change/to/debug/{loggerName} +* /log4j/rootlogger/change/to/error/{loggerName} +* /log4j/rootlogger/change/to/fatal/{loggerName} +* /log4j/rootlogger/change/to/info/{loggerName} +* /log4j/rootlogger/change/to/of/{loggerName} +* /log4j/rootlogger/change/to/trace/{loggerName} +* /log4j/rootlogger/change/to/warn/{loggerName} + +# Configuring Log4jRootLoggerChecker + +This is a scheduled job that periodically enforces a specified log level. For example, you can be sure that any attempt at changing the log level to DEBUG or TRACE via a Rest call is purely temporary and will be reset to INFO by the checker. + +Log4jRootLoggerChecker can be configured by setting the following properties in application.properties, instance.properties or via the Microserver annotation + + log4j.root.logger.checker.active: (e.g. true | false) + log4j.root.logger.checker.correct.level: (e.g. INFO) + log4j.root.logger.checker.fixed.rate: (e.g. 5000) + +Users can also use Log4jRootLoggerResource to change either log4j.root.logger.checker.active or log4j.root.logger.checker.correct.level at runtime + +## Checker endpoints + + +* /log4j/rootlogger/checker/is/{active} = true | false +* /log4j/rootlogger/checker/level/{correctLevelStr} = all | debug | error | info | warn | fatal | trace diff --git a/micro-log4j/build.gradle b/micro-log4j/build.gradle index 9e8c12bb7..1f8250535 100644 --- a/micro-log4j/build.gradle +++ b/micro-log4j/build.gradle @@ -1,72 +1,73 @@ description = 'micro-log4j' -dependencies { - compile project(':micro-core') - compile ('log4j:log4j:' + log4jVersion) { - exclude(group: 'com.sun.jmx', module: 'jmxri') - exclude(group: 'javax.jms', module: 'jms') - exclude(group: 'com.sun.jdmk', module: 'jmxtools') - } - - testCompile project(':micro-client') - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') + +dependencies { + compile project(':micro-core') + compile('log4j:log4j:' + log4jVersion) { + exclude(group: 'com.sun.jmx', module: 'jmxri') + exclude(group: 'javax.jms', module: 'jms') + exclude(group: 'com.sun.jdmk', module: 'jmxtools') + } + + testCompile project(':micro-client') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') } modifyPom { - project { - name 'Microserver log4j' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver log4j' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-log4j' + version "$version" + - groupId 'com.aol.microservices' - artifactId 'micro-log4j' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - developer { - id 'earlzero' - name 'Nikita Sapozhnikov' - email 'nikita.sapozhnikov@teamaol.com' - } - } - } + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-log4j/readme.md b/micro-log4j/readme.md deleted file mode 100644 index 7a655efb0..000000000 --- a/micro-log4j/readme.md +++ /dev/null @@ -1,71 +0,0 @@ -# Log4j plugin for Microserver - -[Example micro-log4j Apps](https://github.com/aol/micro-server/tree/master/micro-log4j/src/test/java/app) - -micro-log4j plugin can be used in two ways: - -1. Rest resources provided by this plugin can be used to manually control logging levels -2. Log4jRootLoggerChecker can be used to automatically bring logging level to a specified one for rootLogger - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-log4j/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-log4j) - -Simply add to the classpath - -Maven -```xml - - com.aol.microservices - micro-log4j - x.yz - -``` -Gradle -```groovy - compile 'com.aol.microservices:micro-log4j:x.yz' -``` - -# Configuration endpoints - -## For Root Logger - -* /log4j/rootlogger/get/level -* /log4j/rootlogger/change/to/all -* /log4j/rootlogger/change/to/debug -* /log4j/rootlogger/change/to/error -* /log4j/rootlogger/change/to/fatal -* /log4j/rootlogger/change/to/info -* /log4j/rootlogger/change/to/of -* /log4j/rootlogger/change/to/trace -* /log4j/rootlogger/change/to/warn - -## For a 'targetable' logger - -* /log4j/logger/get/level/{loggerName} -* /log4j/rootlogger/change/to/all/{loggerName} -* /log4j/rootlogger/change/to/debug/{loggerName} -* /log4j/rootlogger/change/to/error/{loggerName} -* /log4j/rootlogger/change/to/fatal/{loggerName} -* /log4j/rootlogger/change/to/info/{loggerName} -* /log4j/rootlogger/change/to/of/{loggerName} -* /log4j/rootlogger/change/to/trace/{loggerName} -* /log4j/rootlogger/change/to/warn/{loggerName} - -# Configuring Log4jRootLoggerChecker - -This is a scheduled job that periodically enforces a specified log level. For example, you can be sure that any attempt at changing the log level to DEBUG or TRACE via a Rest call is purely temporary and will be reset to INFO by the checker. - -Log4jRootLoggerChecker can be configured by setting the following properties in application.properties, instance.properties or via the Microserver annotation - - log4j.root.logger.checker.active: (e.g. true | false) - log4j.root.logger.checker.correct.level: (e.g. INFO) - log4j.root.logger.checker.fixed.rate: (e.g. 5000) - -Users can also use Log4jRootLoggerResource to change either log4j.root.logger.checker.active or log4j.root.logger.checker.correct.level at runtime - -## Checker endpoints - - -* /log4j/rootlogger/checker/is/{active} = true | false -* /log4j/rootlogger/checker/level/{correctLevelStr} = all | debug | error | info | warn | fatal | trace \ No newline at end of file diff --git a/micro-log4j/src/main/java/com/aol/micro/server/log4j/Log4jPlugin.java b/micro-log4j/src/main/java/com/aol/micro/server/log4j/Log4jPlugin.java deleted file mode 100644 index 0a827c01b..000000000 --- a/micro-log4j/src/main/java/com/aol/micro/server/log4j/Log4jPlugin.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.aol.micro.server.log4j; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.log4j.rest.Log4jLoggerResource; -import com.aol.micro.server.log4j.rest.Log4jRootLoggerResource; -import com.aol.micro.server.log4j.service.Log4jRootLoggerChecker; - -/** - * - * @author Ke Wang - * - */ -public class Log4jPlugin implements Plugin { - @Override - public PSetX springClasses() { - return PSetX.of(Log4jRootLoggerResource.class, Log4jLoggerResource.class, Log4jRootLoggerChecker.class); - } - -} diff --git a/micro-log4j/src/main/java/com/oath/micro/server/log4j/Log4jPlugin.java b/micro-log4j/src/main/java/com/oath/micro/server/log4j/Log4jPlugin.java new file mode 100644 index 000000000..bbbb033a9 --- /dev/null +++ b/micro-log4j/src/main/java/com/oath/micro/server/log4j/Log4jPlugin.java @@ -0,0 +1,23 @@ +package com.oath.micro.server.log4j; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.log4j.rest.Log4jLoggerResource; +import com.oath.micro.server.log4j.rest.Log4jRootLoggerResource; +import com.oath.micro.server.log4j.service.Log4jRootLoggerChecker; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +/** + * + * @author Ke Wang + * + */ +public class Log4jPlugin implements Plugin { + @Override + public Set springClasses() { + return SetX.of(Log4jRootLoggerResource.class, Log4jLoggerResource.class, Log4jRootLoggerChecker.class); + } + +} diff --git a/micro-log4j/src/main/java/com/aol/micro/server/log4j/rest/Log4jLoggerResource.java b/micro-log4j/src/main/java/com/oath/micro/server/log4j/rest/Log4jLoggerResource.java similarity index 95% rename from micro-log4j/src/main/java/com/aol/micro/server/log4j/rest/Log4jLoggerResource.java rename to micro-log4j/src/main/java/com/oath/micro/server/log4j/rest/Log4jLoggerResource.java index b2920cedb..0839cf591 100644 --- a/micro-log4j/src/main/java/com/aol/micro/server/log4j/rest/Log4jLoggerResource.java +++ b/micro-log4j/src/main/java/com/oath/micro/server/log4j/rest/Log4jLoggerResource.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.log4j.rest; +package com.oath.micro.server.log4j.rest; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -10,7 +10,7 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.aol.micro.server.auto.discovery.SingletonRestResource; +import com.oath.micro.server.auto.discovery.SingletonRestResource; @Component @Path("/log4j/logger") diff --git a/micro-log4j/src/main/java/com/aol/micro/server/log4j/rest/Log4jRootLoggerResource.java b/micro-log4j/src/main/java/com/oath/micro/server/log4j/rest/Log4jRootLoggerResource.java similarity index 92% rename from micro-log4j/src/main/java/com/aol/micro/server/log4j/rest/Log4jRootLoggerResource.java rename to micro-log4j/src/main/java/com/oath/micro/server/log4j/rest/Log4jRootLoggerResource.java index 6f666b14a..fb3803be7 100644 --- a/micro-log4j/src/main/java/com/aol/micro/server/log4j/rest/Log4jRootLoggerResource.java +++ b/micro-log4j/src/main/java/com/oath/micro/server/log4j/rest/Log4jRootLoggerResource.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.log4j.rest; +package com.oath.micro.server.log4j.rest; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -6,14 +6,13 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.aol.micro.server.auto.discovery.SingletonRestResource; -import com.aol.micro.server.log4j.service.Log4jRootLoggerChecker; +import com.oath.micro.server.auto.discovery.SingletonRestResource; +import com.oath.micro.server.log4j.service.Log4jRootLoggerChecker; @Component @Path("/log4j/rootlogger") diff --git a/micro-log4j/src/main/java/com/aol/micro/server/log4j/service/Log4jRootLoggerChecker.java b/micro-log4j/src/main/java/com/oath/micro/server/log4j/service/Log4jRootLoggerChecker.java similarity index 96% rename from micro-log4j/src/main/java/com/aol/micro/server/log4j/service/Log4jRootLoggerChecker.java rename to micro-log4j/src/main/java/com/oath/micro/server/log4j/service/Log4jRootLoggerChecker.java index f6cd4711d..db9faee36 100644 --- a/micro-log4j/src/main/java/com/aol/micro/server/log4j/service/Log4jRootLoggerChecker.java +++ b/micro-log4j/src/main/java/com/oath/micro/server/log4j/service/Log4jRootLoggerChecker.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.log4j.service; +package com.oath.micro.server.log4j.service; import lombok.Getter; import lombok.Setter; diff --git a/micro-log4j/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-log4j/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 32bf35904..000000000 --- a/micro-log4j/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.log4j.Log4jPlugin diff --git a/micro-log4j/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-log4j/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..a3cd47304 --- /dev/null +++ b/micro-log4j/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.log4j.Log4jPlugin diff --git a/micro-log4j/src/test/java/app/level/checker/Log4jRootLoggerChekerRunnerTest.java b/micro-log4j/src/test/java/app/level/checker/Log4jRootLoggerChekerRunnerTest.java index 8709ec724..c3ac02426 100644 --- a/micro-log4j/src/test/java/app/level/checker/Log4jRootLoggerChekerRunnerTest.java +++ b/micro-log4j/src/test/java/app/level/checker/Log4jRootLoggerChekerRunnerTest.java @@ -7,9 +7,9 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; @Microserver(properties = { "log4j.root.logger.checker.fixed.rate", "1500" }) public class Log4jRootLoggerChekerRunnerTest { diff --git a/micro-log4j/src/test/java/app/level/setter/Log4jRootLoggerRunnerTest.java b/micro-log4j/src/test/java/app/level/setter/Log4jRootLoggerRunnerTest.java index 6ab10be4b..77939815b 100644 --- a/micro-log4j/src/test/java/app/level/setter/Log4jRootLoggerRunnerTest.java +++ b/micro-log4j/src/test/java/app/level/setter/Log4jRootLoggerRunnerTest.java @@ -7,9 +7,9 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; @Microserver(properties = { "log4j.root.logger.checker.active", "false" }) public class Log4jRootLoggerRunnerTest { diff --git a/micro-log4j/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-log4j/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index 0f68164b7..000000000 --- a/micro-log4j/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.aol.micro.server.testing; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-log4j/src/test/java/com/aol/micro/server/log4j/rest/Log4jLoggerResourceTest.java b/micro-log4j/src/test/java/com/oath/micro/server/log4j/rest/Log4jLoggerResourceTest.java similarity index 96% rename from micro-log4j/src/test/java/com/aol/micro/server/log4j/rest/Log4jLoggerResourceTest.java rename to micro-log4j/src/test/java/com/oath/micro/server/log4j/rest/Log4jLoggerResourceTest.java index 7a7da578d..a3230ba92 100644 --- a/micro-log4j/src/test/java/com/aol/micro/server/log4j/rest/Log4jLoggerResourceTest.java +++ b/micro-log4j/src/test/java/com/oath/micro/server/log4j/rest/Log4jLoggerResourceTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.log4j.rest; +package com.oath.micro.server.log4j.rest; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; diff --git a/micro-log4j/src/test/java/com/aol/micro/server/log4j/rest/Log4jLoggerRunnerTest.java b/micro-log4j/src/test/java/com/oath/micro/server/log4j/rest/Log4jLoggerRunnerTest.java similarity index 76% rename from micro-log4j/src/test/java/com/aol/micro/server/log4j/rest/Log4jLoggerRunnerTest.java rename to micro-log4j/src/test/java/com/oath/micro/server/log4j/rest/Log4jLoggerRunnerTest.java index 7d9c0c452..776de5fe9 100644 --- a/micro-log4j/src/test/java/com/aol/micro/server/log4j/rest/Log4jLoggerRunnerTest.java +++ b/micro-log4j/src/test/java/com/oath/micro/server/log4j/rest/Log4jLoggerRunnerTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.log4j.rest; +package com.oath.micro.server.log4j.rest; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -7,9 +7,9 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; @Microserver public class Log4jLoggerRunnerTest { diff --git a/micro-log4j/src/test/java/com/aol/micro/server/log4j/rest/Log4jRootLoggerResourceTest.java b/micro-log4j/src/test/java/com/oath/micro/server/log4j/rest/Log4jRootLoggerResourceTest.java similarity index 96% rename from micro-log4j/src/test/java/com/aol/micro/server/log4j/rest/Log4jRootLoggerResourceTest.java rename to micro-log4j/src/test/java/com/oath/micro/server/log4j/rest/Log4jRootLoggerResourceTest.java index 45538ff2a..f9c0156b9 100644 --- a/micro-log4j/src/test/java/com/aol/micro/server/log4j/rest/Log4jRootLoggerResourceTest.java +++ b/micro-log4j/src/test/java/com/oath/micro/server/log4j/rest/Log4jRootLoggerResourceTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.log4j.rest; +package com.oath.micro.server.log4j.rest; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; diff --git a/micro-log4j/src/test/java/com/aol/micro/server/logback/service/Log4jRootLoggerCheckerTest.java b/micro-log4j/src/test/java/com/oath/micro/server/logback/service/Log4jRootLoggerCheckerTest.java similarity index 87% rename from micro-log4j/src/test/java/com/aol/micro/server/logback/service/Log4jRootLoggerCheckerTest.java rename to micro-log4j/src/test/java/com/oath/micro/server/logback/service/Log4jRootLoggerCheckerTest.java index 96f683ed6..e3022263c 100644 --- a/micro-log4j/src/test/java/com/aol/micro/server/logback/service/Log4jRootLoggerCheckerTest.java +++ b/micro-log4j/src/test/java/com/oath/micro/server/logback/service/Log4jRootLoggerCheckerTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.logback.service; +package com.oath.micro.server.logback.service; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -8,7 +8,7 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.log4j.service.Log4jRootLoggerChecker; +import com.oath.micro.server.log4j.service.Log4jRootLoggerChecker; diff --git a/micro-log4j/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-log4j/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-log4j/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-logback/README.md b/micro-logback/README.md new file mode 100644 index 000000000..635c401cd --- /dev/null +++ b/micro-logback/README.md @@ -0,0 +1,73 @@ +# Logback plugin for Microserver + +[Example micro-logback Apps](https://github.com/aol/micro-server/tree/master/micro-log4j/src/test/java/app) + +micro-logback plugin can be used in two ways: + +1. Rest resources provided by this plugin can be used to manually control logging levels +2. LogbackRootLoggerChecker can be used to automatically bring logging level to a specified one for rootLogger + + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-logback/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-logback) + +Simply add to the classpath + +Maven + +```xml + + com.oath.microservices + micro-logback + x.yz + +``` +Gradle +```groovy + compile 'com.oath.microservices:micro-logback:x.yz' +``` + +# Configuration endpoints + +## For Root Logger + +* /logback/rootlogger/get/level +* /logback/rootlogger/change/to/all +* /logback/rootlogger/change/to/debug +* /logback/rootlogger/change/to/error +* /logback/rootlogger/change/to/fatal +* /logback/rootlogger/change/to/info +* /logback/rootlogger/change/to/of +* /logback/rootlogger/change/to/trace +* /logback/rootlogger/change/to/warn + +## For a 'targetable' logger + +* /logback/logger/get/level/{loggerName} +* /logback/rootlogger/change/to/all/{loggerName} +* /logback/rootlogger/change/to/debug/{loggerName} +* /logback/rootlogger/change/to/error/{loggerName} +* /logback/rootlogger/change/to/fatal/{loggerName} +* /logback/rootlogger/change/to/info/{loggerName} +* /logback/rootlogger/change/to/of/{loggerName} +* /logback/rootlogger/change/to/trace/{loggerName} +* /logback/rootlogger/change/to/warn/{loggerName} + +# Configuring LogbackRootLoggerChecker + +This is a scheduled job that periodically enforces a specified log level. For example, you can be sure that any attempt at changing the log level to DEBUG or TRACE via a Rest call is purely temporary and will be reset to INFO by the checker. + +LogbackRootLoggerChecker can be configured by setting the following properties in application.properties, instance.properties or via the Microserver annotation + + logback.root.logger.checker.active: (e.g. true | false) + logback.root.logger.checker.correct.level: (e.g. INFO) + logback.root.logger.checker.fixed.rate: (e.g. 5000) + +Users can also use LogbackRootLoggerResource to change either logback.root.logger.checker.active or logback.root.logger.checker.correct.level at runtime + +## Checker endpoints + + +* /logback/rootlogger/checker/is/{active} = true | false +* /logback/rootlogger/checker/level/{correctLevelStr} = all | debug | error | info | warn | fatal | trace diff --git a/micro-logback/build.gradle b/micro-logback/build.gradle index f60e1513e..be3f513f2 100644 --- a/micro-logback/build.gradle +++ b/micro-logback/build.gradle @@ -1,67 +1,67 @@ description = 'micro-logback' -dependencies { - compile project(':micro-core') - - testCompile project(':micro-client') - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') + +dependencies { + compile project(':micro-core') + testCompile project(':micro-client') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') } modifyPom { - project { - name 'Microserver logback' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver logback' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-logback' + version "$version" + - groupId 'com.aol.microservices' - artifactId 'micro-logback' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - developer { - id 'earlzero' - name 'Nikita Sapozhnikov' - email 'nikita.sapozhnikov@teamaol.com' - } - } - } + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-logback/readme.md b/micro-logback/readme.md deleted file mode 100644 index 18154907b..000000000 --- a/micro-logback/readme.md +++ /dev/null @@ -1,73 +0,0 @@ -# Logback plugin for Microserver - -[Example micro-logback Apps](https://github.com/aol/micro-server/tree/master/micro-log4j/src/test/java/app) - -micro-logback plugin can be used in two ways: - -1. Rest resources provided by this plugin can be used to manually control logging levels -2. LogbackRootLoggerChecker can be used to automatically bring logging level to a specified one for rootLogger - - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-logback/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-logback) - -Simply add to the classpath - -Maven - -```xml - - com.aol.microservices - micro-logback - x.yz - -``` -Gradle -```groovy - compile 'com.aol.microservices:micro-logback:x.yz' -``` - -# Configuration endpoints - -## For Root Logger - -* /logback/rootlogger/get/level -* /logback/rootlogger/change/to/all -* /logback/rootlogger/change/to/debug -* /logback/rootlogger/change/to/error -* /logback/rootlogger/change/to/fatal -* /logback/rootlogger/change/to/info -* /logback/rootlogger/change/to/of -* /logback/rootlogger/change/to/trace -* /logback/rootlogger/change/to/warn - -## For a 'targetable' logger - -* /logback/logger/get/level/{loggerName} -* /logback/rootlogger/change/to/all/{loggerName} -* /logback/rootlogger/change/to/debug/{loggerName} -* /logback/rootlogger/change/to/error/{loggerName} -* /logback/rootlogger/change/to/fatal/{loggerName} -* /logback/rootlogger/change/to/info/{loggerName} -* /logback/rootlogger/change/to/of/{loggerName} -* /logback/rootlogger/change/to/trace/{loggerName} -* /logback/rootlogger/change/to/warn/{loggerName} - -# Configuring LogbackRootLoggerChecker - -This is a scheduled job that periodically enforces a specified log level. For example, you can be sure that any attempt at changing the log level to DEBUG or TRACE via a Rest call is purely temporary and will be reset to INFO by the checker. - -LogbackRootLoggerChecker can be configured by setting the following properties in application.properties, instance.properties or via the Microserver annotation - - logback.root.logger.checker.active: (e.g. true | false) - logback.root.logger.checker.correct.level: (e.g. INFO) - logback.root.logger.checker.fixed.rate: (e.g. 5000) - -Users can also use LogbackRootLoggerResource to change either logback.root.logger.checker.active or logback.root.logger.checker.correct.level at runtime - -## Checker endpoints - - -* /logback/rootlogger/checker/is/{active} = true | false -* /logback/rootlogger/checker/level/{correctLevelStr} = all | debug | error | info | warn | fatal | trace diff --git a/micro-logback/src/main/java/com/aol/micro/server/logback/LogbackPlugin.java b/micro-logback/src/main/java/com/aol/micro/server/logback/LogbackPlugin.java deleted file mode 100644 index 7ed0aabe3..000000000 --- a/micro-logback/src/main/java/com/aol/micro/server/logback/LogbackPlugin.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.aol.micro.server.logback; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.logback.rest.LogbackLoggerResource; -import com.aol.micro.server.logback.rest.LogbackRootLoggerResource; -import com.aol.micro.server.logback.service.LogbackRootLoggerChecker; - -/** - * - * @author Ke Wang - * - */ -public class LogbackPlugin implements Plugin { - @Override - public PSetX springClasses() { - return PSetX.of(LogbackRootLoggerResource.class, LogbackRootLoggerChecker.class, LogbackLoggerResource.class); - } - -} diff --git a/micro-logback/src/main/java/com/oath/micro/server/logback/LogbackPlugin.java b/micro-logback/src/main/java/com/oath/micro/server/logback/LogbackPlugin.java new file mode 100644 index 000000000..8a9d35bfc --- /dev/null +++ b/micro-logback/src/main/java/com/oath/micro/server/logback/LogbackPlugin.java @@ -0,0 +1,23 @@ +package com.oath.micro.server.logback; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.logback.rest.LogbackLoggerResource; +import com.oath.micro.server.logback.rest.LogbackRootLoggerResource; +import com.oath.micro.server.logback.service.LogbackRootLoggerChecker; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +/** + * + * @author Ke Wang + * + */ +public class LogbackPlugin implements Plugin { + @Override + public Set springClasses() { + return SetX.of(LogbackRootLoggerResource.class, LogbackRootLoggerChecker.class, LogbackLoggerResource.class); + } + +} diff --git a/micro-logback/src/main/java/com/aol/micro/server/logback/rest/LogbackLoggerResource.java b/micro-logback/src/main/java/com/oath/micro/server/logback/rest/LogbackLoggerResource.java similarity index 96% rename from micro-logback/src/main/java/com/aol/micro/server/logback/rest/LogbackLoggerResource.java rename to micro-logback/src/main/java/com/oath/micro/server/logback/rest/LogbackLoggerResource.java index bf3a1024f..30faf998a 100644 --- a/micro-logback/src/main/java/com/aol/micro/server/logback/rest/LogbackLoggerResource.java +++ b/micro-logback/src/main/java/com/oath/micro/server/logback/rest/LogbackLoggerResource.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.logback.rest; +package com.oath.micro.server.logback.rest; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -12,7 +12,7 @@ import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; -import com.aol.micro.server.auto.discovery.SingletonRestResource; +import com.oath.micro.server.auto.discovery.SingletonRestResource; @Component @Path("/logback/logger") diff --git a/micro-logback/src/main/java/com/aol/micro/server/logback/rest/LogbackRootLoggerResource.java b/micro-logback/src/main/java/com/oath/micro/server/logback/rest/LogbackRootLoggerResource.java similarity index 93% rename from micro-logback/src/main/java/com/aol/micro/server/logback/rest/LogbackRootLoggerResource.java rename to micro-logback/src/main/java/com/oath/micro/server/logback/rest/LogbackRootLoggerResource.java index 70208c22c..aa3061436 100644 --- a/micro-logback/src/main/java/com/aol/micro/server/logback/rest/LogbackRootLoggerResource.java +++ b/micro-logback/src/main/java/com/oath/micro/server/logback/rest/LogbackRootLoggerResource.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.logback.rest; +package com.oath.micro.server.logback.rest; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -13,8 +13,8 @@ import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; -import com.aol.micro.server.auto.discovery.SingletonRestResource; -import com.aol.micro.server.logback.service.LogbackRootLoggerChecker; +import com.oath.micro.server.auto.discovery.SingletonRestResource; +import com.oath.micro.server.logback.service.LogbackRootLoggerChecker; @Component @Path("/logback/rootlogger") diff --git a/micro-logback/src/main/java/com/aol/micro/server/logback/service/LogbackRootLoggerChecker.java b/micro-logback/src/main/java/com/oath/micro/server/logback/service/LogbackRootLoggerChecker.java similarity index 96% rename from micro-logback/src/main/java/com/aol/micro/server/logback/service/LogbackRootLoggerChecker.java rename to micro-logback/src/main/java/com/oath/micro/server/logback/service/LogbackRootLoggerChecker.java index 55d4c7e8e..e0fa676a2 100644 --- a/micro-logback/src/main/java/com/aol/micro/server/logback/service/LogbackRootLoggerChecker.java +++ b/micro-logback/src/main/java/com/oath/micro/server/logback/service/LogbackRootLoggerChecker.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.logback.service; +package com.oath.micro.server.logback.service; import lombok.Getter; import lombok.Setter; diff --git a/micro-logback/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-logback/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 052705e35..000000000 --- a/micro-logback/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.logback.LogbackPlugin diff --git a/micro-logback/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-logback/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..8ed39f127 --- /dev/null +++ b/micro-logback/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.logback.LogbackPlugin diff --git a/micro-logback/src/test/java/app/level/checker/LogbackRootLoggerChekerRunnerTest.java b/micro-logback/src/test/java/app/level/checker/LogbackRootLoggerChekerRunnerTest.java index addec8120..9ab7f5f58 100644 --- a/micro-logback/src/test/java/app/level/checker/LogbackRootLoggerChekerRunnerTest.java +++ b/micro-logback/src/test/java/app/level/checker/LogbackRootLoggerChekerRunnerTest.java @@ -7,9 +7,9 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; @Microserver(properties = { "logback.root.logger.checker.fixed.rate", "1500" }) public class LogbackRootLoggerChekerRunnerTest { diff --git a/micro-logback/src/test/java/app/level/setter/LogbackRootLoggerRunnerTest.java b/micro-logback/src/test/java/app/level/setter/LogbackRootLoggerRunnerTest.java index 3f1aa00d8..f0db26895 100644 --- a/micro-logback/src/test/java/app/level/setter/LogbackRootLoggerRunnerTest.java +++ b/micro-logback/src/test/java/app/level/setter/LogbackRootLoggerRunnerTest.java @@ -7,9 +7,9 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; @Microserver(properties = { "log4j.root.logger.checker.active", "false" }) public class LogbackRootLoggerRunnerTest { diff --git a/micro-logback/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-logback/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index 0f68164b7..000000000 --- a/micro-logback/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.aol.micro.server.testing; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-logback/src/test/java/com/aol/micro/server/log4j/service/LogbackRootLoggerCheckerTest.java b/micro-logback/src/test/java/com/oath/micro/server/log4j/service/LogbackRootLoggerCheckerTest.java similarity index 89% rename from micro-logback/src/test/java/com/aol/micro/server/log4j/service/LogbackRootLoggerCheckerTest.java rename to micro-logback/src/test/java/com/oath/micro/server/log4j/service/LogbackRootLoggerCheckerTest.java index 23b09391d..6a9936508 100644 --- a/micro-logback/src/test/java/com/aol/micro/server/log4j/service/LogbackRootLoggerCheckerTest.java +++ b/micro-logback/src/test/java/com/oath/micro/server/log4j/service/LogbackRootLoggerCheckerTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.log4j.service; +package com.oath.micro.server.log4j.service; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -10,7 +10,7 @@ import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; -import com.aol.micro.server.logback.service.LogbackRootLoggerChecker; +import com.oath.micro.server.logback.service.LogbackRootLoggerChecker; diff --git a/micro-logback/src/test/java/com/aol/micro/server/logback/rest/LogbackLoggerResourceTest.java b/micro-logback/src/test/java/com/oath/micro/server/logback/rest/LogbackLoggerResourceTest.java similarity index 96% rename from micro-logback/src/test/java/com/aol/micro/server/logback/rest/LogbackLoggerResourceTest.java rename to micro-logback/src/test/java/com/oath/micro/server/logback/rest/LogbackLoggerResourceTest.java index 824903059..f8e9e693c 100644 --- a/micro-logback/src/test/java/com/aol/micro/server/logback/rest/LogbackLoggerResourceTest.java +++ b/micro-logback/src/test/java/com/oath/micro/server/logback/rest/LogbackLoggerResourceTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.logback.rest; +package com.oath.micro.server.logback.rest; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; diff --git a/micro-logback/src/test/java/com/aol/micro/server/logback/rest/LogbackLoggerRunnerTest.java b/micro-logback/src/test/java/com/oath/micro/server/logback/rest/LogbackLoggerRunnerTest.java similarity index 76% rename from micro-logback/src/test/java/com/aol/micro/server/logback/rest/LogbackLoggerRunnerTest.java rename to micro-logback/src/test/java/com/oath/micro/server/logback/rest/LogbackLoggerRunnerTest.java index bbd59ff9b..dd4192948 100644 --- a/micro-logback/src/test/java/com/aol/micro/server/logback/rest/LogbackLoggerRunnerTest.java +++ b/micro-logback/src/test/java/com/oath/micro/server/logback/rest/LogbackLoggerRunnerTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.logback.rest; +package com.oath.micro.server.logback.rest; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -7,9 +7,9 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; @Microserver public class LogbackLoggerRunnerTest { diff --git a/micro-logback/src/test/java/com/aol/micro/server/logback/rest/LogbackRootLoggerResourceTest.java b/micro-logback/src/test/java/com/oath/micro/server/logback/rest/LogbackRootLoggerResourceTest.java similarity index 95% rename from micro-logback/src/test/java/com/aol/micro/server/logback/rest/LogbackRootLoggerResourceTest.java rename to micro-logback/src/test/java/com/oath/micro/server/logback/rest/LogbackRootLoggerResourceTest.java index f630d553c..266aaaa75 100644 --- a/micro-logback/src/test/java/com/aol/micro/server/logback/rest/LogbackRootLoggerResourceTest.java +++ b/micro-logback/src/test/java/com/oath/micro/server/logback/rest/LogbackRootLoggerResourceTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.logback.rest; +package com.oath.micro.server.logback.rest; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; diff --git a/micro-logback/src/test/java/com/aol/micro/server/logback/rest/LogbackRootLoggerRunnerTest.java b/micro-logback/src/test/java/com/oath/micro/server/logback/rest/LogbackRootLoggerRunnerTest.java similarity index 76% rename from micro-logback/src/test/java/com/aol/micro/server/logback/rest/LogbackRootLoggerRunnerTest.java rename to micro-logback/src/test/java/com/oath/micro/server/logback/rest/LogbackRootLoggerRunnerTest.java index 7a5b30656..71eb449ec 100644 --- a/micro-logback/src/test/java/com/aol/micro/server/logback/rest/LogbackRootLoggerRunnerTest.java +++ b/micro-logback/src/test/java/com/oath/micro/server/logback/rest/LogbackRootLoggerRunnerTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.logback.rest; +package com.oath.micro.server.logback.rest; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -7,9 +7,9 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; @Microserver public class LogbackRootLoggerRunnerTest { diff --git a/micro-logback/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-logback/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-logback/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-machine-stats/.DS_Store b/micro-machine-stats/.DS_Store deleted file mode 100644 index 5008ddfcf..000000000 Binary files a/micro-machine-stats/.DS_Store and /dev/null differ diff --git a/micro-machine-stats/README.md b/micro-machine-stats/README.md new file mode 100644 index 000000000..69572aaa3 --- /dev/null +++ b/micro-machine-stats/README.md @@ -0,0 +1,60 @@ +# Machine stats plugin for Microserver + +Hands-free kit for the awesame Sigar. + +Uses Sigar to capture machine stats for each service (CPU load, memory usage etc). Automatically installs Sigar native libraries to ./sigar-lib. + +Adds a rest end point /stats/machine to view statistics about the current container or box. + +[Example micro-machine-stats apps](https://github.com/aol/micro-server/tree/master/micro-machine-stats/src/test/java/app) + +(Microserver 0.78 and above!) + +# To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-machine-stats/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-machine-stats) + +Simply add this plugin to your classpath + +Maven + ```xml + + + com.oath.microservices + micro-machine-stats + x.yz + + +``` +Gradle +```groovy + compile 'com.oath.microservices:micro-machine-stats:x.yz' +``` + + +## Example output +```json +{ + "cpu-stats": { + "model": "MacBookPro", + "mhz": 2500, + "idle-percentage": 0.6952141057934509, + "total-cores": 8, + "load-average": 2.56201171875 + }, + "memory-stats": { + "total": 17179869184, + "actual-free": 4435292160, + "free-percent": 25.816798210144043, + "actual-used": 12744577024, + "used-percent": 74.18320178985596 + }, + "swap-stats": { + "free": 1305739264, + "used": 4062969856, + "total": 5368709120, + "page-in": 40316097, + "page-out": 312451 + } +} +``` diff --git a/micro-machine-stats/build.gradle b/micro-machine-stats/build.gradle index a06386d39..a7e25a312 100644 --- a/micro-machine-stats/build.gradle +++ b/micro-machine-stats/build.gradle @@ -1,63 +1,61 @@ description = 'micro-machine-stats' + dependencies { - compile 'io.kamon:sigar-loader:1.6.6-rev002' - compile group: 'org.fusesource', name: 'sigar', version:'1.6.4' - compile group: 'org.fusesource', name: 'sigar', version:'1.6.4', classifier:'native' - compile project(':micro-core') - - testCompile project(':micro-grizzly-with-jersey') - + compile 'io.kamon:sigar-loader:1.6.6-rev002' + compile group: 'org.fusesource', name: 'sigar', version: '1.6.4' + compile group: 'org.fusesource', name: 'sigar', version: '1.6.4', classifier: 'native' + compile project(':micro-core') + testCompile project(':micro-grizzly-with-jersey') } - modifyPom { - project { - name 'Microserver machine stats' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-machine-stats' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - - } - - } + project { + name 'Microserver machine stats' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-machine-stats' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-machine-stats/readme.md b/micro-machine-stats/readme.md deleted file mode 100644 index 1187c2b5c..000000000 --- a/micro-machine-stats/readme.md +++ /dev/null @@ -1,60 +0,0 @@ -# Machine stats plugin for Microserver - -Hands-free kit for the awesame Sigar. - -Uses Sigar to capture machine stats for each service (CPU load, memory usage etc). Automatically installs Sigar native libraries to ./sigar-lib. - -Adds a rest end point /stats/machine to view statistics about the current container or box. - -[Example micro-machine-stats apps](https://github.com/aol/micro-server/tree/master/micro-machine-stats/src/test/java/app) - -(Microserver 0.78 and above!) - -# To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-machine-stats/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-machine-stats) - -Simply add this plugin to your classpath - -Maven - ```xml - - - com.aol.microservices - micro-machine-stats - x.yz - - -``` -Gradle -```groovy - compile 'com.aol.microservices:micro-machine-stats:x.yz' -``` - - -## Example output -```json -{ - "cpu-stats": { - "model": "MacBookPro", - "mhz": 2500, - "idle-percentage": 0.6952141057934509, - "total-cores": 8, - "load-average": 2.56201171875 - }, - "memory-stats": { - "total": 17179869184, - "actual-free": 4435292160, - "free-percent": 25.816798210144043, - "actual-used": 12744577024, - "used-percent": 74.18320178985596 - }, - "swap-stats": { - "free": 1305739264, - "used": 4062969856, - "total": 5368709120, - "page-in": 40316097, - "page-out": 312451 - } -} -``` \ No newline at end of file diff --git a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/CpuStats.java b/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/CpuStats.java deleted file mode 100644 index 92af1eeca..000000000 --- a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/CpuStats.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.machine.stats.sigar; - -import java.io.Serializable; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.Getter; -import lombok.ToString; -import lombok.experimental.Builder; - -@SuppressWarnings("PMD.UnusedPrivateField") -@XmlAccessorType(XmlAccessType.FIELD) -@XmlRootElement(name = "cpu-stats") -@XmlType(name = "") -@Getter -@ToString -public class CpuStats implements Serializable { - - private static final long serialVersionUID = 1L; - - @XmlElement(name = "idle-percentage") - private final Double idlePercentage; - - @XmlElement(name = "total-cores") - private final Integer totalCores; - - private final String model; - - private final Integer mhz; - - @XmlElement(name = "load-average") - private Double loadAverage; - - @Builder - private CpuStats(double idlePercentage, int totalCores, String model, int mhz, double loadAverage) { - this.idlePercentage = idlePercentage; - this.totalCores = totalCores; - this.model = model; - this.mhz = mhz; - this.loadAverage = loadAverage; - } - - public CpuStats() { - this.idlePercentage = null; - this.totalCores = null; - this.model = null; - this.mhz = null; - this.loadAverage = null; - } - -} diff --git a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/MachineStats.java b/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/MachineStats.java deleted file mode 100644 index dc9353e07..000000000 --- a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/MachineStats.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.aol.micro.server.machine.stats.sigar; - -import java.io.Serializable; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.Getter; -import lombok.ToString; -import lombok.experimental.Builder; - -@SuppressWarnings("PMD.UnusedPrivateField") -@XmlAccessorType(XmlAccessType.FIELD) -@XmlRootElement(name = "machine-stats") -@XmlType(name = "") -@Getter -@ToString -public class MachineStats implements Serializable { - - private static final long serialVersionUID = 1L; - - @XmlElement(name = "cpu-stats") - private final CpuStats cpuStats; - - @XmlElement(name = "memory-stats") - private final MemoryStats memoryStats; - - @XmlElement(name = "swap-stats") - private final SwapStats swapStats; - - @Builder - private MachineStats(CpuStats cpuStats, MemoryStats memoryStats, SwapStats swapStats) { - this.cpuStats = cpuStats; - this.memoryStats = memoryStats; - this.swapStats = swapStats; - } - - public MachineStats() { - this.cpuStats = null; - this.memoryStats = null; - this.swapStats = null; - } -} diff --git a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/MachineStatsChecker.java b/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/MachineStatsChecker.java deleted file mode 100644 index 1a81eac7a..000000000 --- a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/MachineStatsChecker.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.aol.micro.server.machine.stats.sigar; - -import org.hyperic.sigar.Sigar; -import org.hyperic.sigar.SigarException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - - - -@Component -public class MachineStatsChecker { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public MachineStats getStats(Sigar sigar) { - - SwapStats.SwapStatsBuilder swapStats = SwapStats.builder(); - CpuStats.CpuStatsBuilder cpuStats = CpuStats.builder(); - MemoryStats.MemoryStatsBuilder memoryStats = MemoryStats.builder(); - - try { - getSwapStats(swapStats, sigar); - getCpuStats(cpuStats, sigar); - getMemoryStats(memoryStats, sigar); - - } catch (SigarException e) { - logger.error("Error during sigar stats operation", e); - } finally { - sigar.close(); - } - - return getMachineStats(swapStats, cpuStats, memoryStats); - - } - - private void getSwapStats(SwapStats.SwapStatsBuilder swapStats, Sigar sigar) throws SigarException { - swapStats.pageIn(sigar.getSwap().getPageIn()); - swapStats.pageOut(sigar.getSwap().getPageOut()); - swapStats.free(sigar.getSwap().getFree()); - swapStats.used(sigar.getSwap().getUsed()); - swapStats.total(sigar.getSwap().getTotal()); - } - - private void getCpuStats(CpuStats.CpuStatsBuilder cpuStats, Sigar sigar) throws SigarException { - cpuStats.idlePercentage(sigar.getCpuPerc().getIdle()); - cpuStats.totalCores(sigar.getCpuInfoList()[0].getTotalCores()); - cpuStats.model(sigar.getCpuInfoList()[0].getModel()); - cpuStats.mhz(sigar.getCpuInfoList()[0].getMhz()); - cpuStats.loadAverage(sigar.getLoadAverage()[0]); - } - - private void getMemoryStats(MemoryStats.MemoryStatsBuilder memoryStats, Sigar sigar) throws SigarException { - memoryStats.total(sigar.getMem().getTotal()); - memoryStats.actualFree(sigar.getMem().getActualFree()); - memoryStats.freePercent(sigar.getMem().getFreePercent()); - memoryStats.actualUsed(sigar.getMem().getActualUsed()); - memoryStats.usedPercent(sigar.getMem().getUsedPercent()); - } - - private MachineStats getMachineStats(SwapStats.SwapStatsBuilder swapStats, CpuStats.CpuStatsBuilder cpuStats, - MemoryStats.MemoryStatsBuilder memoryStats) { - MachineStats.MachineStatsBuilder machineStats = MachineStats.builder(); - machineStats.swapStats(swapStats.build()); - machineStats.cpuStats(cpuStats.build()); - machineStats.memoryStats(memoryStats.build()); - return machineStats.build(); - } -} diff --git a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/MemoryStats.java b/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/MemoryStats.java deleted file mode 100644 index c6876b43f..000000000 --- a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/MemoryStats.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.machine.stats.sigar; - -import java.io.Serializable; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.Getter; -import lombok.ToString; -import lombok.experimental.Builder; - -@SuppressWarnings("PMD.UnusedPrivateField") -@XmlAccessorType(XmlAccessType.FIELD) -@XmlRootElement(name = "memory-stats") -@XmlType(name = "") -@Getter -@ToString -public class MemoryStats implements Serializable { - - private static final long serialVersionUID = 1L; - - private final Long total; - - @XmlElement(name = "actual-free") - private final Long actualFree; - - @XmlElement(name = "free-percent") - private final Double freePercent; - - @XmlElement(name = "actual-used") - private final Long actualUsed; - - @XmlElement(name = "used-percent") - private final Double usedPercent; - - @Builder - private MemoryStats(long total, long actualFree, double freePercent, long actualUsed, double usedPercent) { - this.total = total; - this.actualFree = actualFree; - this.freePercent = freePercent; - this.actualUsed = actualUsed; - this.usedPercent = usedPercent; - } - - public MemoryStats() { - this.total = null; - this.actualFree = null; - this.freePercent = null; - this.actualUsed = null; - this.usedPercent = null; - } -} diff --git a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/StatsServletContextListener.java b/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/StatsServletContextListener.java deleted file mode 100644 index f2ca813cb..000000000 --- a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/StatsServletContextListener.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.aol.micro.server.machine.stats.sigar; - -import java.io.File; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import kamon.sigar.SigarProvisioner; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.aol.cyclops.util.ExceptionSoftener; - - -public class StatsServletContextListener implements ServletContextListener { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Override - public void contextInitialized(ServletContextEvent sce) { - - String workingDir = System.getProperty("user.dir"); - String destination = workingDir + "/sigar-lib"; - logger.info("java.library.path is {}", destination); - System.setProperty("java.library.path", destination); - - if(!new File(System.getProperty("java.library.path")).exists()){ - final File location = new File(System.getProperty("java.library.path")); - try { - SigarProvisioner.provision(location); - } catch (Exception e) { - throw ExceptionSoftener.throwSoftenedException(e); - } - - } - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - } -} diff --git a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/SwapStats.java b/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/SwapStats.java deleted file mode 100644 index c2893b5ce..000000000 --- a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/SwapStats.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.aol.micro.server.machine.stats.sigar; - -import java.io.Serializable; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.Getter; -import lombok.ToString; -import lombok.experimental.Builder; - -@SuppressWarnings("PMD.UnusedPrivateField") -@XmlAccessorType(XmlAccessType.FIELD) -@XmlRootElement(name = "swap-stats") -@XmlType(name = "") -@Getter -@ToString -public class SwapStats implements Serializable { - - private static final long serialVersionUID = 1L; - - @XmlElement(name = "page-in") - private final Long pageIn; - - @XmlElement(name = "page-out") - private final Long pageOut; - - private final Long free; - - private final Long used; - - private final Long total; - - @Builder - private SwapStats(long pageIn, long pageOut, long free, long used, long total) { - this.pageIn = pageIn; - this.pageOut = pageOut; - this.free = free; - this.used = used; - this.total = total; - } - - public SwapStats() { - this.pageIn = null; - this.pageOut = null; - this.free = null; - this.used = null; - this.total = null; - } -} diff --git a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/plugin/MachineStatsPlugin.java b/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/plugin/MachineStatsPlugin.java deleted file mode 100644 index 06a1b7c3b..000000000 --- a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/plugin/MachineStatsPlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.aol.micro.server.machine.stats.sigar.plugin; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.machine.stats.sigar.MachineStatsChecker; -import com.aol.micro.server.machine.stats.sigar.StatsServletContextListener; -import com.aol.micro.server.machine.stats.sigar.rest.StatsResource; - - -/** - * - * Collections of Spring configuration classes (Classes annotated with @Configuration) - * that configure various useful pieces of functionality - such as property file loading, - * datasources, scheduling etc - * - * @author johnmcclean - * - */ -public class MachineStatsPlugin implements Plugin{ - - @Override - public PSetX springClasses() { - return PSetX.of( - StatsResource.class, MachineStatsChecker.class - ,StatsServletContextListener.class); - } - - - -} diff --git a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/rest/StatsResource.java b/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/rest/StatsResource.java deleted file mode 100644 index ac191a293..000000000 --- a/micro-machine-stats/src/main/java/com/aol/micro/server/machine/stats/sigar/rest/StatsResource.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.aol.micro.server.machine.stats.sigar.rest; - - - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.hyperic.sigar.Sigar; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.SingletonRestResource; -import com.aol.micro.server.machine.stats.sigar.MachineStats; -import com.aol.micro.server.machine.stats.sigar.MachineStatsChecker; - -@Path("/stats") -public class StatsResource implements SingletonRestResource { - - - private final MachineStatsChecker machineStatsChecker; - - @Autowired - public StatsResource(MachineStatsChecker machineStatsChecker){ - this.machineStatsChecker = machineStatsChecker; - } - - @GET - @Path("/machine") - @Produces("application/json") - public MachineStats getMachineStats() { - return machineStatsChecker.getStats(new Sigar()); - } -} diff --git a/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/CpuStats.java b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/CpuStats.java new file mode 100644 index 000000000..856f10f6f --- /dev/null +++ b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/CpuStats.java @@ -0,0 +1,67 @@ +package com.oath.micro.server.machine.stats.sigar; + +import java.io.Serializable; +import java.util.Map; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +import cyclops.reactive.companion.MapXs; +import lombok.Getter; +import lombok.ToString; +import lombok.Builder; + +@SuppressWarnings("PMD.UnusedPrivateField") +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "cpu-stats") +@XmlType(name = "") +@Getter +@ToString +public class CpuStats implements Serializable { + + private static final long serialVersionUID = 1L; + + @XmlElement(name = "idle-percentage") + private final Double idlePercentage; + + @XmlElement(name = "total-cores") + private final Integer totalCores; + + private final String model; + + private final Integer mhz; + + @XmlElement(name = "load-average") + private Double loadAverage; + + @Builder + private CpuStats(double idlePercentage, int totalCores, String model, int mhz, double loadAverage) { + this.idlePercentage = idlePercentage; + this.totalCores = totalCores; + this.model = model; + this.mhz = mhz; + this.loadAverage = loadAverage; + } + + public CpuStats() { + this.idlePercentage = null; + this.totalCores = null; + this.model = null; + this.mhz = null; + this.loadAverage = null; + } + + public Map toMap() { + return MapXs.map("idle-percentage", "" + idlePercentage) + .put("total-cores", "" + totalCores) + .put("model", model) + .put("mhz", "" + mhz) + .put("load-average", "" + loadAverage) + .build(); + } + +} diff --git a/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/MachineStats.java b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/MachineStats.java new file mode 100644 index 000000000..acb1d830a --- /dev/null +++ b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/MachineStats.java @@ -0,0 +1,54 @@ +package com.oath.micro.server.machine.stats.sigar; + +import java.io.Serializable; +import java.util.Map; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +import cyclops.reactive.companion.MapXs; +import lombok.Getter; +import lombok.ToString; +import lombok.Builder; + +@SuppressWarnings("PMD.UnusedPrivateField") +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "machine-stats") +@XmlType(name = "") +@Getter +@ToString +public class MachineStats implements Serializable { + + private static final long serialVersionUID = 1L; + + @XmlElement(name = "cpu-stats") + private final CpuStats cpuStats; + + @XmlElement(name = "memory-stats") + private final MemoryStats memoryStats; + + @XmlElement(name = "swap-stats") + private final SwapStats swapStats; + + @Builder + private MachineStats(CpuStats cpuStats, MemoryStats memoryStats, SwapStats swapStats) { + this.cpuStats = cpuStats; + this.memoryStats = memoryStats; + this.swapStats = swapStats; + } + + public MachineStats() { + this.cpuStats = null; + this.memoryStats = null; + this.swapStats = null; + } + + public Map> toMap() { + return MapXs.of("cpu-stats", cpuStats.toMap(), "memory-stats", memoryStats.toMap(), "swap-stats", + swapStats.toMap()); + } +} diff --git a/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/MachineStatsChecker.java b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/MachineStatsChecker.java new file mode 100644 index 000000000..3eb4697a9 --- /dev/null +++ b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/MachineStatsChecker.java @@ -0,0 +1,97 @@ +package com.oath.micro.server.machine.stats.sigar; + +import org.hyperic.sigar.Sigar; +import org.hyperic.sigar.SigarException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class MachineStatsChecker { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public MachineStats getStats(Sigar sigar) { + CpuStats cpuStats = CpuStats.builder() + .build(); + SwapStats swapStats = SwapStats.builder() + .build(); + MemoryStats memoryStats = MemoryStats.builder() + .build(); + try { + swapStats = getSwapStats(sigar); + cpuStats = getCpuStats(sigar); + getMemoryStats(sigar); + + } catch (SigarException | UnsatisfiedLinkError e) { + logger.error("Error during sigar stats operation", e); + } finally { + sigar.close(); + } + + return getMachineStats(swapStats, cpuStats, memoryStats); + + } + + CpuStats cpuStats(Sigar sigar) { + try { + return getCpuStats(sigar); + + } catch (SigarException | UnsatisfiedLinkError e) { + logger.error("Error during sigar stats operation", e); + } finally { + sigar.close(); + } + return CpuStats.builder() + .build(); + } + + private SwapStats getSwapStats(Sigar sigar) throws SigarException { + SwapStats.SwapStatsBuilder swapStats = SwapStats.builder(); + swapStats.pageIn(sigar.getSwap() + .getPageIn()); + swapStats.pageOut(sigar.getSwap() + .getPageOut()); + swapStats.free(sigar.getSwap() + .getFree()); + swapStats.used(sigar.getSwap() + .getUsed()); + swapStats.total(sigar.getSwap() + .getTotal()); + return swapStats.build(); + } + + private CpuStats getCpuStats(Sigar sigar) throws SigarException { + CpuStats.CpuStatsBuilder cpuStats = CpuStats.builder(); + cpuStats.idlePercentage(sigar.getCpuPerc() + .getIdle()); + cpuStats.totalCores(sigar.getCpuInfoList()[0].getTotalCores()); + cpuStats.model(sigar.getCpuInfoList()[0].getModel()); + cpuStats.mhz(sigar.getCpuInfoList()[0].getMhz()); + cpuStats.loadAverage(sigar.getLoadAverage()[0]); + return cpuStats.build(); + } + + private MemoryStats getMemoryStats(Sigar sigar) throws SigarException { + MemoryStats.MemoryStatsBuilder memoryStats = MemoryStats.builder(); + memoryStats.total(sigar.getMem() + .getTotal()); + memoryStats.actualFree(sigar.getMem() + .getActualFree()); + memoryStats.freePercent(sigar.getMem() + .getFreePercent()); + memoryStats.actualUsed(sigar.getMem() + .getActualUsed()); + memoryStats.usedPercent(sigar.getMem() + .getUsedPercent()); + return memoryStats.build(); + } + + private MachineStats getMachineStats(SwapStats swapStats, CpuStats cpuStats, MemoryStats memoryStats) { + MachineStats.MachineStatsBuilder machineStats = MachineStats.builder(); + machineStats.swapStats(swapStats); + machineStats.cpuStats(cpuStats); + machineStats.memoryStats(memoryStats); + return machineStats.build(); + } +} diff --git a/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/MemoryStats.java b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/MemoryStats.java new file mode 100644 index 000000000..9511f43ad --- /dev/null +++ b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/MemoryStats.java @@ -0,0 +1,67 @@ +package com.oath.micro.server.machine.stats.sigar; + +import java.io.Serializable; +import java.util.Map; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +import cyclops.reactive.companion.MapXs; +import lombok.Getter; +import lombok.ToString; +import lombok.Builder; + +@SuppressWarnings("PMD.UnusedPrivateField") +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "memory-stats") +@XmlType(name = "") +@Getter +@ToString +public class MemoryStats implements Serializable { + + private static final long serialVersionUID = 1L; + + private final Long total; + + @XmlElement(name = "actual-free") + private final Long actualFree; + + @XmlElement(name = "free-percent") + private final Double freePercent; + + @XmlElement(name = "actual-used") + private final Long actualUsed; + + @XmlElement(name = "used-percent") + private final Double usedPercent; + + @Builder + private MemoryStats(long total, long actualFree, double freePercent, long actualUsed, double usedPercent) { + this.total = total; + this.actualFree = actualFree; + this.freePercent = freePercent; + this.actualUsed = actualUsed; + this.usedPercent = usedPercent; + } + + public MemoryStats() { + this.total = null; + this.actualFree = null; + this.freePercent = null; + this.actualUsed = null; + this.usedPercent = null; + } + + public Map toMap() { + return MapXs.map("total", "" + total) + .put("actual-free", "" + actualFree) + .put("free-percent", "" + freePercent) + .put("actual-used", "" + actualUsed) + .put("used-percent", "" + usedPercent) + .build(); + } +} diff --git a/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/SigarStats.java b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/SigarStats.java new file mode 100644 index 000000000..4e1e4f00c --- /dev/null +++ b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/SigarStats.java @@ -0,0 +1,36 @@ +package com.oath.micro.server.machine.stats.sigar; + +import java.util.Map; + +import cyclops.reactive.companion.MapXs; +import org.hyperic.sigar.Sigar; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.StatsSupplier; + +@Component +public class SigarStats implements StatsSupplier { + private final MachineStatsChecker checker; + private final long statsDelay; + private final boolean cpuOnly; + private volatile long lastRan = 0; + private volatile boolean lastRanValue = true; + + public SigarStats(MachineStatsChecker checker, @Value("${stats.checker.delay:1000}") long statsDelay, + @Value("${stats.checker.cpu.only:true}") boolean cpuOnly) { + this.statsDelay = statsDelay; + this.checker = checker; + this.cpuOnly = cpuOnly; + } + + @Override + public Map> get() { + if (cpuOnly) + return MapXs.of("cpu-stats", checker.cpuStats(new Sigar()) + .toMap()); + MachineStats stats = checker.getStats(new Sigar()); + return stats.toMap(); + } + +} diff --git a/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/StatsServletContextListener.java b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/StatsServletContextListener.java new file mode 100644 index 000000000..ab62ea529 --- /dev/null +++ b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/StatsServletContextListener.java @@ -0,0 +1,45 @@ +package com.oath.micro.server.machine.stats.sigar; + +import java.io.File; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import com.oath.cyclops.util.ExceptionSoftener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; + + +import kamon.sigar.SigarProvisioner; + +public class StatsServletContextListener implements ServletContextListener { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Value("${machine.stats.deploy.dir:#{null}}") + String deployDir; + + @Override + public void contextInitialized(ServletContextEvent sce) { + + String workingDir = deployDir == null ? System.getProperty("user.dir") : deployDir; + String destination = workingDir + "/sigar-lib"; + + System.setProperty("java.library.path", destination); + logger.info("java.library.path is {}", destination); + if (!new File(System.getProperty("java.library.path")).exists()) { + final File location = new File(System.getProperty("java.library.path")); + try { + SigarProvisioner.provision(location); + } catch (Exception e) { + throw ExceptionSoftener.throwSoftenedException(e); + } + + } + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + } +} diff --git a/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/SwapStats.java b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/SwapStats.java new file mode 100644 index 000000000..b66e8da74 --- /dev/null +++ b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/SwapStats.java @@ -0,0 +1,64 @@ +package com.oath.micro.server.machine.stats.sigar; + +import java.io.Serializable; +import java.util.Map; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +import cyclops.reactive.companion.MapXs; +import lombok.Getter; +import lombok.ToString; +import lombok.Builder; + +@SuppressWarnings("PMD.UnusedPrivateField") +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "swap-stats") +@XmlType(name = "") +@Getter +@ToString +public class SwapStats implements Serializable { + + private static final long serialVersionUID = 1L; + + @XmlElement(name = "page-in") + private final Long pageIn; + + @XmlElement(name = "page-out") + private final Long pageOut; + + private final Long free; + + private final Long used; + + private final Long total; + + @Builder + private SwapStats(long pageIn, long pageOut, long free, long used, long total) { + this.pageIn = pageIn; + this.pageOut = pageOut; + this.free = free; + this.used = used; + this.total = total; + } + + public SwapStats() { + this.pageIn = null; + this.pageOut = null; + this.free = null; + this.used = null; + this.total = null; + } + + public Map toMap() { + return MapXs.map("page-in", "" + pageIn) + .put("page-out", "" + pageOut) + .put("free", "" + used) + .put("total", "" + total) + .build(); + } +} diff --git a/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/plugin/MachineStatsPlugin.java b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/plugin/MachineStatsPlugin.java new file mode 100644 index 000000000..8f6b10c55 --- /dev/null +++ b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/plugin/MachineStatsPlugin.java @@ -0,0 +1,30 @@ +package com.oath.micro.server.machine.stats.sigar.plugin; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.machine.stats.sigar.MachineStatsChecker; +import com.oath.micro.server.machine.stats.sigar.SigarStats; +import com.oath.micro.server.machine.stats.sigar.StatsServletContextListener; +import com.oath.micro.server.machine.stats.sigar.rest.StatsResource; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +/** + * + * Collections of Spring configuration classes (Classes annotated with @Configuration) + * that configure various useful pieces of functionality - such as property file loading, + * datasources, scheduling etc + * + * @author johnmcclean + * + */ +public class MachineStatsPlugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of(StatsResource.class, MachineStatsChecker.class, StatsServletContextListener.class, + SigarStats.class); + } + +} diff --git a/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/rest/StatsResource.java b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/rest/StatsResource.java new file mode 100644 index 000000000..510e54517 --- /dev/null +++ b/micro-machine-stats/src/main/java/com/oath/micro/server/machine/stats/sigar/rest/StatsResource.java @@ -0,0 +1,33 @@ +package com.oath.micro.server.machine.stats.sigar.rest; + + + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.hyperic.sigar.Sigar; +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.SingletonRestResource; +import com.oath.micro.server.machine.stats.sigar.MachineStats; +import com.oath.micro.server.machine.stats.sigar.MachineStatsChecker; + +@Path("/stats") +public class StatsResource implements SingletonRestResource { + + + private final MachineStatsChecker machineStatsChecker; + + @Autowired + public StatsResource(MachineStatsChecker machineStatsChecker){ + this.machineStatsChecker = machineStatsChecker; + } + + @GET + @Path("/machine") + @Produces("application/json") + public MachineStats getMachineStats() { + return machineStatsChecker.getStats(new Sigar()); + } +} diff --git a/micro-machine-stats/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-machine-stats/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index a120f70f7..000000000 --- a/micro-machine-stats/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.machine.stats.sigar.plugin.MachineStatsPlugin \ No newline at end of file diff --git a/micro-machine-stats/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-machine-stats/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..fa31f6820 --- /dev/null +++ b/micro-machine-stats/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.machine.stats.sigar.plugin.MachineStatsPlugin \ No newline at end of file diff --git a/micro-machine-stats/src/test/java/app/sigar/com/aol/micro/server/StatsRunnerTest.java b/micro-machine-stats/src/test/java/app/sigar/com/aol/micro/server/StatsRunnerTest.java deleted file mode 100644 index 81ba245a3..000000000 --- a/micro-machine-stats/src/test/java/app/sigar/com/aol/micro/server/StatsRunnerTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package app.sigar.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.assertThat; - -import java.io.File; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class StatsRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer() { - server = new MicroserverApp(ConfigurableModule.builder() - .context("simple-app").build()); - - server.start(); - - } - - @After - public void stopServer() { - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, - ExecutionException { - - assertThat(rest.get("http://localhost:8080/simple-app/stats/machine"), - containsString("cpu-stats")); - - } - -} diff --git a/micro-machine-stats/src/test/java/app/sigar/com/oath/micro/server/SingleClassApp.java b/micro-machine-stats/src/test/java/app/sigar/com/oath/micro/server/SingleClassApp.java new file mode 100644 index 000000000..53b12ff37 --- /dev/null +++ b/micro-machine-stats/src/test/java/app/sigar/com/oath/micro/server/SingleClassApp.java @@ -0,0 +1,24 @@ +package app.sigar.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class SingleClassApp { + + public static void main(String[] args){ + new MicroserverApp(()-> "simple-app").run(); + } + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-machine-stats/src/test/java/app/sigar/com/oath/micro/server/StatsRunnerTest.java b/micro-machine-stats/src/test/java/app/sigar/com/oath/micro/server/StatsRunnerTest.java new file mode 100644 index 000000000..0a681971a --- /dev/null +++ b/micro-machine-stats/src/test/java/app/sigar/com/oath/micro/server/StatsRunnerTest.java @@ -0,0 +1,45 @@ +package app.sigar.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class StatsRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + server = new MicroserverApp(ConfigurableModule.builder() + .context("simple-app") + .build()); + + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() { + assertThat(rest.get("http://localhost:8080/simple-app/stats/machine"), containsString("cpu-stats")); + } +} diff --git a/micro-machine-stats/src/test/java/com/aol/micro/server/machine/stats/sigar/StatsServletContextListenerTest.groovy b/micro-machine-stats/src/test/java/com/aol/micro/server/machine/stats/sigar/StatsServletContextListenerTest.groovy deleted file mode 100644 index e1857784c..000000000 --- a/micro-machine-stats/src/test/java/com/aol/micro/server/machine/stats/sigar/StatsServletContextListenerTest.groovy +++ /dev/null @@ -1,36 +0,0 @@ -package com.aol.micro.server.machine.stats.sigar; - -import static org.hamcrest.Matchers.is -import static org.junit.Assert.assertThat -import static org.mockito.Mockito.mock -import static org.mockito.Mockito.when - -import javax.servlet.ServletContext -import javax.servlet.ServletContextEvent - -import org.junit.Before -import org.junit.Test - - -class StatsServletContextListenerTest { - - private StatsServletContextListener contextListener - - private ServletContextEvent sce - - private ServletContext servletContext - - @Before - public void setUp() { - sce = mock(ServletContextEvent.class) - servletContext = mock(ServletContext.class) - contextListener = new StatsServletContextListener() - } - - @Test - public void testGrizzly() { - contextListener.contextInitialized(sce) - assertThat(System.getProperty("java.library.path"), is(System.getProperty("user.dir") + "/sigar-lib")) - contextListener.contextDestroyed(sce) - } -} diff --git a/micro-machine-stats/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-machine-stats/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index 991ffed12..000000000 --- a/micro-machine-stats/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.aol.micro.server.testing; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -public class RestAgent { - - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - - - -} diff --git a/micro-machine-stats/src/test/java/com/aol/micro/server/machine/stats/sigar/MachineStatsCheckerTest.java b/micro-machine-stats/src/test/java/com/oath/micro/server/machine/stats/sigar/MachineStatsCheckerTest.java similarity index 95% rename from micro-machine-stats/src/test/java/com/aol/micro/server/machine/stats/sigar/MachineStatsCheckerTest.java rename to micro-machine-stats/src/test/java/com/oath/micro/server/machine/stats/sigar/MachineStatsCheckerTest.java index 1b5e90c63..5744507f5 100644 --- a/micro-machine-stats/src/test/java/com/aol/micro/server/machine/stats/sigar/MachineStatsCheckerTest.java +++ b/micro-machine-stats/src/test/java/com/oath/micro/server/machine/stats/sigar/MachineStatsCheckerTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.machine.stats.sigar; +package com.oath.micro.server.machine.stats.sigar; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -14,8 +14,6 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.machine.stats.sigar.MachineStatsChecker; - public class MachineStatsCheckerTest { private Sigar sigar; diff --git a/micro-machine-stats/src/test/java/com/aol/micro/server/machine/stats/sigar/MachineStatsTest.java b/micro-machine-stats/src/test/java/com/oath/micro/server/machine/stats/sigar/MachineStatsTest.java similarity index 92% rename from micro-machine-stats/src/test/java/com/aol/micro/server/machine/stats/sigar/MachineStatsTest.java rename to micro-machine-stats/src/test/java/com/oath/micro/server/machine/stats/sigar/MachineStatsTest.java index 49265614f..3d1422c10 100644 --- a/micro-machine-stats/src/test/java/com/aol/micro/server/machine/stats/sigar/MachineStatsTest.java +++ b/micro-machine-stats/src/test/java/com/oath/micro/server/machine/stats/sigar/MachineStatsTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.machine.stats.sigar; +package com.oath.micro.server.machine.stats.sigar; import org.junit.Test; diff --git a/micro-machine-stats/src/test/java/com/oath/micro/server/machine/stats/sigar/StatsServletContextListenerTest.java b/micro-machine-stats/src/test/java/com/oath/micro/server/machine/stats/sigar/StatsServletContextListenerTest.java new file mode 100644 index 000000000..15205a01d --- /dev/null +++ b/micro-machine-stats/src/test/java/com/oath/micro/server/machine/stats/sigar/StatsServletContextListenerTest.java @@ -0,0 +1,30 @@ +package com.oath.micro.server.machine.stats.sigar; + +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; + +public class StatsServletContextListenerTest { + @Before + public void setUp() { + sce = Mockito.mock(ServletContextEvent.class); + servletContext = Mockito.mock(ServletContext.class); + contextListener = new StatsServletContextListener(); + } + + @Test + public void testGrizzly() { + contextListener.contextInitialized(sce); + Assert.assertThat(System.getProperty("java.library.path"), Matchers.is(System.getProperty("user.dir") + "/sigar-lib")); + contextListener.contextDestroyed(sce); + } + + private StatsServletContextListener contextListener; + private ServletContextEvent sce; + private ServletContext servletContext; +} diff --git a/micro-machine-stats/src/test/java/com/aol/micro/server/machine/stats/sigar/rest/StatsResourceTest.java b/micro-machine-stats/src/test/java/com/oath/micro/server/machine/stats/sigar/rest/StatsResourceTest.java similarity index 81% rename from micro-machine-stats/src/test/java/com/aol/micro/server/machine/stats/sigar/rest/StatsResourceTest.java rename to micro-machine-stats/src/test/java/com/oath/micro/server/machine/stats/sigar/rest/StatsResourceTest.java index 27afc618f..95656d072 100644 --- a/micro-machine-stats/src/test/java/com/aol/micro/server/machine/stats/sigar/rest/StatsResourceTest.java +++ b/micro-machine-stats/src/test/java/com/oath/micro/server/machine/stats/sigar/rest/StatsResourceTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.machine.stats.sigar.rest; +package com.oath.micro.server.machine.stats.sigar.rest; import static org.mockito.Matchers.anyObject; @@ -11,8 +11,8 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.machine.stats.sigar.MachineStats; -import com.aol.micro.server.machine.stats.sigar.MachineStatsChecker; +import com.oath.micro.server.machine.stats.sigar.MachineStats; +import com.oath.micro.server.machine.stats.sigar.MachineStatsChecker; public class StatsResourceTest { diff --git a/micro-machine-stats/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-machine-stats/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..a5f4fe51a --- /dev/null +++ b/micro-machine-stats/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,28 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +public class RestAgent { + + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + + + +} diff --git a/micro-machine-stats/src/test/resources/.DS_Store b/micro-machine-stats/src/test/resources/.DS_Store deleted file mode 100644 index 5008ddfcf..000000000 Binary files a/micro-machine-stats/src/test/resources/.DS_Store and /dev/null differ diff --git a/micro-manifest-comparator/README.md b/micro-manifest-comparator/README.md new file mode 100644 index 000000000..2fc1ecfd8 --- /dev/null +++ b/micro-manifest-comparator/README.md @@ -0,0 +1,158 @@ +# Manifest Compartor plugin for BASE microservices + +This plugin provides the core classes and interfaces for building Manifest Comparator based data loading (see below for an explanation). Implementations are provided via micro-couchbase or micro-s3. + +[micro-manifest-comparator example apps via micro-couchbase](https://github.com/aol/micro-server/tree/master/micro-couchbase/src/test/java/app) + +[micro-manifest-comparator example apps via micro-s3](https://github.com/aol/micro-server/tree/master/micro-s3/src/test/java/app) + +Basically Available Soft statE + +* Manifest comparator : Versioned key for loading refreshed state + +# Manifest comparison + +Manifest comparison stores a manifest along with each value. The manifest contains the version for the value, if the version has changed, the latest verson of the value will be loaded. + + + key : manifest [contains version info] + versionedKey : key with version + +This allows large immutable datastructures to be stored in as a key/value pair (with separate key/value pairing for version info), and reloaded automatically on change. + +## Injecting the manifest comparator + +Inject the Spring bean created by micro-couchbase or micro-s3 that implements ManifestComparator into your own beans. Customize the key used (allows multiple ManifestComparators to be used) + +```java +public class ManifestComparatorResource { + + + private final ManifestComparator comparator; + @Autowired + public ManifestComparatorResource(ManifestComparator comparator) { + this.comparator = comparator.withKey("test-key"); + } +``` + +## Create a scheduled job + +See micro-events, for Microserver help in managing scheduled jobs. + +Create a scheduled job to check the manifest for changes & automatically reload data when stale. + +In the example below we run the versioned key cleaner once per day, and check for changes every minute. + + ```java +@Component +public class DataLoader implements ScheduledJob{ + + private final ManifestComparator comparator; + @Autowired + public DataLoader(ManifestComparator comparator) { + this.comparator = comparator.withKey("test-key"); + } + @Override + public SystemData scheduleAndLog() { + try{ + boolean changed = comparator.isOutOfDate(); + comparator.load(); + return SystemData.builder().errors(0).processed(isOutOfDate?1:0).build(); + }catch(Exception e){ + return SystemData.builder().errors(1).processed(0).build(); + } + } + +} + +@Component +public class DataCleaner implements ScheduledJob{ + + private final ManifestComparator comparator; + @Autowired + public DataCleaner(ManifestComparator comparator) { + this.comparator = comparator.withKey("test-key"); + } + @Override + public SystemData scheduleAndLog() { + try{ + comparator.cleanAll(); + return SystemData.builder().errors(0).processed(1).build(); + }catch(Exception e){ + return SystemData.builder().errors(1).processed(0).build(); + } + + } + +} + +@Component +public class Schedular{ + + private final DataCleaner cleaner; + private final DataLoader loader; + + public Schedular(DataCleaner cleaner,DataLoader loader){ + this.cleaner = cleaner; + this.loader = loader; + } + + + @Scheduled(cron = "0 1 1 * * ?") + public synchronized void scheduleCleaner(){ + cleaner.scheduleAndLog(); + } + @Scheduled(cron = "0 * * * * *") + public synchronized void scheduleLoader(){ + loader.scheduleAndLog(); + } + +} + + ``` + +Elsewhere a single writer service can write data to the store for all services of a type to load. See micro-mysql or micro-curator for a DistributedLock implementation + +e.g. + + ```java + @Component + public class DataWriter { + + private final DistributedLockService lockService; + + private final ManifestComparator comparator; + @Autowired + public DataWriter(DistributedLockService lockService,ManifestComparator comparator) { + this.lockService = lockService; + this.comparator = comparator.withKey("test-key"); + } + + public void write(Supplier data){ + if(lockService.tryLock("single-writer-lock-a") { + comparator.saveAndIncrement(data.get()); + } + } + + + + } + + ``` + +## Getting The Microserver Manifest comparator Plugin + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-couchbase/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-couchbase) + +### Maven +```xml + + com.oath.microservices + micro-manifest-comparator + x.yz + +``` +### Gradle +```groovy + compile 'com.oath.microservices:micro-manifest-comparator:x.yz' + ``` diff --git a/micro-manifest-comparator/build.gradle b/micro-manifest-comparator/build.gradle new file mode 100644 index 000000000..affa1683b --- /dev/null +++ b/micro-manifest-comparator/build.gradle @@ -0,0 +1,79 @@ +description = 'micro-manifest-comparator' + +dependencies { + compile project(':micro-jackson-configuration') + testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: hamcrestVersion +} + +sourceSets { + main { + java { srcDirs = ['src/main/java'] } + resources { srcDir 'src/main/resources' } + } + + test { + java { srcDirs = [] } + resources { srcDir 'src/test/resources' } + } + +} + +modifyPom { + project { + name 'Microserver Manifest Comparator' + description 'Pattern for loading cached data for BASE microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2016' + + groupId 'com.oath.microservices' + artifactId 'micro-manifest-comparator' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'pbujko' + name 'Przemyslaw Bujko' + email 'przemyslaw.bujko@teamaol.com' + } + } + + } +} + +extraArchive { + sources = true + tests = true + javadoc = true +} + +nexus { + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' +} + diff --git a/micro-manifest-comparator/src/main/java/com/oath/micro/server/distributed/DistributedMap.java b/micro-manifest-comparator/src/main/java/com/oath/micro/server/distributed/DistributedMap.java new file mode 100644 index 000000000..dba6b35ca --- /dev/null +++ b/micro-manifest-comparator/src/main/java/com/oath/micro/server/distributed/DistributedMap.java @@ -0,0 +1,13 @@ +package com.oath.micro.server.distributed; + +import java.util.Optional; + +public interface DistributedMap { + + boolean put(String key, V value); + + Optional get(String key); + + void delete(String key); + +} \ No newline at end of file diff --git a/micro-manifest-comparator/src/main/java/com/oath/micro/server/manifest/Data.java b/micro-manifest-comparator/src/main/java/com/oath/micro/server/manifest/Data.java new file mode 100644 index 000000000..f7bcabf45 --- /dev/null +++ b/micro-manifest-comparator/src/main/java/com/oath/micro/server/manifest/Data.java @@ -0,0 +1,23 @@ +package com.oath.micro.server.manifest; + +import java.io.Serializable; +import java.util.Date; + +import lombok.Getter; + +public class Data implements Serializable { + + private static final long serialVersionUID = 1L; + @Getter + private final T data; + @Getter + private final Date date; + @Getter + private final String versionedKey; + + public Data(T data, Date date, String versionedKey) { + this.data = data; + this.date = date; + this.versionedKey = versionedKey; + } +} diff --git a/micro-manifest-comparator/src/main/java/com/oath/micro/server/manifest/ManifestComparator.java b/micro-manifest-comparator/src/main/java/com/oath/micro/server/manifest/ManifestComparator.java new file mode 100644 index 000000000..13f70e884 --- /dev/null +++ b/micro-manifest-comparator/src/main/java/com/oath/micro/server/manifest/ManifestComparator.java @@ -0,0 +1,30 @@ +package com.oath.micro.server.manifest; + +public interface ManifestComparator { + public ManifestComparator withKey(String key); + + public boolean isOutOfDate(); + + public boolean load(); + + public void cleanAll(); + + public void clean(int numberToClean); + + public void saveAndIncrement(T data); + + /** + * Gets data from ManifestComparator, blocks until it has been initialized + * + * @return Initialized data from ManifestComparator + */ + public T getData(); + + /** + * Gets data from ManifestComparator, returns null if unitialized + * + * @return Current Data + */ + public T getCurrentData(); + +} diff --git a/micro-manifest-comparator/src/main/java/com/oath/micro/server/manifest/ManifestComparatorKeyNotFoundException.java b/micro-manifest-comparator/src/main/java/com/oath/micro/server/manifest/ManifestComparatorKeyNotFoundException.java new file mode 100644 index 000000000..a3f7aa937 --- /dev/null +++ b/micro-manifest-comparator/src/main/java/com/oath/micro/server/manifest/ManifestComparatorKeyNotFoundException.java @@ -0,0 +1,13 @@ +package com.oath.micro.server.manifest; + +public class ManifestComparatorKeyNotFoundException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public ManifestComparatorKeyNotFoundException(String message) { + super( + message); + + } + +} diff --git a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/base/VersionedKey.java b/micro-manifest-comparator/src/main/java/com/oath/micro/server/manifest/VersionedKey.java similarity index 86% rename from micro-couchbase/src/main/java/com/aol/micro/server/couchbase/base/VersionedKey.java rename to micro-manifest-comparator/src/main/java/com/oath/micro/server/manifest/VersionedKey.java index c87ac01aa..2f9eb0a26 100644 --- a/micro-couchbase/src/main/java/com/aol/micro/server/couchbase/base/VersionedKey.java +++ b/micro-manifest-comparator/src/main/java/com/oath/micro/server/manifest/VersionedKey.java @@ -1,18 +1,16 @@ -package com.aol.micro.server.couchbase.base; +package com.oath.micro.server.manifest; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; +import com.oath.micro.server.rest.jackson.JacksonUtil; + import lombok.AllArgsConstructor; import lombok.Getter; import lombok.experimental.Wither; -import com.aol.micro.server.rest.jackson.JacksonUtil; - - - @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "versioned-key") @XmlType(name = "") diff --git a/micro-manifest-comparator/src/test/java/com/aol/micro/server/manifest/ManifestComparatorKeyNotFoundExceptionTest.java b/micro-manifest-comparator/src/test/java/com/aol/micro/server/manifest/ManifestComparatorKeyNotFoundExceptionTest.java new file mode 100644 index 000000000..4d8fc06b2 --- /dev/null +++ b/micro-manifest-comparator/src/test/java/com/aol/micro/server/manifest/ManifestComparatorKeyNotFoundExceptionTest.java @@ -0,0 +1,17 @@ +package com.oath.micro.server.manifest; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.Test; + +public class ManifestComparatorKeyNotFoundExceptionTest { + + @Test + public void testConstructor() { + ManifestComparatorKeyNotFoundException exception = new ManifestComparatorKeyNotFoundException( + "hello"); + assertThat(exception.getMessage(), is("hello")); + } + +} diff --git a/micro-memcached/README.md b/micro-memcached/README.md new file mode 100644 index 000000000..a99eb723d --- /dev/null +++ b/micro-memcached/README.md @@ -0,0 +1,34 @@ +# Elasticache plugin for BASE microservices + +[micro-memcached example apps](https://github.com/aol/micro-server/tree/master/micro-memcached/src/test/java/app) + +Basically Available Soft statE + +* Simple Memcached Client (ElastiCache as distributed / persistent map) + + +## Configurable properties + +Key used to store data used by the configured ManfiestComparator in Couchbase (default is default-key) + +elasticache.hostname is configuration endpoint of the elasticache cluster +elasticache.portis the port of the elasticache cluster +elasticache.retry.after.seconds is the number of seconds between each retry +elasticache.max.retries is the maximum number of retries before client throws error and gives up + + +## Getting The Microserver Couchbase Plugin + + +### Maven +```xml + + com.oath.microservices + micro-memcached + x.yz + +``` +### Gradle +```groovy + compile 'com.oath.microservices:micro-memcached:x.yz' + ``` diff --git a/micro-memcached/build.gradle b/micro-memcached/build.gradle new file mode 100644 index 000000000..b7767bad1 --- /dev/null +++ b/micro-memcached/build.gradle @@ -0,0 +1,95 @@ +description = 'micro-memcached' + +apply plugin: 'groovy' +apply plugin: 'java' + +repositories {} + +dependencies { + compile group: 'com.amazonaws', name: 'aws-java-sdk-elasticache', version: '1.11.126' + compile group: 'net.spy', name: 'spymemcached', version: '2.12.3' + compile project(':micro-core') + compile project(':micro-guava') + testCompile group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.3.3' + testCompile(group: 'org.spockframework', name: 'spock-core', version: '0.7-groovy-2.0') { + exclude(module: 'groovy-all') + } + testCompile group: 'com.cyrusinnovation', name: 'mockito-groovy-support', version: '1.3' + testCompile 'cglib:cglib-nodep:2.2' + testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: hamcrestVersion + testCompile project(':micro-grizzly-with-jersey') +} + +sourceSets { + main { + java { srcDirs = ['src/main/java'] } + resources { srcDir 'src/main/resources' } + } + + test { + java { srcDirs = [] } + groovy { srcDirs = ['src/test/java'] } + resources { srcDir 'src/test/resources' } + } + +} + +modifyPom { + project { + name 'Microserver elasticache' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-memcached' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'morrowgi' + name 'Gordon Morrow' + email 'gordon.morrow@teamaol.com' + } + developer { + id 'davidartplus' + name 'David Guzman' + email 'davidartplus@gmail.com' + } + } + + } +} + +extraArchive { + sources = true + tests = true + javadoc = true +} + +nexus { + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' +} + diff --git a/micro-memcached/src/main/java/com/oath/micro/server/memcached/DistributedCache.java b/micro-memcached/src/main/java/com/oath/micro/server/memcached/DistributedCache.java new file mode 100644 index 000000000..9225029ad --- /dev/null +++ b/micro-memcached/src/main/java/com/oath/micro/server/memcached/DistributedCache.java @@ -0,0 +1,15 @@ +package com.oath.micro.server.memcached; + +import java.net.SocketAddress; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.Future; + +public interface DistributedCache { + void setConnectionTested(boolean result); + boolean isAvailable(); + boolean add(K key, int exp, V value); + Optional get(K key); + Future flush(); + Map> getStats(); +} diff --git a/micro-memcached/src/main/java/com/oath/micro/server/memcached/DistributedCacheFactory.java b/micro-memcached/src/main/java/com/oath/micro/server/memcached/DistributedCacheFactory.java new file mode 100644 index 000000000..48be8d97e --- /dev/null +++ b/micro-memcached/src/main/java/com/oath/micro/server/memcached/DistributedCacheFactory.java @@ -0,0 +1,43 @@ +package com.oath.micro.server.memcached; + +import lombok.extern.slf4j.Slf4j; +import net.spy.memcached.MemcachedClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.net.InetSocketAddress; + +@Component +@Slf4j +public class DistributedCacheFactory { + + private final ElasticacheConfig config; + + @Autowired + public DistributedCacheFactory(ElasticacheConfig config) { + this.config = config; + } + + public DistributedCache create() { + try { + log.info("Creating Memcached Data connection for elasticache cluster: {}", config.getHostname()); + return new MemcachedCacheImpl(createMemcachedClient(), config.getRetryAfterSecs(), config.getMaxRetries()); + } + catch (Exception e) { + log.error("Failed to create transient data connection", e); + return null; + } + } + + private MemcachedClient createMemcachedClient() { + try { + log.info("Starting an instance of memcache client towards elasticache cluster"); + return new MemcachedClient(new InetSocketAddress(config.getHostname(), config.getPort())); + } catch (IOException e) { + log.error("Could not initialize connection to elasticache cluster", e); + return null; + } + + } +} diff --git a/micro-memcached/src/main/java/com/oath/micro/server/memcached/ElasticacheConfig.java b/micro-memcached/src/main/java/com/oath/micro/server/memcached/ElasticacheConfig.java new file mode 100644 index 000000000..7e365138b --- /dev/null +++ b/micro-memcached/src/main/java/com/oath/micro/server/memcached/ElasticacheConfig.java @@ -0,0 +1,39 @@ +package com.oath.micro.server.memcached; + + + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; + + +import net.spy.memcached.MemcachedClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.net.InetSocketAddress; + +@Slf4j +@Getter +@Configuration +public class ElasticacheConfig { + private final String hostname; + private final int port; + private final int retryAfterSecs; + private final int maxRetries; + + @Autowired + public ElasticacheConfig(@Value("${elasticache.hostname:null}") String hostname, + @Value("${elasticache.port:6379}") int port, + @Value("${elasticache.retry.after.seconds:1}") int retryAfterSecs, + @Value("${elasticache.max.retries:3}") int maxRetries) { + this.hostname = hostname; + this.port = port; + this.retryAfterSecs = retryAfterSecs; + this.maxRetries = maxRetries; + } +} + diff --git a/micro-memcached/src/main/java/com/oath/micro/server/memcached/ElasticachePlugin.java b/micro-memcached/src/main/java/com/oath/micro/server/memcached/ElasticachePlugin.java new file mode 100644 index 000000000..0a6136aaa --- /dev/null +++ b/micro-memcached/src/main/java/com/oath/micro/server/memcached/ElasticachePlugin.java @@ -0,0 +1,14 @@ +package com.oath.micro.server.memcached; + +import com.oath.micro.server.Plugin; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +public class ElasticachePlugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of(ElasticacheConfig.class, DistributedCacheFactory.class); + } +} diff --git a/micro-memcached/src/main/java/com/oath/micro/server/memcached/MemcachedCacheImpl.java b/micro-memcached/src/main/java/com/oath/micro/server/memcached/MemcachedCacheImpl.java new file mode 100644 index 000000000..815add31c --- /dev/null +++ b/micro-memcached/src/main/java/com/oath/micro/server/memcached/MemcachedCacheImpl.java @@ -0,0 +1,88 @@ +package com.oath.micro.server.memcached; + +import lombok.extern.slf4j.Slf4j; + +import java.net.SocketAddress; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.Future; + +import net.spy.memcached.MemcachedClient; +import net.spy.memcached.internal.OperationFuture; + + +@Slf4j +public class MemcachedCacheImpl implements DistributedCache { + + private final MemcachedClient memcachedClient; + private final int retryAfterSec; + private final int maxTry; + private volatile boolean available = false; + + public MemcachedCacheImpl(MemcachedClient memcachedClient, int retryAfterSec, int maxTry) { + this.memcachedClient = memcachedClient; + this.retryAfterSec = retryAfterSec; + this.maxTry = maxTry; + } + + @Override + public boolean add(final K key, int exp, final V value) { + + log.trace("Memcached add operation on key '{}', with value:{}", key, value); + boolean success = false; + int tryCount = 0; + + do { + try { + if (tryCount > 0) { + Thread.sleep(retryAfterSec * 1000); + log.warn("Retrying operation #{}", tryCount); + } + tryCount++; + success = memcachedClient.add(asString(key), exp, value) + .get(); + } catch (final Exception e) { + log.warn("Memcache set: {}", e.getMessage()); + } + } while (!success && tryCount < maxTry); + + if (!success) { + log.error("Failed to add key to Elasticache {}", key); + } + if (success && tryCount > 1) { + log.info("Connection restored OK to Elasticache cluster"); + } + + available = success; + return success; + } + + @Override + public Optional get(K key) { + return (Optional) Optional.ofNullable(memcachedClient.get(asString(key))); + } + + @Override + public Future flush() { + return memcachedClient.flush(); + } + + @Override + public Map> getStats() { + return memcachedClient.getStats(); + } + + @Override + public boolean isAvailable() { + return available; + } + + @Override + public final void setConnectionTested(final boolean available) { + this.available = available; + } + + private String asString(K key) { + return key.toString(); + } +} diff --git a/micro-memcached/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-memcached/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..1a8bfe803 --- /dev/null +++ b/micro-memcached/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.memcached.ElasticachePlugin diff --git a/micro-memcached/src/test/java/com/oath/micros/server/elasticache/MemcachedCacheImplTest.java b/micro-memcached/src/test/java/com/oath/micros/server/elasticache/MemcachedCacheImplTest.java new file mode 100644 index 000000000..cef022a13 --- /dev/null +++ b/micro-memcached/src/test/java/com/oath/micros/server/elasticache/MemcachedCacheImplTest.java @@ -0,0 +1,109 @@ +package com.oath.micros.server.elasticache; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.stub; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +import com.oath.micro.server.memcached.MemcachedCacheImpl; +import net.spy.memcached.internal.OperationFuture; +import org.junit.Before; +import org.junit.Test; +import net.spy.memcached.MemcachedClient; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +public class MemcachedCacheImplTest { + + MemcachedClient memcachedClient; + OperationFuture mockedFuture; + + @Before + public void setup() { + memcachedClient = mock(MemcachedClient.class); + + stub(memcachedClient.get("key1")).toReturn("value1"); + stub(memcachedClient.get("key2")).toReturn("value2"); + stub(memcachedClient.getStats()).toReturn(getStatsMap()); + mockedFuture = mock(OperationFuture.class); + stub(memcachedClient.add("keyAdd", 3600, "valueadd")).toReturn(mockedFuture); + stub(memcachedClient.flush()).toReturn(mockedFuture); + } + + Map> getStatsMap(){ + Map statsMap = new HashMap<>(); + Map> statsMapForAllHost = new HashMap<>(); + statsMap.put("hitCount", "10"); + statsMap.put("missCount", "1"); + statsMapForAllHost.put(new InetSocketAddress(1234), statsMap); + return statsMapForAllHost; + } + + @Test + public void happyPathGetTest() { + MemcachedCacheImpl cache = new MemcachedCacheImpl(memcachedClient, 3, 1); + assertEquals(Optional.ofNullable("value1"), cache.get("key1")); + assertEquals(Optional.ofNullable("value2"), cache.get("key2")); + } + + @Test + public void notExistingKeyGetTest() { + MemcachedCacheImpl cache = new MemcachedCacheImpl(memcachedClient, 3, 1); + assertEquals(Optional.empty(), cache.get("key3")); + } + + @Test + public void notExistingKeyPutTest() throws ExecutionException, InterruptedException { + MemcachedCacheImpl cache = new MemcachedCacheImpl(memcachedClient, 3, 1); + when(mockedFuture.get()).thenReturn(false); + assertFalse(cache.add("keyAdd", 3600, "valueadd")); + } + + @Test + public void existingKeyPutTest() throws ExecutionException, InterruptedException { + MemcachedCacheImpl cache = new MemcachedCacheImpl(memcachedClient, 3, 1); + when(mockedFuture.get()).thenReturn(true); + assertTrue(cache.add("keyAdd", 3600, "valueadd")); + } + + @Test + public void existingKeyPutTestWithRetry() throws ExecutionException, InterruptedException { + MemcachedCacheImpl cache = new MemcachedCacheImpl(memcachedClient, 3, 2); + when(mockedFuture.get()).thenReturn(false, true); + assertTrue(cache.add("keyAdd", 3600, "valueadd")); + } + + @Test + public void testIsAvailableFalse() { + MemcachedCacheImpl cache = new MemcachedCacheImpl(memcachedClient, 3, 1); + cache.setConnectionTested(false); + assertFalse(cache.isAvailable()); + } + + @Test + public void testIsAvailableTrue() { + MemcachedCacheImpl cache = new MemcachedCacheImpl(memcachedClient, 3, 1); + cache.setConnectionTested(true); + assertTrue(cache.isAvailable()); + } + + @Test + public void testFlush() throws ExecutionException, InterruptedException { + MemcachedCacheImpl cache = new MemcachedCacheImpl(memcachedClient, 3, 1); + when(mockedFuture.get()).thenReturn(false); + assertFalse((boolean)cache.flush().get()); + } + + @Test + public void testGetStats() { + MemcachedCacheImpl cache = new MemcachedCacheImpl(memcachedClient, 3, 1); + assertEquals(cache.getStats().toString(), "{0.0.0.0/0.0.0.0:1234={hitCount=10, missCount=1}}"); + } +} diff --git a/micro-metrics-datadog/README.md b/micro-metrics-datadog/README.md new file mode 100644 index 000000000..73a6c31b4 --- /dev/null +++ b/micro-metrics-datadog/README.md @@ -0,0 +1,47 @@ +# Datadog metrics plugin for Microserver + +[micro-metrics-datadog example apps](https://github.com/aol/micro-server/tree/master/micro-metrics-datadog/src/test/java/app/datadog/metrics) + +This adds support for sending the metrics to Datadog if an api key is provided in the application.properties file. For more detailed info see [metrics-datadog](https://github.com/coursera/metrics-datadog/) + +This plugin in combination with the micro-event-metrics plugin will send some metrics to datadog by default. Refer here (https://github.com/aol/micro-server/tree/master/micro-event-metrics) and (https://github.com/aol/micro-server/blob/master/micro-event-metrics/src/main/java/com/oath/micro/server/event/metrics/MetricsCatcher.java) + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-metrics-datadog/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-metrics-datadog) + +Simply add to the classpath + +Maven +```xml + + com.oath.microservices + micro-metrics-datadog + x.yz + +``` +Gradle +```groovy + compile 'com.oath.microservices:micro-metrics-datadog:x.yz' +``` + +# Configuring datadog metrics Reporters + + By default we report to the datadog every second. with the tag stage:dev. To modify these settings, change the values in the application.properties file. + For example: + The application.peroperties file can be modifed as follows + ``` +datadog.apikey = +datadog.tags = "stage:dev", "owner:abc" +datadog.report.period = 10 +datadog.report.timeunit = SECONDS +datadog.report.expansions= +``` + +Default setting is to report all available expansions. List is available here [Datadog expansions](http://static.javadoc.io/org.coursera/metrics-datadog/1.1.6/org/coursera/metrics/datadog/DatadogReporter.Expansion.html). + +This will report the metrics to datadog with tags as "stage:dev" and "owner:abc" and for every 10 seconds + + + + diff --git a/micro-metrics-datadog/build.gradle b/micro-metrics-datadog/build.gradle new file mode 100644 index 000000000..02603c86a --- /dev/null +++ b/micro-metrics-datadog/build.gradle @@ -0,0 +1,61 @@ +description = 'micro-metrics-datadog' + +dependencies { + compile('org.coursera:metrics-datadog:' + datadogMetricsVersion) + compile project(':micro-metrics') + compile project(':micro-event-metrics') + testCompile project(':micro-jackson-configuration') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') + testCompile project(':micro-error-codes') +} + +modifyPom { + project { + name 'Microserver metrics' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-metrics-datadog' + version "$version" + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'arunbcodes ' + name 'Arun Balakrishnan' + email 'arun.balakrishnan@teamaol.com' + } + } + + } +} + +extraArchive { + sources = true + tests = true + javadoc = true +} + +nexus { + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' +} + + diff --git a/micro-metrics-datadog/src/main/java/com/oath/micro/server/datadog/metrics/DatadogMetricsConfigurer.java b/micro-metrics-datadog/src/main/java/com/oath/micro/server/datadog/metrics/DatadogMetricsConfigurer.java new file mode 100644 index 000000000..7fc590e4a --- /dev/null +++ b/micro-metrics-datadog/src/main/java/com/oath/micro/server/datadog/metrics/DatadogMetricsConfigurer.java @@ -0,0 +1,87 @@ +package com.oath.micro.server.datadog.metrics; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; +import java.util.Optional; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import cyclops.control.Maybe; +import lombok.extern.slf4j.Slf4j; +import org.coursera.metrics.datadog.DatadogReporter; +import org.coursera.metrics.datadog.transport.HttpTransport; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +import com.codahale.metrics.MetricRegistry; +import com.ryantenney.metrics.spring.config.annotation.EnableMetrics; +import com.ryantenney.metrics.spring.config.annotation.MetricsConfigurerAdapter; + +import lombok.Getter; + +@Configuration +@EnableMetrics +@Slf4j +public class DatadogMetricsConfigurer extends MetricsConfigurerAdapter { + + private String apiKey; + private List tags; + private int period; + private TimeUnit timeUnit; + @Getter + private EnumSet expansions; + + private final String host; + + @Autowired + public DatadogMetricsConfigurer(@Value("${datadog.apikey:#{null}}") String apiKey, + @Value("${datadog.tags:{\"stage:dev\"}}") String tags, + @Value("${datadog.report.period:1}") int period, + @Value("${datadog.report.timeunit:SECONDS}") TimeUnit timeUnit, + @Value("${datadog.report.expansions:#{null}}") String expStr, + @Value("${host.address:#{null}}") String host){ + this.apiKey = apiKey; + this.tags = Arrays.asList(Optional.ofNullable(tags) + .orElse("") + .split(",")); + this.period = period; + this.timeUnit = timeUnit; + this.expansions = expansions(expStr); + this.host = host; + } + + private EnumSet expansions(String expStr) { + return Maybe.just(Maybe.ofNullable(expStr) + .map(s -> s.split(",")) + .stream() + .flatMap(Stream::of) + .map(String::trim) + .map(DatadogReporter.Expansion::valueOf) + .collect(Collectors.toCollection(() -> EnumSet.noneOf(DatadogReporter.Expansion.class)))) + .filter(s -> !s.isEmpty()) + .orElse(DatadogReporter.Expansion.ALL); + } + + @Override + public void configureReporters(MetricRegistry metricRegistry) { + if (Objects.isNull(apiKey)) { + log.error("The 'datadog.apikey' is null. Datadog reporting will be ignored."); + return; + } + HttpTransport httpTransport = new HttpTransport.Builder().withApiKey(apiKey) + .build(); + EnumSet expansions = DatadogReporter.Expansion.ALL; + DatadogReporter.Builder builder = DatadogReporter.forRegistry(metricRegistry) + .withTransport(httpTransport) + .withExpansions(expansions) + .withTags(tags); + + DatadogReporter reporter = (Objects.nonNull(host) ? builder.withHost(host) : builder).build(); + reporter.start(period, timeUnit); + registerReporter(reporter); + } +} diff --git a/micro-metrics-datadog/src/main/java/com/oath/micro/server/datadog/metrics/DatadogMetricsPlugin.java b/micro-metrics-datadog/src/main/java/com/oath/micro/server/datadog/metrics/DatadogMetricsPlugin.java new file mode 100644 index 000000000..04bc21d56 --- /dev/null +++ b/micro-metrics-datadog/src/main/java/com/oath/micro/server/datadog/metrics/DatadogMetricsPlugin.java @@ -0,0 +1,23 @@ +package com.oath.micro.server.datadog.metrics; + +import com.oath.micro.server.Plugin; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +/** + * + * Collections of Spring configuration classes (Classes annotated with @Configuration) + * that configure various useful pieces of functionality - such as property file loading, + * datasources, scheduling etc + * + * @author arunbcodes + */ + +public class DatadogMetricsPlugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of( DatadogMetricsConfigurer.class); + } +} diff --git a/micro-metrics-datadog/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-metrics-datadog/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..8ab22e22d --- /dev/null +++ b/micro-metrics-datadog/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.datadog.metrics.DatadogMetricsPlugin \ No newline at end of file diff --git a/micro-metrics-datadog/src/test/java/app/datadog/metrics/com/aol/micro/server/DatadogMetricsRunnerTest.java b/micro-metrics-datadog/src/test/java/app/datadog/metrics/com/aol/micro/server/DatadogMetricsRunnerTest.java new file mode 100644 index 000000000..796cdda74 --- /dev/null +++ b/micro-metrics-datadog/src/test/java/app/datadog/metrics/com/aol/micro/server/DatadogMetricsRunnerTest.java @@ -0,0 +1,38 @@ +package app.datadog.metrics.com.aol.micro.server; + +import com.oath.micro.server.testing.RestAgent; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class DatadogMetricsRunnerTest { + RestAgent rest = new RestAgent(); + DatadogTestMain server; + + @Before + public void startServer() { + server.start(); + } + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() { + + try { + assertThat(rest.get("http://localhost:8080/datadog-app/metrics/ping"), is("ok")); + } catch (Exception e) { + + } + + try { + Thread.sleep(5000); + } catch (Exception e) {} + + } +} diff --git a/micro-metrics-datadog/src/test/java/app/datadog/metrics/com/aol/micro/server/DatadogMetricsStatusResource.java b/micro-metrics-datadog/src/test/java/app/datadog/metrics/com/aol/micro/server/DatadogMetricsStatusResource.java new file mode 100644 index 000000000..529b61179 --- /dev/null +++ b/micro-metrics-datadog/src/test/java/app/datadog/metrics/com/aol/micro/server/DatadogMetricsStatusResource.java @@ -0,0 +1,36 @@ +package app.datadog.metrics.com.aol.micro.server; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.auto.discovery.RestResource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +@Component +@Path("/metrics") +@Rest +public class DatadogMetricsStatusResource implements RestResource { + + private final DatadogTestService service; + + @Autowired + public DatadogMetricsStatusResource(DatadogTestService service) { + this.service = service; + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + try { + service.someMethod(); + } catch (Exception e) { + System.out.println(e); + } + return "ok"; + } + +} diff --git a/micro-metrics-datadog/src/test/java/app/datadog/metrics/com/aol/micro/server/DatadogTestMain.java b/micro-metrics-datadog/src/test/java/app/datadog/metrics/com/aol/micro/server/DatadogTestMain.java new file mode 100644 index 000000000..8620b840e --- /dev/null +++ b/micro-metrics-datadog/src/test/java/app/datadog/metrics/com/aol/micro/server/DatadogTestMain.java @@ -0,0 +1,18 @@ +package app.datadog.metrics.com.aol.micro.server; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; + +@Microserver(basePackages = { "app.datadog.metrics.com.oath.micro.server", "com.oath.micro.server.datadog.metrics", "com.oath.micro.server.event.metrics"}) +public class DatadogTestMain { + + public static final String CONTEXT = "datadog-app"; + + public static void start() { + new MicroserverApp(() -> CONTEXT).start(); + } + + public static void stop() { + new MicroserverApp(() -> CONTEXT).stop(); + } +} diff --git a/micro-metrics-datadog/src/test/java/app/datadog/metrics/com/aol/micro/server/DatadogTestService.java b/micro-metrics-datadog/src/test/java/app/datadog/metrics/com/aol/micro/server/DatadogTestService.java new file mode 100644 index 000000000..3b88de7c1 --- /dev/null +++ b/micro-metrics-datadog/src/test/java/app/datadog/metrics/com/aol/micro/server/DatadogTestService.java @@ -0,0 +1,13 @@ +package app.datadog.metrics.com.aol.micro.server; + +import com.oath.micro.server.errors.ErrorCode; +import com.oath.micro.server.errors.InvalidStateException; +import org.springframework.stereotype.Component; + +@Component +public class DatadogTestService { + + public void someMethod() { + throw new InvalidStateException(ErrorCode.high(100,"Some Error Message").format()); + } +} diff --git a/micro-metrics-datadog/src/test/java/com/oath/micro/server/datadog/metrics/DatadogMetricsConfigurerTest.java b/micro-metrics-datadog/src/test/java/com/oath/micro/server/datadog/metrics/DatadogMetricsConfigurerTest.java new file mode 100644 index 000000000..c417dded5 --- /dev/null +++ b/micro-metrics-datadog/src/test/java/com/oath/micro/server/datadog/metrics/DatadogMetricsConfigurerTest.java @@ -0,0 +1,54 @@ +package com.oath.micro.server.datadog.metrics; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.util.EnumSet; +import java.util.concurrent.TimeUnit; + +import org.coursera.metrics.datadog.DatadogReporter; +import org.junit.Test; + +public class DatadogMetricsConfigurerTest { + + private String apiKey = "api"; + private String tags = "tags"; + private int period = 10; + private TimeUnit timeUnit = TimeUnit.DAYS; + + @Test + public void expansionsDefault() { + String expStr = null; + DatadogMetricsConfigurer c = new DatadogMetricsConfigurer( + apiKey, tags, period, timeUnit, expStr, null); + assertThat(c.getExpansions(), equalTo(DatadogReporter.Expansion.ALL)); + } + + @Test + public void expansionsSingle() { + String expStr = DatadogReporter.Expansion.MEDIAN.name(); + DatadogMetricsConfigurer c = new DatadogMetricsConfigurer( + apiKey, tags, period, timeUnit, expStr, null); + assertThat(c.getExpansions(), equalTo(EnumSet.of(DatadogReporter.Expansion.MEDIAN))); + } + + @Test + public void expansionsTwo() { + String expStr = DatadogReporter.Expansion.MEDIAN.name() + "," + DatadogReporter.Expansion.RATE_15_MINUTE.name(); + DatadogMetricsConfigurer c = new DatadogMetricsConfigurer( + apiKey, tags, period, timeUnit, expStr, null); + assertThat(c.getExpansions(), + equalTo(EnumSet.of(DatadogReporter.Expansion.MEDIAN, DatadogReporter.Expansion.RATE_15_MINUTE))); + } + + @Test + public void expansionsTwoSpace() { + String expStr = DatadogReporter.Expansion.MEDIAN.name() + " , " + + DatadogReporter.Expansion.RATE_15_MINUTE.name(); + DatadogMetricsConfigurer c = new DatadogMetricsConfigurer( + apiKey, tags, period, timeUnit, expStr, null); + assertThat(c.getExpansions(), + equalTo(EnumSet.of(DatadogReporter.Expansion.MEDIAN, DatadogReporter.Expansion.RATE_15_MINUTE))); + } + +} diff --git a/micro-metrics-datadog/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-metrics-datadog/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..9eb341321 --- /dev/null +++ b/micro-metrics-datadog/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-metrics-datadog/src/test/resources/application.properties b/micro-metrics-datadog/src/test/resources/application.properties new file mode 100644 index 000000000..f35fe5593 --- /dev/null +++ b/micro-metrics-datadog/src/test/resources/application.properties @@ -0,0 +1 @@ +datadog.apikey = "" \ No newline at end of file diff --git a/micro-metrics/README.md b/micro-metrics/README.md new file mode 100644 index 000000000..632f2d3bd --- /dev/null +++ b/micro-metrics/README.md @@ -0,0 +1,50 @@ +# Dropwizard metrics plugin for Microserver + +[micro-metrics example apps](https://github.com/aol/micro-server/tree/master/micro-metrics/src/test/java/app/metrics) + +This adds support for Dropwizard metrics annotations on Spring beans. For more detailed info see [Metrics Spring](http://www.ryantenney.com/metrics-spring/) + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-metrics/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-metrics) + +Simply add to the classpath + +Maven + + + com.oath.microservices + micro-metrics + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-metrics:x.yz' + + # Configuring Metrics Reporters + + By default we report to the console hourly and to JMX. To configure other reporters, this can be done via the setInit method on the CodahaleMetricsConfigurer class e.g. + + CodahaleMetricsConfigurer.setInit( metricRegistry -> + TestReporter.forRegistry(metricRegistry) + .build() + .start(10, TimeUnit.MILLISECONDS)); + + +# An example Spring Bean capturing Metrics + + + + @Component + public class TimedResource { + + + @Timed + public String times(){ + + return "ok!"; + } + } + + diff --git a/micro-metrics/build.gradle b/micro-metrics/build.gradle index 693dc6b32..485252a5e 100644 --- a/micro-metrics/build.gradle +++ b/micro-metrics/build.gradle @@ -1,60 +1,65 @@ description = 'micro-metrics' + dependencies { - compile ('com.ryantenney.metrics:metrics-spring:'+springMetricsVersion){ - exclude(module: 'org.springframework') - } - compile project(':micro-core') - testCompile project(':micro-jackson-configuration') - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') + compile('com.ryantenney.metrics:metrics-spring:' + springMetricsVersion) { + exclude(module: 'org.springframework') + exclude(group: 'io.dropwizard.metrics', module: 'metrics-core') + } + + compile("io.dropwizard.metrics:metrics-core:3.2.3") + + compile project(':micro-core') + testCompile project(':micro-jackson-configuration') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') } modifyPom { - project { - name 'Microserver metrics' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-metrics' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - } - - } + project { + name 'Microserver metrics' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-metrics' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-metrics/readme.md b/micro-metrics/readme.md deleted file mode 100644 index 6eff4ace5..000000000 --- a/micro-metrics/readme.md +++ /dev/null @@ -1,50 +0,0 @@ -# Dropwizard metrics plugin for Microserver - -[micro-metrics example apps](https://github.com/aol/micro-server/tree/master/micro-metrics/src/test/java/app/metrics) - -This adds support for Dropwizard metrics annotations on Spring beans. For more detailed info see [Metrics Spring](http://www.ryantenney.com/metrics-spring/) - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-metrics/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-metrics) - -Simply add to the classpath - -Maven - - - com.aol.microservices - micro-metrics - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-metrics:x.yz' - - # Configuring Metrics Reporters - - By default we report to the console hourly and to JMX. To configure other reporters, this can be done via the setInit method on the CodahaleMetricsConfigurer class e.g. - - CodahaleMetricsConfigurer.setInit( metricRegistry -> - TestReporter.forRegistry(metricRegistry) - .build() - .start(10, TimeUnit.MILLISECONDS)); - - -# An example Spring Bean capturing Metrics - - - - @Component - public class TimedResource { - - - @Timed - public String times(){ - - return "ok!"; - } - } - - \ No newline at end of file diff --git a/micro-metrics/src/main/java/com/aol/micro/server/spring/metrics/CodahaleMetricsConfigurer.java b/micro-metrics/src/main/java/com/aol/micro/server/spring/metrics/CodahaleMetricsConfigurer.java deleted file mode 100644 index f7024bd6a..000000000 --- a/micro-metrics/src/main/java/com/aol/micro/server/spring/metrics/CodahaleMetricsConfigurer.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.aol.micro.server.spring.metrics; - -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; - -import lombok.Setter; - -import org.springframework.context.annotation.Configuration; - -import com.codahale.metrics.ConsoleReporter; -import com.codahale.metrics.JmxReporter; -import com.codahale.metrics.MetricRegistry; -import com.ryantenney.metrics.spring.config.annotation.EnableMetrics; -import com.ryantenney.metrics.spring.config.annotation.MetricsConfigurerAdapter; - -@Configuration -@EnableMetrics -public class CodahaleMetricsConfigurer extends MetricsConfigurerAdapter { - - @Setter - private static volatile Consumer init = (metricRegistry)-> { - - JmxReporter.forRegistry(metricRegistry) .build() - .start(); - - ConsoleReporter - .forRegistry(metricRegistry) - .build() - .start(1, TimeUnit.HOURS); - }; - - public static void switchOff(){ - setInit( (m) -> {}); - } - - @Override - public void configureReporters(MetricRegistry metricRegistry) { - CodahaleMetricsConfigurer.init.accept(metricRegistry); - } - -} \ No newline at end of file diff --git a/micro-metrics/src/main/java/com/aol/micro/server/spring/metrics/MetricsPlugin.java b/micro-metrics/src/main/java/com/aol/micro/server/spring/metrics/MetricsPlugin.java deleted file mode 100644 index cdffaa408..000000000 --- a/micro-metrics/src/main/java/com/aol/micro/server/spring/metrics/MetricsPlugin.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aol.micro.server.spring.metrics; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; - -/** - * - * Collections of Spring configuration classes (Classes annotated with @Configuration) - * that configure various useful pieces of functionality - such as property file loading, - * datasources, scheduling etc - * - * @author johnmcclean - * - */ -public class MetricsPlugin implements Plugin{ - - @Override - public PSetX springClasses() { - return PSetX.of( CodahaleMetricsConfigurer.class); - } - -} diff --git a/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/CodahaleMetricsConfigurer.java b/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/CodahaleMetricsConfigurer.java new file mode 100644 index 000000000..2d1fac173 --- /dev/null +++ b/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/CodahaleMetricsConfigurer.java @@ -0,0 +1,42 @@ +package com.oath.micro.server.spring.metrics; + +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +import org.springframework.context.annotation.Configuration; + +import com.codahale.metrics.ConsoleReporter; +import com.codahale.metrics.JmxReporter; +import com.codahale.metrics.MetricRegistry; +import com.ryantenney.metrics.spring.config.annotation.EnableMetrics; +import com.ryantenney.metrics.spring.config.annotation.MetricsConfigurerAdapter; + +import lombok.Setter; + +@Configuration +@EnableMetrics +public class CodahaleMetricsConfigurer extends MetricsConfigurerAdapter { + + @Setter + private static volatile Consumer init = (metricRegistry) -> { + + JmxReporter.forRegistry(metricRegistry) + .build() + .start(); + + ConsoleReporter.forRegistry(metricRegistry) + .build() + .start(1, TimeUnit.HOURS); + }; + + public static void switchOff() { + setInit((m) -> { + }); + } + + @Override + public void configureReporters(MetricRegistry metricRegistry) { + CodahaleMetricsConfigurer.init.accept(metricRegistry); + } + +} \ No newline at end of file diff --git a/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/InstantGauge.java b/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/InstantGauge.java new file mode 100644 index 000000000..6161860fb --- /dev/null +++ b/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/InstantGauge.java @@ -0,0 +1,24 @@ +package com.oath.micro.server.spring.metrics; + +import java.util.concurrent.atomic.AtomicLong; + +import com.codahale.metrics.Gauge; + + +public class InstantGauge implements Gauge { + + private final AtomicLong counter = new AtomicLong(0l); + + @Override + public Long getValue() { + return counter.getAndSet(0l); + } + + public void increment() { + counter.incrementAndGet(); + } + + public void increase(long value) { + counter.addAndGet(value); + } +} diff --git a/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/MetricsPlugin.java b/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/MetricsPlugin.java new file mode 100644 index 000000000..7f04d2acf --- /dev/null +++ b/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/MetricsPlugin.java @@ -0,0 +1,27 @@ +package com.oath.micro.server.spring.metrics; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.spring.metrics.health.HealthCheckRunner; +import com.oath.micro.server.spring.metrics.health.HealthResource; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +/** + * + * Collections of Spring configuration classes (Classes annotated with @Configuration) + * that configure various useful pieces of functionality - such as property file loading, + * datasources, scheduling etc + * + * @author johnmcclean + * + */ +public class MetricsPlugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of(CodahaleMetricsConfigurer.class, HealthCheckRunner.class, HealthResource.class); + } + +} diff --git a/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/health/HealthCheckRunner.java b/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/health/HealthCheckRunner.java new file mode 100644 index 000000000..df4bab8b2 --- /dev/null +++ b/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/health/HealthCheckRunner.java @@ -0,0 +1,36 @@ +package com.oath.micro.server.spring.metrics.health; + +import cyclops.companion.Semigroups; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.HealthStatusChecker; +import com.codahale.metrics.health.HealthCheckRegistry; + +@Component +public class HealthCheckRunner implements HealthStatusChecker { + + private final HealthCheckRegistry healthChecks; + private final long healthDelay; + private volatile long lastRan = 0; + private volatile boolean lastRanValue = true; + + public HealthCheckRunner(@Value("${metrics.health.delay:1000}") long healthDelay, + HealthCheckRegistry healthChecks) { + this.healthDelay = healthDelay; + this.healthChecks = healthChecks; + } + + @Override + public boolean isOk() { + if (System.currentTimeMillis() - healthDelay < lastRan) + return lastRanValue; + return healthChecks.runHealthChecks() + .values() + .stream() + .map(hc -> hc.isHealthy()) + .reduce(true, Semigroups.booleanConjunction); + } + +} diff --git a/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/health/HealthResource.java b/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/health/HealthResource.java new file mode 100644 index 000000000..ddb6f5d43 --- /dev/null +++ b/micro-metrics/src/main/java/com/oath/micro/server/spring/metrics/health/HealthResource.java @@ -0,0 +1,32 @@ +package com.oath.micro.server.spring.metrics.health; + +import java.util.Map; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.CommonRestResource; +import com.oath.micro.server.auto.discovery.SingletonRestResource; +import com.codahale.metrics.health.HealthCheck.Result; +import com.codahale.metrics.health.HealthCheckRegistry; + +@Path("/health") +@Component +public class HealthResource implements CommonRestResource, SingletonRestResource { + + final HealthCheckRegistry healthChecks; + + public HealthResource(HealthCheckRegistry healthChecks) { + this.healthChecks = healthChecks; + } + + @GET + @Produces("application/json") + public Map health() { + return healthChecks.runHealthChecks(); + + } +} diff --git a/micro-metrics/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-metrics/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index a6b12afbb..000000000 --- a/micro-metrics/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.spring.metrics.MetricsPlugin \ No newline at end of file diff --git a/micro-metrics/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-metrics/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..cc5e4e6b0 --- /dev/null +++ b/micro-metrics/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.spring.metrics.MetricsPlugin \ No newline at end of file diff --git a/micro-metrics/src/test/java/app/health/com/oath/micro/server/HealthRunnerTest.java b/micro-metrics/src/test/java/app/health/com/oath/micro/server/HealthRunnerTest.java new file mode 100644 index 000000000..dc71a101a --- /dev/null +++ b/micro-metrics/src/test/java/app/health/com/oath/micro/server/HealthRunnerTest.java @@ -0,0 +1,56 @@ +package app.health.com.oath.micro.server; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.spring.metrics.CodahaleMetricsConfigurer; +import com.oath.micro.server.testing.RestAgent; + +import app.metrics.com.oath.micro.server.TestReporter; + +@Configuration +@ComponentScan(basePackages = { "app.metrics.com.oath.micro.server" }) +public class HealthRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + CodahaleMetricsConfigurer.setInit(metricRegistry -> TestReporter.forRegistry(metricRegistry) + .build() + .start(10, TimeUnit.MILLISECONDS)); + + server = new MicroserverApp( + HealthRunnerTest.class, () -> "simple-app"); + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException, IOException { + + assertThat(rest.getJson("http://localhost:8080/simple-app/health"), + is("{\"myHealthCheck\":{\"healthy\":true}}")); + assertThat(rest.get("http://localhost:8080/simple-app/test"), is("true")); + + } + +} diff --git a/micro-metrics/src/test/java/app/health/com/oath/micro/server/HealthTestResource.java b/micro-metrics/src/test/java/app/health/com/oath/micro/server/HealthTestResource.java new file mode 100644 index 000000000..139d8e3fd --- /dev/null +++ b/micro-metrics/src/test/java/app/health/com/oath/micro/server/HealthTestResource.java @@ -0,0 +1,25 @@ +package app.health.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.HealthStatusChecker; +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/test") +public class HealthTestResource { + + @Autowired + HealthStatusChecker status; + + @GET + @Produces("text/plain") + public String health() { + return "" + status.isOk(); + + } +} diff --git a/micro-metrics/src/test/java/app/health/com/oath/micro/server/MyHealthCheck.java b/micro-metrics/src/test/java/app/health/com/oath/micro/server/MyHealthCheck.java new file mode 100644 index 000000000..f5d858ce4 --- /dev/null +++ b/micro-metrics/src/test/java/app/health/com/oath/micro/server/MyHealthCheck.java @@ -0,0 +1,15 @@ +package app.health.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +import com.codahale.metrics.health.HealthCheck; + +@Component +public class MyHealthCheck extends HealthCheck { + + @Override + protected Result check() throws Exception { + return Result.healthy(); + } + +} diff --git a/micro-metrics/src/test/java/app/metrics/com/aol/micro/server/MetricsRunnerTest.java b/micro-metrics/src/test/java/app/metrics/com/aol/micro/server/MetricsRunnerTest.java deleted file mode 100644 index 0fd8eea3a..000000000 --- a/micro-metrics/src/test/java/app/metrics/com/aol/micro/server/MetricsRunnerTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package app.metrics.com.aol.micro.server; - - -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.io.IOException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.spring.metrics.CodahaleMetricsConfigurer; -import com.aol.micro.server.testing.RestAgent; - -@Configuration -@ComponentScan(basePackages = { "app.metrics.com.aol.micro.server" }) -public class MetricsRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - CodahaleMetricsConfigurer.setInit( metricRegistry -> TestReporter - .forRegistry(metricRegistry) - .build() - .start(10, TimeUnit.MILLISECONDS)); - - server = new MicroserverApp( MetricsRunnerTest.class, ()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException, IOException{ - - - - - - assertThat(rest.get("http://localhost:8080/simple-app/metrics/ping"),is("ok")); - - - assertThat(TestReporter.getTimer().size(),greaterThan(0)); - } - - - -} diff --git a/micro-metrics/src/test/java/app/metrics/com/aol/micro/server/MetricsStatusResource.java b/micro-metrics/src/test/java/app/metrics/com/aol/micro/server/MetricsStatusResource.java deleted file mode 100644 index de803313b..000000000 --- a/micro-metrics/src/test/java/app/metrics/com/aol/micro/server/MetricsStatusResource.java +++ /dev/null @@ -1,28 +0,0 @@ -package app.metrics.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import app.metrics.com.aol.micro.server.TimedResource; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/metrics") -public class MetricsStatusResource implements RestResource { - - @Autowired - TimedResource timed; - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - timed.times(); - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-metrics/src/test/java/app/metrics/com/aol/micro/server/TestReporter.java b/micro-metrics/src/test/java/app/metrics/com/aol/micro/server/TestReporter.java deleted file mode 100644 index cfcf0136e..000000000 --- a/micro-metrics/src/test/java/app/metrics/com/aol/micro/server/TestReporter.java +++ /dev/null @@ -1,170 +0,0 @@ -package app.metrics.com.aol.micro.server; - -import java.io.PrintStream; -import java.util.Locale; -import java.util.SortedMap; -import java.util.TimeZone; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - -import lombok.Getter; - -import com.codahale.metrics.Clock; -import com.codahale.metrics.ConsoleReporter; -import com.codahale.metrics.Counter; -import com.codahale.metrics.Gauge; -import com.codahale.metrics.Histogram; -import com.codahale.metrics.Meter; -import com.codahale.metrics.MetricFilter; -import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.ScheduledReporter; -import com.codahale.metrics.Timer; - - - -public class TestReporter extends ScheduledReporter { - - @Getter - private static volatile SortedMap timer = new TreeMap<>(); - - protected TestReporter(MetricRegistry registry, String name, - MetricFilter filter, TimeUnit rateUnit, TimeUnit durationUnit) { - super(registry, name, filter, rateUnit, durationUnit); - - } - - - public static Builder forRegistry(MetricRegistry registry) { - return new Builder(registry); - } - - @Override - public void report(SortedMap gauges, - SortedMap counters, - SortedMap histograms, - SortedMap meters, SortedMap timers) { - this.timer = timers; - - - } - - public static class Builder { - private final MetricRegistry registry; - private PrintStream output; - private Locale locale; - private Clock clock; - private TimeZone timeZone; - private TimeUnit rateUnit; - private TimeUnit durationUnit; - private MetricFilter filter; - - private Builder(MetricRegistry registry) { - this.registry = registry; - this.output = System.out; - this.locale = Locale.getDefault(); - this.clock = Clock.defaultClock(); - this.timeZone = TimeZone.getDefault(); - this.rateUnit = TimeUnit.SECONDS; - this.durationUnit = TimeUnit.MILLISECONDS; - this.filter = MetricFilter.ALL; - } - - /** - * Write to the given {@link PrintStream}. - * - * @param output a {@link PrintStream} instance. - * @return {@code this} - */ - public Builder outputTo(PrintStream output) { - this.output = output; - return this; - } - - /** - * Format numbers for the given {@link Locale}. - * - * @param locale a {@link Locale} - * @return {@code this} - */ - public Builder formattedFor(Locale locale) { - this.locale = locale; - return this; - } - - /** - * Use the given {@link Clock} instance for the time. - * - * @param clock a {@link Clock} instance - * @return {@code this} - */ - public Builder withClock(Clock clock) { - this.clock = clock; - return this; - } - - /** - * Use the given {@link TimeZone} for the time. - * - * @param timeZone a {@link TimeZone} - * @return {@code this} - */ - public Builder formattedFor(TimeZone timeZone) { - this.timeZone = timeZone; - return this; - } - - /** - * Convert rates to the given time unit. - * - * @param rateUnit a unit of time - * @return {@code this} - */ - public Builder convertRatesTo(TimeUnit rateUnit) { - this.rateUnit = rateUnit; - return this; - } - - /** - * Convert durations to the given time unit. - * - * @param durationUnit a unit of time - * @return {@code this} - */ - public Builder convertDurationsTo(TimeUnit durationUnit) { - this.durationUnit = durationUnit; - return this; - } - - /** - * Only report metrics which match the given filter. - * - * @param filter a {@link MetricFilter} - * @return {@code this} - */ - public Builder filter(MetricFilter filter) { - this.filter = filter; - return this; - } - - /** - * Builds a {@link ConsoleReporter} with the given properties. - * - * @return a {@link ConsoleReporter} - */ - public TestReporter build() { - return new TestReporter(registry, - // output, - "name", - // locale, - // clock, - // timeZone, - this.filter, - rateUnit, - durationUnit - ); - } - } - - -} - diff --git a/micro-metrics/src/test/java/app/metrics/com/aol/micro/server/TimedResource.java b/micro-metrics/src/test/java/app/metrics/com/aol/micro/server/TimedResource.java deleted file mode 100644 index a2e3f2910..000000000 --- a/micro-metrics/src/test/java/app/metrics/com/aol/micro/server/TimedResource.java +++ /dev/null @@ -1,17 +0,0 @@ -package app.metrics.com.aol.micro.server; - -import org.springframework.stereotype.Component; - -import com.codahale.metrics.annotation.Timed; -import com.ryantenney.metrics.annotation.Counted; - -@Component -public class TimedResource { - - - @Timed - public String times(){ - - return "ok!"; - } -} diff --git a/micro-metrics/src/test/java/app/metrics/com/oath/micro/server/MetricsRunnerTest.java b/micro-metrics/src/test/java/app/metrics/com/oath/micro/server/MetricsRunnerTest.java new file mode 100644 index 000000000..3a77bc3eb --- /dev/null +++ b/micro-metrics/src/test/java/app/metrics/com/oath/micro/server/MetricsRunnerTest.java @@ -0,0 +1,61 @@ +package app.metrics.com.oath.micro.server; + + +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.spring.metrics.CodahaleMetricsConfigurer; +import com.oath.micro.server.testing.RestAgent; + +@Configuration +@ComponentScan(basePackages = { "app.metrics.com.aol.micro.server" }) +public class MetricsRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + CodahaleMetricsConfigurer.setInit( metricRegistry -> TestReporter + .forRegistry(metricRegistry) + .build() + .start(10, TimeUnit.MILLISECONDS)); + + server = new MicroserverApp( MetricsRunnerTest.class, ()-> "simple-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException, IOException{ + + + + + + assertThat(rest.get("http://localhost:8080/simple-app/metrics/ping"),is("ok")); + + + assertThat(TestReporter.getTimer().size(),greaterThan(0)); + } + + + +} diff --git a/micro-metrics/src/test/java/app/metrics/com/oath/micro/server/MetricsStatusResource.java b/micro-metrics/src/test/java/app/metrics/com/oath/micro/server/MetricsStatusResource.java new file mode 100644 index 000000000..3559c2590 --- /dev/null +++ b/micro-metrics/src/test/java/app/metrics/com/oath/micro/server/MetricsStatusResource.java @@ -0,0 +1,26 @@ +package app.metrics.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/metrics") +public class MetricsStatusResource implements RestResource { + + @Autowired + TimedResource timed; + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + timed.times(); + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-metrics/src/test/java/app/metrics/com/oath/micro/server/TestReporter.java b/micro-metrics/src/test/java/app/metrics/com/oath/micro/server/TestReporter.java new file mode 100644 index 000000000..530782ee0 --- /dev/null +++ b/micro-metrics/src/test/java/app/metrics/com/oath/micro/server/TestReporter.java @@ -0,0 +1,170 @@ +package app.metrics.com.oath.micro.server; + +import java.io.PrintStream; +import java.util.Locale; +import java.util.SortedMap; +import java.util.TimeZone; +import java.util.TreeMap; +import java.util.concurrent.TimeUnit; + +import lombok.Getter; + +import com.codahale.metrics.Clock; +import com.codahale.metrics.ConsoleReporter; +import com.codahale.metrics.Counter; +import com.codahale.metrics.Gauge; +import com.codahale.metrics.Histogram; +import com.codahale.metrics.Meter; +import com.codahale.metrics.MetricFilter; +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.ScheduledReporter; +import com.codahale.metrics.Timer; + + + +public class TestReporter extends ScheduledReporter { + + @Getter + private static volatile SortedMap timer = new TreeMap<>(); + + protected TestReporter(MetricRegistry registry, String name, + MetricFilter filter, TimeUnit rateUnit, TimeUnit durationUnit) { + super(registry, name, filter, rateUnit, durationUnit); + + } + + + public static Builder forRegistry(MetricRegistry registry) { + return new Builder(registry); + } + + @Override + public void report(SortedMap gauges, + SortedMap counters, + SortedMap histograms, + SortedMap meters, SortedMap timers) { + this.timer = timers; + + + } + + public static class Builder { + private final MetricRegistry registry; + private PrintStream output; + private Locale locale; + private Clock clock; + private TimeZone timeZone; + private TimeUnit rateUnit; + private TimeUnit durationUnit; + private MetricFilter filter; + + private Builder(MetricRegistry registry) { + this.registry = registry; + this.output = System.out; + this.locale = Locale.getDefault(); + this.clock = Clock.defaultClock(); + this.timeZone = TimeZone.getDefault(); + this.rateUnit = TimeUnit.SECONDS; + this.durationUnit = TimeUnit.MILLISECONDS; + this.filter = MetricFilter.ALL; + } + + /** + * Write to the given {@link PrintStream}. + * + * @param output a {@link PrintStream} instance. + * @return {@code this} + */ + public Builder outputTo(PrintStream output) { + this.output = output; + return this; + } + + /** + * Format numbers for the given {@link Locale}. + * + * @param locale a {@link Locale} + * @return {@code this} + */ + public Builder formattedFor(Locale locale) { + this.locale = locale; + return this; + } + + /** + * Use the given {@link Clock} instance for the time. + * + * @param clock a {@link Clock} instance + * @return {@code this} + */ + public Builder withClock(Clock clock) { + this.clock = clock; + return this; + } + + /** + * Use the given {@link TimeZone} for the time. + * + * @param timeZone a {@link TimeZone} + * @return {@code this} + */ + public Builder formattedFor(TimeZone timeZone) { + this.timeZone = timeZone; + return this; + } + + /** + * Convert rates to the given time unit. + * + * @param rateUnit a unit of time + * @return {@code this} + */ + public Builder convertRatesTo(TimeUnit rateUnit) { + this.rateUnit = rateUnit; + return this; + } + + /** + * Convert durations to the given time unit. + * + * @param durationUnit a unit of time + * @return {@code this} + */ + public Builder convertDurationsTo(TimeUnit durationUnit) { + this.durationUnit = durationUnit; + return this; + } + + /** + * Only report metrics which match the given filter. + * + * @param filter a {@link MetricFilter} + * @return {@code this} + */ + public Builder filter(MetricFilter filter) { + this.filter = filter; + return this; + } + + /** + * Builds a {@link ConsoleReporter} with the given properties. + * + * @return a {@link ConsoleReporter} + */ + public TestReporter build() { + return new TestReporter(registry, + // output, + "name", + // locale, + // clock, + // timeZone, + this.filter, + rateUnit, + durationUnit + ); + } + } + + +} + diff --git a/micro-metrics/src/test/java/app/metrics/com/oath/micro/server/TimedResource.java b/micro-metrics/src/test/java/app/metrics/com/oath/micro/server/TimedResource.java new file mode 100644 index 000000000..50626f343 --- /dev/null +++ b/micro-metrics/src/test/java/app/metrics/com/oath/micro/server/TimedResource.java @@ -0,0 +1,16 @@ +package app.metrics.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +import com.codahale.metrics.annotation.Timed; + +@Component +public class TimedResource { + + + @Timed + public String times(){ + + return "ok!"; + } +} diff --git a/micro-metrics/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-metrics/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-metrics/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-metrics/src/test/java/com/oath/micro/server/spring/metrics/InstantGaugeTest.java b/micro-metrics/src/test/java/com/oath/micro/server/spring/metrics/InstantGaugeTest.java new file mode 100644 index 000000000..57246a0ba --- /dev/null +++ b/micro-metrics/src/test/java/com/oath/micro/server/spring/metrics/InstantGaugeTest.java @@ -0,0 +1,19 @@ +package com.oath.micro.server.spring.metrics; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class InstantGaugeTest { + + @Test + public void instantGauge() { + InstantGauge gauge = new InstantGauge(); + gauge.increment(); + gauge.increase(3); + + assertEquals(4l ,gauge.getValue().longValue()); + assertEquals(0l ,gauge.getValue().longValue()); + + } + +} diff --git a/micro-metrics/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-metrics/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-metrics/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-mysql/README.md b/micro-mysql/README.md new file mode 100644 index 000000000..3cffffb7f --- /dev/null +++ b/micro-mysql/README.md @@ -0,0 +1,22 @@ +# Distributed lock plugin for MySQL + +Allows MySQL to be used to create distributed locks. Not suitable for use against a MySQL cluster prior to version . + +Autowire com.aol.micro.server.utility.DistributedLockService into your beans to make use of Distributed locking. If you also have the couchbase plugin installed autowire com.aol.micro.server.mysql.distlock.DistributedLockServiceMySqlImpl instead. + +## Getting The Microserver MySql Plugin + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-mysql/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-mysql) + +### Maven +```xml + + com.oath.microservices + micro-mysql + x.yz + +``` +### Gradle +```groovy + compile 'com.oath.microservices:micro-mysql:x.yz' +``` diff --git a/micro-mysql/build.gradle b/micro-mysql/build.gradle index f679e6da6..9a8d8c5d2 100644 --- a/micro-mysql/build.gradle +++ b/micro-mysql/build.gradle @@ -1,59 +1,59 @@ description = 'micro-mysql' + dependencies { - compile group: 'org.springframework', name: 'spring-jdbc', version:"${springVersion}" - compile 'com.zaxxer:HikariCP:'+hikariCPVersion - compile project(':micro-core') - testCompile project(':micro-grizzly-with-jersey') - testCompile group: 'org.hsqldb', name:'hsqldb', version:'2.0.0' - + compile group: 'org.springframework', name: 'spring-jdbc', version: "${springVersion}" + compile 'com.zaxxer:HikariCP:' + hikariCPVersion + compile project(':micro-dist-lock') + testCompile project(':micro-grizzly-with-jersey') + testCompile group: 'org.hsqldb', name: 'hsqldb', version: '2.0.0' + } modifyPom { - project { - name 'Microserver mysql' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-mysql' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'Arkadiusz-Gasior' - name 'Arkadiusz Gasior' - email 'arkadiusz.gasior@teamaol.com' - } - } - - } + project { + name 'Microserver mysql' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-mysql' + version "$version" + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'Arkadiusz-Gasior' + name 'Arkadiusz Gasior' + email 'arkadiusz.gasior@teamaol.com' + } + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-mysql/readme.md b/micro-mysql/readme.md deleted file mode 100644 index 7edc0e6ca..000000000 --- a/micro-mysql/readme.md +++ /dev/null @@ -1,22 +0,0 @@ -# Distributed lock plugin for MySQL - -Allows MySQL to be used to create distributed locks. Not suitable for use against a MySQL cluster prior to version . - -Autowire com.aol.micro.server.utility.DistributedLockService into your beans to make use of Distributed locking. If you also have the couchbase plugin installed autowire com.aol.micro.server.mysql.distlock.DistributedLockServiceMySqlImpl instead. - -## Getting The Microserver MySql Plugin - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-mysql/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-mysql) - -### Maven -```xml - - com.aol.microservices - micro-mysql - x.yz - -``` -### Gradle -```groovy - compile 'com.aol.microservices:micro-mysql:x.yz' -``` \ No newline at end of file diff --git a/micro-mysql/src/main/java/com/aol/micro/server/mysql/distlock/DistributedLockServiceMySqlImpl.java b/micro-mysql/src/main/java/com/aol/micro/server/mysql/distlock/DistributedLockServiceMySqlImpl.java deleted file mode 100644 index 7c8f399dc..000000000 --- a/micro-mysql/src/main/java/com/aol/micro/server/mysql/distlock/DistributedLockServiceMySqlImpl.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.aol.micro.server.mysql.distlock; - -import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.utility.DistributedLockService; - -@Component -public class DistributedLockServiceMySqlImpl implements DistributedLockService { - - static final String GET_LOCK_TEMPLATE = "select COALESCE(GET_LOCK(?, 0), 0)"; - static final String RELEASE_LOCK_TEMPLATE = "select COALESCE(RELEASE_LOCK(?), 0)"; - - volatile JdbcTemplate jdbcTemplate; - - @Autowired(required = false) - @Qualifier("distLockingDataSource") - public void setSmartDataSource(DataSource dataSource) { - if (dataSource != null) - this.jdbcTemplate = new JdbcTemplate(dataSource); - } - - @Override - public boolean tryLock(String key) { - return executeScalar(GET_LOCK_TEMPLATE, key, 1); - } - - @Override - public boolean tryReleaseLock(String key) { - return executeScalar(RELEASE_LOCK_TEMPLATE, key, 1); - } - - synchronized boolean executeScalar(String operation, String key, Integer expectedResult) { - - int result = jdbcTemplate.queryForObject(operation, new Object[]{key},Integer.class); - return result == expectedResult; - - } - - public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - -} diff --git a/micro-mysql/src/main/java/com/aol/micro/server/mysql/distlock/MySqlPlugin.java b/micro-mysql/src/main/java/com/aol/micro/server/mysql/distlock/MySqlPlugin.java deleted file mode 100644 index 5b7e4e745..000000000 --- a/micro-mysql/src/main/java/com/aol/micro/server/mysql/distlock/MySqlPlugin.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.aol.micro.server.mysql.distlock; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.mysql.distlock.datasource.JdbcConfigDistLock; -import com.aol.micro.server.mysql.distlock.datasource.MysqlDataSourceBuilder; - -public class MySqlPlugin implements Plugin { - public PSetX springClasses(){ - return PSetX.of(DistributedLockServiceMySqlImpl.class, - MysqlDataSourceBuilder.class,JdbcConfigDistLock.class); - } -} diff --git a/micro-mysql/src/main/java/com/oath/micro/server/mysql/distlock/DistributedLockServiceMySqlImpl.java b/micro-mysql/src/main/java/com/oath/micro/server/mysql/distlock/DistributedLockServiceMySqlImpl.java new file mode 100644 index 000000000..ee810ecbb --- /dev/null +++ b/micro-mysql/src/main/java/com/oath/micro/server/mysql/distlock/DistributedLockServiceMySqlImpl.java @@ -0,0 +1,49 @@ +package com.oath.micro.server.mysql.distlock; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.dist.lock.DistributedLockService; + +@Component +public class DistributedLockServiceMySqlImpl implements DistributedLockService { + + static final String GET_LOCK_TEMPLATE = "select COALESCE(GET_LOCK(?, 0), 0)"; + static final String RELEASE_LOCK_TEMPLATE = "select COALESCE(RELEASE_LOCK(?), 0)"; + + volatile JdbcTemplate jdbcTemplate; + + @Autowired(required = false) + @Qualifier("distLockingDataSource") + public void setSmartDataSource(DataSource dataSource) { + if (dataSource != null) + this.jdbcTemplate = new JdbcTemplate( + dataSource); + } + + @Override + public boolean tryLock(String key) { + return executeScalar(GET_LOCK_TEMPLATE, key, 1); + } + + @Override + public boolean tryReleaseLock(String key) { + return executeScalar(RELEASE_LOCK_TEMPLATE, key, 1); + } + + synchronized boolean executeScalar(String operation, String key, Integer expectedResult) { + + int result = jdbcTemplate.queryForObject(operation, new Object[] { key }, Integer.class); + return result == expectedResult; + + } + + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + +} diff --git a/micro-mysql/src/main/java/com/oath/micro/server/mysql/distlock/MySqlPlugin.java b/micro-mysql/src/main/java/com/oath/micro/server/mysql/distlock/MySqlPlugin.java new file mode 100644 index 000000000..3f2231f12 --- /dev/null +++ b/micro-mysql/src/main/java/com/oath/micro/server/mysql/distlock/MySqlPlugin.java @@ -0,0 +1,16 @@ +package com.oath.micro.server.mysql.distlock; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.mysql.distlock.datasource.JdbcConfigDistLock; +import com.oath.micro.server.mysql.distlock.datasource.MysqlDataSourceBuilder; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +public class MySqlPlugin implements Plugin { + public Set springClasses(){ + return SetX.of(DistributedLockServiceMySqlImpl.class, + MysqlDataSourceBuilder.class,JdbcConfigDistLock.class); + } +} diff --git a/micro-mysql/src/main/java/com/aol/micro/server/mysql/distlock/datasource/JdbcConfigDistLock.java b/micro-mysql/src/main/java/com/oath/micro/server/mysql/distlock/datasource/JdbcConfigDistLock.java similarity index 96% rename from micro-mysql/src/main/java/com/aol/micro/server/mysql/distlock/datasource/JdbcConfigDistLock.java rename to micro-mysql/src/main/java/com/oath/micro/server/mysql/distlock/datasource/JdbcConfigDistLock.java index 1d9de18e4..93e926b66 100644 --- a/micro-mysql/src/main/java/com/aol/micro/server/mysql/distlock/datasource/JdbcConfigDistLock.java +++ b/micro-mysql/src/main/java/com/oath/micro/server/mysql/distlock/datasource/JdbcConfigDistLock.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.mysql.distlock.datasource; +package com.oath.micro.server.mysql.distlock.datasource; import java.util.Properties; diff --git a/micro-mysql/src/main/java/com/aol/micro/server/mysql/distlock/datasource/MysqlDataSourceBuilder.java b/micro-mysql/src/main/java/com/oath/micro/server/mysql/distlock/datasource/MysqlDataSourceBuilder.java similarity index 94% rename from micro-mysql/src/main/java/com/aol/micro/server/mysql/distlock/datasource/MysqlDataSourceBuilder.java rename to micro-mysql/src/main/java/com/oath/micro/server/mysql/distlock/datasource/MysqlDataSourceBuilder.java index 39fa05f24..47890f896 100644 --- a/micro-mysql/src/main/java/com/aol/micro/server/mysql/distlock/datasource/MysqlDataSourceBuilder.java +++ b/micro-mysql/src/main/java/com/oath/micro/server/mysql/distlock/datasource/MysqlDataSourceBuilder.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.mysql.distlock.datasource; +package com.oath.micro.server.mysql.distlock.datasource; import javax.annotation.Resource; import javax.sql.DataSource; diff --git a/micro-mysql/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-mysql/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index d7e909829..000000000 --- a/micro-mysql/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.mysql.distlock.MySqlPlugin \ No newline at end of file diff --git a/micro-mysql/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-mysql/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..456a38736 --- /dev/null +++ b/micro-mysql/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.mysql.distlock.MySqlPlugin \ No newline at end of file diff --git a/micro-mysql/src/test/java/app/single/com/aol/micro/server/SimpleClassTest.java b/micro-mysql/src/test/java/app/single/com/aol/micro/server/SimpleClassTest.java deleted file mode 100644 index 27ac50359..000000000 --- a/micro-mysql/src/test/java/app/single/com/aol/micro/server/SimpleClassTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package app.single.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.mysql.distlock.DistributedLockServiceMySqlImpl; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", - "db.connection.url","jdbc:hsqldb:mem:aname", - "db.connection.username", "sa", - "db.connection.password", "", - "db.connection.dialect","org.hibernate.dialect.HSQLDialect", - "db.connection.ddl.auto","create-drop" }) -public class SimpleClassTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("true")); - - } - - - - -} \ No newline at end of file diff --git a/micro-mysql/src/test/java/app/single/com/aol/micro/server/SimpleStatusResource.java b/micro-mysql/src/test/java/app/single/com/aol/micro/server/SimpleStatusResource.java deleted file mode 100644 index 09ec9b576..000000000 --- a/micro-mysql/src/test/java/app/single/com/aol/micro/server/SimpleStatusResource.java +++ /dev/null @@ -1,36 +0,0 @@ -package app.single.com.aol.micro.server; - -import java.io.InputStream; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; -import org.glassfish.jersey.media.multipart.FormDataParam; -import org.springframework.beans.factory.annotation.Autowired; - -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.mysql.distlock.DistributedLockServiceMySqlImpl; - -@Rest -@Path("/status") -public class SimpleStatusResource { - @Autowired - DistributedLockServiceMySqlImpl lock; - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return ""+ (lock!=null); - } - - -} \ No newline at end of file diff --git a/micro-mysql/src/test/java/app/single/com/oath/micro/server/SimpleClassTest.java b/micro-mysql/src/test/java/app/single/com/oath/micro/server/SimpleClassTest.java new file mode 100644 index 000000000..59268f26f --- /dev/null +++ b/micro-mysql/src/test/java/app/single/com/oath/micro/server/SimpleClassTest.java @@ -0,0 +1,52 @@ +package app.single.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", + "db.connection.url","jdbc:hsqldb:mem:aname", + "db.connection.username", "sa", + "db.connection.password", "", + "db.connection.dialect","org.hibernate.dialect.HSQLDialect", + "db.connection.ddl.auto","create-drop" }) +public class SimpleClassTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer(){ + + server = new MicroserverApp(()-> "simple-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("true")); + + } + + + + +} \ No newline at end of file diff --git a/micro-mysql/src/test/java/app/single/com/oath/micro/server/SimpleStatusResource.java b/micro-mysql/src/test/java/app/single/com/oath/micro/server/SimpleStatusResource.java new file mode 100644 index 000000000..d69d7c4a8 --- /dev/null +++ b/micro-mysql/src/test/java/app/single/com/oath/micro/server/SimpleStatusResource.java @@ -0,0 +1,29 @@ +package app.single.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.mysql.distlock.DistributedLockServiceMySqlImpl; + +@Rest +@Path("/status") +public class SimpleStatusResource { + @Autowired + DistributedLockServiceMySqlImpl lock; + + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + return ""+ (lock!=null); + } + + +} \ No newline at end of file diff --git a/micro-mysql/src/test/java/com/aol/micro/server/mysql/distlock/DistributedLockServiceConfigurationTest.groovy b/micro-mysql/src/test/java/com/aol/micro/server/mysql/distlock/DistributedLockServiceConfigurationTest.groovy deleted file mode 100644 index 00af1f50d..000000000 --- a/micro-mysql/src/test/java/com/aol/micro/server/mysql/distlock/DistributedLockServiceConfigurationTest.groovy +++ /dev/null @@ -1,26 +0,0 @@ -package com.aol.micro.server.mysql.distlock - -import static org.hamcrest.CoreMatchers.is -import static org.junit.Assert.assertThat - -import org.junit.Test - -class DistributedLockServiceConfigurationTest { - - - private DistributedLockServiceConfiguration configuration = new DistributedLockServiceConfiguration() - - @Test - public void "test couchbase"() { - configuration.distributedLockToUse = "couchbase" - configuration.keyTimeoutInSeconds = 100 - assertThat(configuration.distributedLockService() instanceof DistributedLockServiceCouchbaseImpl, is(true)); - } - - @Test - public void "test mysql"() { - configuration.distributedLockToUse = "mysql" - configuration.keyTimeoutInSeconds = 100 - assertThat(configuration.distributedLockService() instanceof DistributedLockServiceMySqlImpl, is(true)); - } -} diff --git a/micro-mysql/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-mysql/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-mysql/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-mysql/src/test/java/com/aol/micro/server/mysql/distlock/DistributedLockServiceMySqlImplTest.java b/micro-mysql/src/test/java/com/oath/micro/server/mysql/distlock/DistributedLockServiceMySqlImplTest.java similarity index 98% rename from micro-mysql/src/test/java/com/aol/micro/server/mysql/distlock/DistributedLockServiceMySqlImplTest.java rename to micro-mysql/src/test/java/com/oath/micro/server/mysql/distlock/DistributedLockServiceMySqlImplTest.java index e86911cd9..62bc30a88 100644 --- a/micro-mysql/src/test/java/com/aol/micro/server/mysql/distlock/DistributedLockServiceMySqlImplTest.java +++ b/micro-mysql/src/test/java/com/oath/micro/server/mysql/distlock/DistributedLockServiceMySqlImplTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.mysql.distlock; +package com.oath.micro.server.mysql.distlock; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; diff --git a/micro-mysql/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-mysql/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-mysql/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-reactive/README.md b/micro-reactive/README.md new file mode 100644 index 000000000..27ac138ee --- /dev/null +++ b/micro-reactive/README.md @@ -0,0 +1,160 @@ +# Reactive plugin for Microserver + +[micro-reactive example apps](https://github.com/aol/micro-server/tree/master/micro-reactive/src/test/java/app) + +The micro-reactive plugin integrates [cyclops-react](https://github.com/aol/cyclops-react) and [Pivotal Reactor](http://projectreactor.io/) to provide a very rich integrated reactive programming environment on top of Spring. + +*NB* Microserver's Jersey plugin already makes Publisher a valid return type, converts them to asynchronously executing REST End points + +Why? + +cyclops-react offers a range of functional datatypes and datastructures, many of which act as reactive-streams Publishers /subscribers. Pivotal Reactor offer advanced / specialized processing capabilities for reactive-streams Publishers and subscribers. + +Features include + +* Inter-Microservice Streaming [v0.87 and above] +* EventQueueManager - a powerful event bus +* Enhanced for-comprehension syntax specifically for micro-reactive +* Ability to treat Flux and Mono as cyclops monads +* Job schedular - runs jobs as scheduled jobs and integrates with micro-events +* CyclopsReactor a conversion layer between cyclops-react and Reactor datatypes + +## Examples + +### Streaming across Microservices + +To publish an infinite Stream of Boo! we could create Rest end points like those below + +```java +@GET +@Produces("application/json") +@Path("/infinite-boo") +public Response boo() { + return ReactiveResponse.publishAsJson(ReactiveSeq.generate(() -> "boo!")); + +} +@GET +@Produces("application/json") +@Path("/infinite-boo-jdk") +public Response booJDK() { + return ReactiveResponse.streamAsJson(Stream.generate(() -> "boo!")); + +} + +``` + +To Stream in output from our infinetely Streaming Rest end points we can write + +```java + +new ReactiveRequest(1000, 1000).getJsonStream("http://localhost:8080/simple-app/single/infinite-boo",String.class) + .forEach(System.err::println); +``` + +Which will write each Boo! recieved from our end point to the console. + +## Event bus - + +Strongly typed event bus backed by Agrona wait free or JDK blocking / non-blocking queues. + +```java +bus.forEach("hello",this::eventReciever); +bus.push("hello", "world"); + +bus.stream("bus-2") + .futureOperations(Executor.newFixedThreadExecutor(1)) + .map(this::transform) + .forEach(this::process); + +bus.push("bus-2", myData1); +bus.push("bus-2", myData2); + + +``` + + +## For comprehensions + + ```java +ListX> list = For.Publishers.each(Flux.range(1,10), + i-> ReactiveSeq.iterate(i,a->a+1), + Tuple::tuple) + .to(ListX::fromIterable); + + ``` + +## Job Schedular + + ```java +schedular.schedule("* * * * * ?", myJob) + .connect() + .debounce(1,TimeUnit.DAYS) + .forEach(this::logStats) + ``` + +## Reactor monads + + AnyMSeq wraps any sequential monad, allowing standard interfaces across Streams, Lists etc + + ```java + AnyMSeq flux = CyclopsReactor.from(Flux.just("hello","world","c")); + ``` + +## Conversions + + From a Flux to a LazyFutureStream + + ```java +CyclopsReactor.fromFlux(Flux.just(1,2,3)) + .toFutureStream(new LazyReact(100,100)) + .map(this::parallelIO) + .run(); + +``` + + From a Flux to a ListX + + ```java +ListX.fromPublisher(Flux.just(1,2,3)); + ``` + + From a Flux to a ListX 2 + +```java +Flux.just(1,2,3).collect(ListX::empty,(l,e)->l.add(e)); + ``` + + From a Flux to a LinkedListX + + ```java +LinkedListX.fromPublisher(Flux.just(1,2,3)); + ``` + + From a Flux to a LinkedListX + + ```java +Flux.just(1,2,3) + .map(LinkedListX::of) + .reduce(Reducers.toLinkedListX()); + ``` + +## To use + + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-reactive/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-reactive) + +Simply add to the classpath + +Maven + ```xml + + com.oath.microservices + micro-reactive + x.yz + + ``` +Gradle + ```groovy + compile 'com.oath.microservices:micro-reactive:x.yz' + ``` + diff --git a/micro-reactive/build.gradle b/micro-reactive/build.gradle index 40803f323..52893f3e4 100644 --- a/micro-reactive/build.gradle +++ b/micro-reactive/build.gradle @@ -1,61 +1,61 @@ description = 'micro-reactive' + dependencies { - - - compile 'com.aol.cyclops:cyclops-reactor:'+cyclopsVersion - compile project(':micro-core') - compile project(':micro-events') - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') - testCompile project(':micro-jackson-configuration') + compile project(':micro-core') + compile project(':micro-client') + compile project(':micro-events') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') + testCompile project(':micro-jackson-configuration') + testCompile "com.oath.cyclops:cyclops-futurestream:$cyclopsVersion" } modifyPom { - project { - name 'Microserver reactive' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-reactive' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - } - - } + project { + name 'Microserver reactive' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-reactive' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-reactive/readme.md b/micro-reactive/readme.md deleted file mode 100644 index a68c6fccc..000000000 --- a/micro-reactive/readme.md +++ /dev/null @@ -1,125 +0,0 @@ -# Reactive plugin for Microserver - -[micro-reactive example apps](https://github.com/aol/micro-server/tree/master/micro-reactive/src/test/java/app) - -The micro-reactive plugin integrates [cyclops-react](https://github.com/aol/cyclops-react) and [Pivotal Reactor](http://projectreactor.io/) to provide a very rich integrated reactive programming environment on top of Spring. - -Why? - -cyclops-react offers a range of functional datatypes and datastructures, many of which act as reactive-streams Publishers /subscribers. Pivotal Reactor offer advanced / specialized processing capabilities for reactive-streams Publishers and subscribers. - -Features include - -* EventQueueManager - a powerful event bus -* Enhanced for-comprehension syntax specifically for micro-reactive -* Ability to treat Flux and Mono as cyclops monads -* Job schedular - runs jobs as scheduled jobs and integrates with micro-events -* CyclopsReactor a conversion layer between cyclops-react and Reactor datatypes - -## Examples - -## Event bus - - -Strongly typed event bus backed by Agrona wait free or JDK blocking / non-blocking queues. - -```java -bus.forEach("hello",this::eventReciever); -bus.push("hello", "world"); - -bus.stream("bus-2") - .futureOperations(Executor.newFixedThreadExecutor(1)) - .map(this::transform) - .forEach(this::process); - -bus.push("bus-2", myData1); -bus.push("bus-2", myData2); - - -``` - - -## For comprehensions - - ```java -ListX> list = For.Publishers.each(Flux.range(1,10), - i-> ReactiveSeq.iterate(i,a->a+1), - Tuple::tuple) - .toListX(); - - ``` - -## Job Schedular - - ```java -schedular.schedule("* * * * * ?", myJob) - .connect() - .debounce(1,TimeUnit.DAYS) - .forEach(this::logStats) - ``` - - ## Reactor monads - - AnyMSeq wraps any sequential monad, allowing standard interfaces across Streams, Lists etc - - ```java - AnyMSeq flux = CyclopsReactor.from(Flux.just("hello","world","c")); - ``` - - ## Conversions - - From a Flux to a LazyFutureStream - - ```java -CyclopsReactor.fromFlux(Flux.just(1,2,3)) - .toFutureStream(new LazyReact(100,100)) - .map(this::parallelIO) - .run(); - -``` - - From a Flux to a ListX - - ```java -ListX.fromPublisher(Flux.just(1,2,3)); - ``` - - From a Flux to a ListX 2 - -```java -Flux.just(1,2,3).collect(ListX::empty,(l,e)->l.add(e)); - ``` - - From a Flux to a PStackX - - ```java -PStackX.fromPublisher(Flux.just(1,2,3)); - ``` - - From a Flux to a PStackX - - ```java -Flux.just(1,2,3) - .map(PStackX::of) - .reduce(Reducers.toPStackX()); - ``` - -## To use - - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-reactive/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-reactive) - -Simply add to the classpath - -Maven - ```xml - - com.aol.microservices - micro-reactive - x.yz - - ``` -Gradle - ```groovy - compile 'com.aol.microservices:micro-reactive:x.yz' - ``` - diff --git a/micro-reactive/src/main/java/com/aol/micro/server/reactive/CyclopsReactor.java b/micro-reactive/src/main/java/com/aol/micro/server/reactive/CyclopsReactor.java deleted file mode 100644 index 53fbecfce..000000000 --- a/micro-reactive/src/main/java/com/aol/micro/server/reactive/CyclopsReactor.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.aol.micro.server.reactive; - -import org.reactivestreams.Publisher; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import com.aol.cyclops.control.AnyM; -import com.aol.cyclops.control.FutureW; -import com.aol.cyclops.control.LazyReact; -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.types.anyM.AnyMSeq; -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.cyclops.types.stream.reactive.SeqSubscriber; -import com.aol.cyclops.types.stream.reactive.ValueSubscriber; - -/** - * Type conversion tier for cyclops-react and Reactor. - * Note both cyclops-react and Reactor data types can generally be constructed from another - * reactive-streams publisher. - * e.g. - *
- * {@code 
- *  ListX.fromPublisher(Flux.just(1,2,3));
- *  Flux.from(SetX.of(1,2,3));
- * }
- * - * - * @author johnmcclean - * - */ -public interface CyclopsReactor { - - static AnyMSeq from(Publisher t){ - return (AnyMSeq)AnyM.ofSeq(Flux.from(t)); - } - - static SeqSubscriber fromFlux(Flux flux){ - SeqSubscriber seqSubscriber = SeqSubscriber.subscriber(); - flux.subscribe(seqSubscriber); - return seqSubscriber; - } - static ValueSubscriber fromMono(Mono mono){ - - ValueSubscriber valueSubscriber = ValueSubscriber.subscriber(); - mono.subscribe(valueSubscriber); - return valueSubscriber; - } - static ReactiveSeq reactiveSeq(Flux flux){ - return fromFlux(flux) - .stream(); - } - static LazyFutureStream futureStream(Flux flux, LazyReact lazyReact){ - return fromFlux(flux) - .toFutureStream(lazyReact); - } - - static FutureW futureW(Mono mono){ - return FutureW.of(mono.toCompletableFuture()); - } - - -} diff --git a/micro-reactive/src/main/java/com/aol/micro/server/reactive/EventQueueManager.java b/micro-reactive/src/main/java/com/aol/micro/server/reactive/EventQueueManager.java deleted file mode 100644 index ac18e87f0..000000000 --- a/micro-reactive/src/main/java/com/aol/micro/server/reactive/EventQueueManager.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.aol.micro.server.reactive; - -import java.util.concurrent.Executor; -import java.util.function.Consumer; -import java.util.function.Supplier; - -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import com.aol.cyclops.control.Eval; -import com.aol.cyclops.control.FluentFunctions; -import com.aol.cyclops.control.FutureW; -import com.aol.cyclops.control.LazyReact; -import com.aol.cyclops.control.Maybe; -import com.aol.cyclops.control.Pipes; -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.data.async.QueueFactory; -import com.aol.cyclops.types.futurestream.LazyFutureStream; - -/** - * Class for pusing information across threads to various consumers. - * Push data onto a queue on one thread for a Stream or Consumer on another to react to. - * - * @author johnmcclean - * - * @param - */ -@AllArgsConstructor(access=AccessLevel.PRIVATE) -public class EventQueueManager { - public final static Supplier io = FluentFunctions.of(()->new LazyReact(100,100)) - .memoize(); - public static EventQueueManager of(Executor ex, QueueFactory factory){ - return new EventQueueManager<>(ex,factory); - } - private final Pipes pipes = Pipes.of(); - private final Executor ex; - private final QueueFactory factory; - - /** - * Push data onto the named queue. - * - * @param key Queue name - * @param value Data to push - */ - public void push(String key, T value){ - pipes.push(key,value); - } - /** - * React to any data pushed onto the named Queue with the supplied consumer. - * - * @param key Queu name - * @param reactor Consumer to react to new data - */ - public void forEach(String key,Consumer reactor){ - if(!pipes.get(key).isPresent()) - pipes.register(key, factory.build()); - pipes.reactiveSeq(key) - .get() - .futureOperations(ex) - .forEach(reactor); - } - /** - * @param key Register a new queue with supplied key - */ - public void register(String key){ - pipes.register(key, factory.build()); - } - /** - * Asynchronously extract a single data point from the named Queue. - * - * - * @param key Queue name - * @param ex Executor to run on - * @return FutureW that will eventually have data from the Queue - */ - public FutureW future(String key,Executor ex){ - return pipes.oneOrErrorAsync(key, ex); - } - /** - * Asynchronously extract a single data point from the named Queue. - * - * - * @param key Queue name - * @param ex Executor to run on - * @return Mono that will eventually have data from the Queue - */ - public Mono mono(String key,Executor ex){ - return Mono.fromCompletableFuture(pipes.oneOrErrorAsync(key, ex) - .getFuture()); - } - - /** - * Generate a Reactor Stream (Flux) from the supplied Queue name. - * Any data pushed to the Queue will pass on to the returned Flux. - * - * @param key Queue name - * @return Flux which will recieve data from the Queue - */ - public Flux flux(String key){ - if(!pipes.get(key).isPresent()) - pipes.register(key, factory.build()); - return Flux.from(pipes.reactiveSeq(key) - .get()); - } - /** - * Generate a cyclops-react Stream (ReactiveSeq) from the supplied Queue name. - * Any data pushed to the Queue will pass on to the returned ReactiveSeq. - * - * @param key Queue name - * @return ReactiveSeq which will recieve data from the Queue - */ - public ReactiveSeq stream(String key){ - if(!pipes.get(key).isPresent()) - pipes.register(key, factory.build()); - return pipes.reactiveSeq(key) - .get(); - } - /** - * Lazily extract a single value from the named Queue. - * Maybe will be none if the Queue is closed, otherwise will retrieve the next value. - * - * @param key Queue name - * @return Maybe with next data point - */ - public Maybe maybe(String key){ - if(!pipes.get(key).isPresent()) - pipes.register(key, factory.build()); - return pipes.oneValue(key); - } - /** - * Lazily extract a single value from the named Queue. - * Eval will be contain null if the Queue is closed, otherwise will retrieve the next value. - * - * @param key Queue name - * @return Eval with next data point with next data point - */ - public Eval lazy(String key){ - if(!pipes.get(key).isPresent()) - pipes.register(key, factory.build()); - return pipes.nextOrNull(key); - } - /** - * Generate a Stream of Futures from the supplied key name - * - * @param key Queue name - * @return Stream of futures - */ - public LazyFutureStream ioFutureStream(String key){ - if(!pipes.get(key).isPresent()) - pipes.register(key, factory.build()); - return pipes.futureStream(key, io.get()) - .get(); - } - - -} \ No newline at end of file diff --git a/micro-reactive/src/main/java/com/aol/micro/server/reactive/JobSchedular.java b/micro-reactive/src/main/java/com/aol/micro/server/reactive/JobSchedular.java deleted file mode 100644 index 3b2013e1d..000000000 --- a/micro-reactive/src/main/java/com/aol/micro/server/reactive/JobSchedular.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aol.micro.server.reactive; -import java.util.concurrent.ScheduledExecutorService; - -import lombok.AllArgsConstructor; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.types.stream.HotStream; -import com.aol.micro.server.events.ScheduledJob; -import com.aol.micro.server.events.SystemData; - -@AllArgsConstructor -public class JobSchedular { - - private final ScheduledExecutorService ex; - - public HotStream> schedule(String expression, ScheduledJob job){ - return ReactiveSeq.generate(()->"new job") - .>map(drop->job.scheduleAndLog()) - .schedule(expression,ex); - } - public HotStream> scheduleFixedDelay(long fixedDelay, ScheduledJob job){ - return ReactiveSeq.generate(()->"new job") - .>map(drop->job.scheduleAndLog()) - .scheduleFixedDelay(fixedDelay,ex); - } - - public HotStream> scheduleFixedRate(long fixedRate, ScheduledJob job){ - return ReactiveSeq.generate(()->"new job") - .>map(drop->job.scheduleAndLog()) - .scheduleFixedRate(fixedRate,ex); - } - -} \ No newline at end of file diff --git a/micro-reactive/src/main/java/com/aol/micro/server/reactive/ReactivePlugin.java b/micro-reactive/src/main/java/com/aol/micro/server/reactive/ReactivePlugin.java deleted file mode 100644 index 34c0bc056..000000000 --- a/micro-reactive/src/main/java/com/aol/micro/server/reactive/ReactivePlugin.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.aol.micro.server.reactive; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; - - -public class ReactivePlugin implements Plugin{ - - @Override - public PSetX springClasses() { - return PSetX.of(ResponderConfigurer.class); - } - - - -} diff --git a/micro-reactive/src/main/java/com/aol/micro/server/reactive/ResponderConfigurer.java b/micro-reactive/src/main/java/com/aol/micro/server/reactive/ResponderConfigurer.java deleted file mode 100644 index a36d750d7..000000000 --- a/micro-reactive/src/main/java/com/aol/micro/server/reactive/ResponderConfigurer.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.aol.micro.server.reactive; - -import java.util.concurrent.Executors; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.data.async.QueueFactories; -import com.aol.cyclops.data.async.QueueFactory; - -@Configuration -public class ResponderConfigurer { - - - @Value("${responder.threads:0}") - int threads; - - - @Autowired(required=false) - @Qualifier(value="responderQueueFactory") - private QueueFactory factory; - - - @Bean - public EventQueueManager responder(){ - if(threads==0) - threads= Runtime.getRuntime().availableProcessors(); - if(threads==-1) - threads=0; - if(factory==null) - factory = QueueFactories.unboundedQueue(); - - return EventQueueManager.of(Executors.newFixedThreadPool(threads),factory); - - } -} diff --git a/micro-reactive/src/main/java/com/oath/micro/server/reactive/JobSchedular.java b/micro-reactive/src/main/java/com/oath/micro/server/reactive/JobSchedular.java new file mode 100644 index 000000000..8953dfda5 --- /dev/null +++ b/micro-reactive/src/main/java/com/oath/micro/server/reactive/JobSchedular.java @@ -0,0 +1,34 @@ +package com.oath.micro.server.reactive; +import java.util.concurrent.ScheduledExecutorService; + +import com.oath.cyclops.types.stream.Connectable; +import cyclops.reactive.ReactiveSeq; +import lombok.AllArgsConstructor; + + +import com.oath.micro.server.events.ScheduledJob; +import com.oath.micro.server.events.SystemData; + +@AllArgsConstructor +public class JobSchedular { + + private final ScheduledExecutorService ex; + + public Connectable> schedule(String expression, ScheduledJob job){ + return ReactiveSeq.generate(()->"new job") + .>map(drop->job.scheduleAndLog()) + .schedule(expression,ex); + } + public Connectable> scheduleFixedDelay(long fixedDelay, ScheduledJob job){ + return ReactiveSeq.generate(()->"new job") + .>map(drop->job.scheduleAndLog()) + .scheduleFixedDelay(fixedDelay,ex); + } + + public Connectable> scheduleFixedRate(long fixedRate, ScheduledJob job){ + return ReactiveSeq.generate(()->"new job") + .>map(drop->job.scheduleAndLog()) + .scheduleFixedRate(fixedRate,ex); + } + +} diff --git a/micro-reactive/src/main/java/com/oath/micro/server/reactive/ReactivePlugin.java b/micro-reactive/src/main/java/com/oath/micro/server/reactive/ReactivePlugin.java new file mode 100644 index 000000000..a07ba59e4 --- /dev/null +++ b/micro-reactive/src/main/java/com/oath/micro/server/reactive/ReactivePlugin.java @@ -0,0 +1,12 @@ +package com.oath.micro.server.reactive; + + +import com.oath.micro.server.Plugin; + + +public class ReactivePlugin implements Plugin{ + + + + +} diff --git a/micro-reactive/src/main/java/com/oath/micro/server/reactive/rest/ReactiveRequest.java b/micro-reactive/src/main/java/com/oath/micro/server/reactive/rest/ReactiveRequest.java new file mode 100644 index 000000000..61aff51fc --- /dev/null +++ b/micro-reactive/src/main/java/com/oath/micro/server/reactive/rest/ReactiveRequest.java @@ -0,0 +1,193 @@ +package com.oath.micro.server.reactive.rest; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import cyclops.reactive.ReactiveSeq; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.ClientProperties; + + +import com.oath.micro.server.rest.jackson.JacksonFeature; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.fasterxml.jackson.databind.JavaType; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.SneakyThrows; +import lombok.experimental.Wither; + +@AllArgsConstructor +@Builder +@Wither +public class ReactiveRequest { + + private final Client client; + private final String contentType; + private final String accept; + private final String stringFormat; + + /** + * Create a new rest client. + * @param readTimeoutMillis Read timeout, in milliseconds + * @param connectTimeoutMillis Connect timeout, in milliseconds + */ + public ReactiveRequest(int readTimeoutMillis, int connectTimeoutMillis) { + + this.client = initClient(readTimeoutMillis, connectTimeoutMillis); + contentType = MediaType.APPLICATION_JSON; + accept = MediaType.APPLICATION_JSON; + stringFormat = "UTF-8"; + + } + + protected Client initClient(int rt, int ct) { + + ClientConfig clientConfig = new ClientConfig(); + clientConfig.property(ClientProperties.CONNECT_TIMEOUT, ct); + clientConfig.property(ClientProperties.READ_TIMEOUT, rt); + + ClientBuilder.newBuilder() + .register(JacksonFeature.class); + Client client = ClientBuilder.newClient(clientConfig); + + return client; + + } + + @SneakyThrows + public ReactiveSeq getTextStream(final String url) { + + final WebTarget webResource = client.target(url); + + InputStream s = webResource.request(MediaType.TEXT_PLAIN) + .accept(MediaType.TEXT_PLAIN) + .get(InputStream.class); + + BufferedReader reader = new BufferedReader( + new InputStreamReader( + s, this.stringFormat)); + return ReactiveSeq.fromStream(reader.lines()); + + } + + @SneakyThrows + public ReactiveSeq getStream(final String url) { + + final WebTarget webResource = client.target(url); + + InputStream s = webResource.request(accept) + .accept(accept) + .get(InputStream.class); + + BufferedReader reader = new BufferedReader( + new InputStreamReader( + s, this.stringFormat)); + return ReactiveSeq.fromStream(reader.lines()); + + } + + @SneakyThrows + public ReactiveSeq postStream(final String url, final V request) { + + final WebTarget webResource = client.target(url); + + InputStream s = webResource.request(accept) + .accept(accept) + .post(Entity.entity(request, contentType), InputStream.class); + + BufferedReader reader = new BufferedReader( + new InputStreamReader( + s, this.stringFormat)); + return ReactiveSeq.fromStream(reader.lines()); + + } + + @SneakyThrows + public ReactiveSeq putStream(final String url, final V request) { + + final WebTarget webResource = client.target(url); + + InputStream s = webResource.request(accept) + .accept(accept) + .put(Entity.entity(request, contentType), InputStream.class); + + BufferedReader reader = new BufferedReader( + new InputStreamReader( + s, this.stringFormat)); + return ReactiveSeq.fromStream(reader.lines()); + + } + + @SneakyThrows + public ReactiveSeq deleteStream(final String url, final V request) { + + final WebTarget webResource = client.target(url); + + InputStream s = webResource.request(accept) + .accept(accept) + .delete(InputStream.class); + + BufferedReader reader = new BufferedReader( + new InputStreamReader( + s, this.stringFormat)); + return ReactiveSeq.fromStream(reader.lines()); + + } + + public ReactiveSeq getJsonStream(final String url, Class type) { + + return getStream(url).map(jsonString -> JacksonUtil.convertFromJson(jsonString, type)); + + } + + public ReactiveSeq getJsonStream(final String url, JavaType type) { + + return getStream(url).map(jsonString -> JacksonUtil.convertFromJson(jsonString, type)); + + } + + public ReactiveSeq deleteJsonStream(final String url, Class type) { + + return getStream(url).map(jsonString -> JacksonUtil.convertFromJson(jsonString, type)); + + } + + public ReactiveSeq deleteJsonStream(final String url, JavaType type) { + + return getStream(url).map(jsonString -> JacksonUtil.convertFromJson(jsonString, type)); + + } + + public ReactiveSeq postJsonStream(final String url, final V request, Class type) { + + return postStream(url, request).map(jsonString -> JacksonUtil.convertFromJson(jsonString, type)); + + } + + public ReactiveSeq postJsonStream(final String url, final V request, JavaType type) { + + return postStream(url, request).map(jsonString -> JacksonUtil.convertFromJson(jsonString, type)); + + } + + public ReactiveSeq putJsonStream(final String url, final V request, Class type) { + + return putStream(url, request).map(jsonString -> JacksonUtil.convertFromJson(jsonString, type)); + + } + + public ReactiveSeq putJsonStream(final String url, final V request, JavaType type) { + + return putStream(url, request).map(jsonString -> JacksonUtil.convertFromJson(jsonString, type)); + + } + +} diff --git a/micro-reactive/src/main/java/com/oath/micro/server/reactive/rest/ReactiveResponse.java b/micro-reactive/src/main/java/com/oath/micro/server/reactive/rest/ReactiveResponse.java new file mode 100644 index 000000000..5dc3511c8 --- /dev/null +++ b/micro-reactive/src/main/java/com/oath/micro/server/reactive/rest/ReactiveResponse.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.reactive.rest; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.stream.Stream; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; + +import com.oath.cyclops.util.ExceptionSoftener; +import cyclops.reactive.ReactiveSeq; +import org.reactivestreams.Publisher; + + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class ReactiveResponse { + + public static Response streamAsJson(Stream json) { + return publishAsJson(ReactiveSeq.fromStream(json)); + } + + public static Response publishAsJson(Publisher json) { + + StreamingOutput stream = new StreamingOutput() { + @Override + public void write(OutputStream os) throws IOException, WebApplicationException { + Writer writer = new BufferedWriter( + new OutputStreamWriter( + os)); + + ReactiveSeq.fromPublisher(json) + .map(JacksonUtil::serializeToJson) + .forEach(ExceptionSoftener.softenConsumer(json -> { + + writer.write(json); + writer.write("\n"); + + }), e -> { + } , ExceptionSoftener.softenRunnable(() -> writer.flush())); + + writer.flush(); + } + }; + return Response.ok(stream) + .build(); + } + +} diff --git a/micro-reactive/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-reactive/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index aaf0778ee..000000000 --- a/micro-reactive/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.reactive.ReactivePlugin \ No newline at end of file diff --git a/micro-reactive/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-reactive/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..ac0e2a888 --- /dev/null +++ b/micro-reactive/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.reactive.ReactivePlugin \ No newline at end of file diff --git a/micro-reactive/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java b/micro-reactive/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java deleted file mode 100644 index 979b5fbf5..000000000 --- a/micro-reactive/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java +++ /dev/null @@ -1,57 +0,0 @@ -package app.async.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.io.IOException; -import java.util.Properties; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.spring.properties.PropertyFileConfig; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class AsyncAppRunner { - - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( ()-> "async-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - Thread.sleep(2000); - - assertThat(rest.get("http://localhost:8080/async-app/async/expensive"),is(";test!;test!;test!")); - - } - - @Test - public void loadProperties() throws IOException{ - - Properties props = new PropertyFileConfig(true).propertyFactory() ; - assertThat(props.getProperty("test"),is("hello world")); - } - - - -} \ No newline at end of file diff --git a/micro-reactive/src/test/java/app/async/com/aol/micro/server/AsyncResource.java b/micro-reactive/src/test/java/app/async/com/aol/micro/server/AsyncResource.java deleted file mode 100644 index c411ec484..000000000 --- a/micro-reactive/src/test/java/app/async/com/aol/micro/server/AsyncResource.java +++ /dev/null @@ -1,57 +0,0 @@ -package app.async.com.aol.micro.server; - -import java.util.Arrays; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.container.Suspended; - -import org.pcollections.ConsPStack; -import org.pcollections.PStack; -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.testing.RestAgent; - -@Path("/async") -@Component -public class AsyncResource implements RestResource{ - - private final SimpleReact simpleReact =new SimpleReact(); - private final PStack urls = ConsPStack.from(Arrays.asList("http://localhost:8080/async-app/async/ping2", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping")); - - private final RestAgent client = new RestAgent(); - - @GET - @Path("/expensive") - @Produces("text/plain") - public void expensive(@Suspended AsyncResponse asyncResponse){ - - LazyFutureStream.lazyFutureStreamFromIterable(urls) - .then(it->client.get(it)) - .onFail(it -> "") - .peek(it -> - System.out.println(it)) - .convertToSimpleReact() - .allOf(data -> { - System.out.println(data); - return asyncResponse.resume(ReactiveSeq.fromIterable(data).join(";")); }); - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - -} diff --git a/micro-reactive/src/test/java/app/async/com/aol/micro/server/Simple.java b/micro-reactive/src/test/java/app/async/com/aol/micro/server/Simple.java deleted file mode 100644 index edefa80ef..000000000 --- a/micro-reactive/src/test/java/app/async/com/aol/micro/server/Simple.java +++ /dev/null @@ -1,16 +0,0 @@ -package app.async.com.aol.micro.server; - -import java.io.IOException; -import java.util.Properties; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.spring.properties.PropertyFileConfig; - -public class Simple { - - public static void main(String[] args) throws IOException{ - - new MicroserverApp(()->"test-app").run(); - } -} diff --git a/micro-reactive/src/test/java/app/async/com/aol/micro/server/SimpleApp.java b/micro-reactive/src/test/java/app/async/com/aol/micro/server/SimpleApp.java deleted file mode 100644 index 919b7c6b0..000000000 --- a/micro-reactive/src/test/java/app/async/com/aol/micro/server/SimpleApp.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.async.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; - - - -@Rest -@Path("/test") -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()->"test-app").run(); - } - @GET - public String myEndPoint(){ - return "hello world!"; - } - - -} diff --git a/micro-reactive/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java b/micro-reactive/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java new file mode 100644 index 000000000..c71dd8184 --- /dev/null +++ b/micro-reactive/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java @@ -0,0 +1,57 @@ +package app.async.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.Properties; +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.spring.properties.PropertyFileConfig; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class AsyncAppRunner { + + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( ()-> "async-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + Thread.sleep(2000); + + assertThat(rest.get("http://localhost:8080/async-app/async/expensive"),is(";test!;test!;test!")); + + } + + @Test + public void loadProperties() throws IOException{ + + Properties props = new PropertyFileConfig(true).propertyFactory() ; + assertThat(props.getProperty("test"),is("hello world")); + } + + + +} \ No newline at end of file diff --git a/micro-reactive/src/test/java/app/async/com/oath/micro/server/AsyncResource.java b/micro-reactive/src/test/java/app/async/com/oath/micro/server/AsyncResource.java new file mode 100644 index 000000000..26d6df8be --- /dev/null +++ b/micro-reactive/src/test/java/app/async/com/oath/micro/server/AsyncResource.java @@ -0,0 +1,58 @@ +package app.async.com.oath.micro.server; + +import java.util.Arrays; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; + +import cyclops.futurestream.SimpleReact; +import cyclops.data.Seq; +import cyclops.futurestream.FutureStream; +import cyclops.reactive.ReactiveSeq; + +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.testing.RestAgent; + +@Path("/async") +@Component +public class AsyncResource implements RestResource{ + + private final SimpleReact simpleReact =new SimpleReact(); + private final Seq urls = Seq.fromIterable(Arrays.asList("http://localhost:8080/async-app/async/ping2", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping")); + + private final RestAgent client = new RestAgent(); + + @GET + @Path("/expensive") + @Produces("text/plain") + public void expensive(@Suspended AsyncResponse asyncResponse){ + + FutureStream.builder().fromIterable(urls) + .then(it->client.get(it)) + .onFail(it -> "") + .peek(it -> + System.out.println(it)) + .convertToSimpleReact() + .allOf(data -> { + System.out.println(data); + return asyncResponse.resume(ReactiveSeq.fromIterable(data).join(";")); }); + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "test!"; + } + + +} diff --git a/micro-reactive/src/test/java/app/async/com/oath/micro/server/Simple.java b/micro-reactive/src/test/java/app/async/com/oath/micro/server/Simple.java new file mode 100644 index 000000000..3eb3e7504 --- /dev/null +++ b/micro-reactive/src/test/java/app/async/com/oath/micro/server/Simple.java @@ -0,0 +1,13 @@ +package app.async.com.oath.micro.server; + +import java.io.IOException; + +import com.oath.micro.server.MicroserverApp; + +public class Simple { + + public static void main(String[] args) throws IOException{ + + new MicroserverApp(()->"test-app").run(); + } +} diff --git a/micro-reactive/src/test/java/app/async/com/oath/micro/server/SimpleApp.java b/micro-reactive/src/test/java/app/async/com/oath/micro/server/SimpleApp.java new file mode 100644 index 000000000..916d0330e --- /dev/null +++ b/micro-reactive/src/test/java/app/async/com/oath/micro/server/SimpleApp.java @@ -0,0 +1,24 @@ +package app.async.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; + + + +@Rest +@Path("/test") +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()->"test-app").run(); + } + @GET + public String myEndPoint(){ + return "hello world!"; + } + + +} diff --git a/micro-reactive/src/test/java/app/bus/com/aol/micro/server/MyQueueFactoryConfig.java b/micro-reactive/src/test/java/app/bus/com/aol/micro/server/MyQueueFactoryConfig.java index 01bfdd9f9..4679d7564 100644 --- a/micro-reactive/src/test/java/app/bus/com/aol/micro/server/MyQueueFactoryConfig.java +++ b/micro-reactive/src/test/java/app/bus/com/aol/micro/server/MyQueueFactoryConfig.java @@ -1,10 +1,12 @@ package app.bus.com.aol.micro.server; +import com.oath.cyclops.async.QueueFactories; +import com.oath.cyclops.async.adapters.QueueFactory; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import com.aol.cyclops.data.async.QueueFactories; -import com.aol.cyclops.data.async.QueueFactory; + @Configuration public class MyQueueFactoryConfig { diff --git a/micro-reactive/src/test/java/app/bus/com/aol/micro/server/SingleClassTest.java b/micro-reactive/src/test/java/app/bus/com/aol/micro/server/SingleClassTest.java index 43ea049e0..6f25c6a29 100644 --- a/micro-reactive/src/test/java/app/bus/com/aol/micro/server/SingleClassTest.java +++ b/micro-reactive/src/test/java/app/bus/com/aol/micro/server/SingleClassTest.java @@ -1,11 +1,10 @@ package app.bus.com.aol.micro.server; -import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import java.util.concurrent.ExecutionException; -import javax.annotation.PostConstruct; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; @@ -13,62 +12,53 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.reactive.EventQueueManager; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; @Microserver @Path("/single") -public class SingleClassTest implements RestResource{ - - RestAgent rest = new RestAgent(); - - @Autowired - EventQueueManager manager; - MicroserverApp server; - - static String lastRecieved = null; - - @Before - public void startServer(){ - lastRecieved = null; - server = new MicroserverApp( SingleClassTest.class, ()-> "simple-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @PostConstruct - public void busManager(){ - manager.forEach("ping",in->lastRecieved=in); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/single/ping"),is("ok")); - - assertThat(lastRecieved,equalTo("input")); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - manager.push("ping", "input"); - return "ok"; - } - - +public class SingleClassTest implements RestResource { + + RestAgent rest = new RestAgent(); + + + MicroserverApp server; + + + @Before + public void startServer() { + + server = new MicroserverApp( + SingleClassTest.class, () -> "simple-app"); + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + assertThat(rest.get("http://localhost:8080/simple-app/single/ping"), is("ok")); + Thread.sleep(500); + + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + return "ok"; + } + } \ No newline at end of file diff --git a/micro-reactive/src/test/java/app/streaming/com/aol/micro/server/MyQueueFactoryConfig.java b/micro-reactive/src/test/java/app/streaming/com/aol/micro/server/MyQueueFactoryConfig.java new file mode 100644 index 000000000..8980b2e95 --- /dev/null +++ b/micro-reactive/src/test/java/app/streaming/com/aol/micro/server/MyQueueFactoryConfig.java @@ -0,0 +1,18 @@ +package app.streaming.com.aol.micro.server; + +import com.oath.cyclops.async.QueueFactories; +import com.oath.cyclops.async.adapters.QueueFactory; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +@Configuration +public class MyQueueFactoryConfig { + + + @Bean + public QueueFactory responderQueueFactory(){ + return QueueFactories.boundedNonBlockingQueue(1000); + } +} diff --git a/micro-reactive/src/test/java/app/streaming/com/aol/micro/server/SingleClassTest.java b/micro-reactive/src/test/java/app/streaming/com/aol/micro/server/SingleClassTest.java new file mode 100644 index 000000000..9a76f3861 --- /dev/null +++ b/micro-reactive/src/test/java/app/streaming/com/aol/micro/server/SingleClassTest.java @@ -0,0 +1,145 @@ +package app.streaming.com.aol.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; + +import cyclops.reactive.ReactiveSeq; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.reactive.rest.ReactiveRequest; +import com.oath.micro.server.reactive.rest.ReactiveResponse; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +@Path("/single") +public class SingleClassTest implements RestResource { + + RestAgent rest = new RestAgent(); + + + MicroserverApp server; + + static String lastRecieved = null; + + @Before + public void startServer() { + lastRecieved = null; + server = new MicroserverApp( + SingleClassTest.class, () -> "simple-app"); + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + List boos = new ReactiveRequest( + 1000, 1000) + .getJsonStream("http://localhost:8080/simple-app/single/infinite-boo", + String.class) + .toList(); + + assertThat(boos.size(), is(5)); + // System.out.println(rest.get("http://localhost:8080/simple-app/single/ping")); + // assertThat(rest.get("http://localhost:8080/simple-app/single/ping"), + // is("[1,2,3,4]")); + + // assertThat(lastRecieved, equalTo("input")); + + } + + @GET + @Produces(MediaType.TEXT_PLAIN) + @Path("/example") + public Response streamExample() { + StreamingOutput stream = new StreamingOutput() { + @Override + public void write(OutputStream os) throws IOException, WebApplicationException { + Writer writer = new BufferedWriter( + new OutputStreamWriter( + os)); + for (int i = 0; i < 100_000_000; i++) { + writer.write("test"); + + writer.flush(); + /** try { + Thread.sleep(100l); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }**/ + } + } + }; + return Response.ok(stream) + .build(); + } + + @GET + @Produces(MediaType.TEXT_PLAIN) + @Path("/out") + public Response output() { + StringBuilder b = new StringBuilder(); + + for (int i = 0; i < 100_000; i++) { + b.append("test"); + + } + + return Response.ok(b.toString()) + .build(); + } + + @GET + @Produces("application/json") + @Path("/infinite-boo") + public Response boo() { + + Response response = ReactiveResponse.publishAsJson(ReactiveSeq.generate(() -> "boo!") + .limit(5)); + + System.out.println("created response"); + return response; + } + + @GET + @Produces("application/json") + @Path("/ping") + public Response ping() { + + Response response = ReactiveResponse.publishAsJson(ReactiveSeq.of(1, 2, 3, 4) + .limit(5)); + System.out.println("created response"); + return response; + } + +} \ No newline at end of file diff --git a/micro-reactive/src/test/java/com/aol/micro/server/reactive/CyclopsReactorTest.java b/micro-reactive/src/test/java/com/aol/micro/server/reactive/CyclopsReactorTest.java deleted file mode 100644 index 855e4c6ee..000000000 --- a/micro-reactive/src/test/java/com/aol/micro/server/reactive/CyclopsReactorTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.aol.micro.server.reactive; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; - -import org.junit.Test; - -import com.aol.cyclops.control.FutureW; -import com.aol.cyclops.control.LazyReact; -import com.aol.cyclops.control.Maybe; -import com.aol.cyclops.data.collections.extensions.standard.ListX; -import com.aol.cyclops.types.anyM.AnyMSeq; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -public class CyclopsReactorTest { - - @Test - public void testFrom() { - AnyMSeq flux = CyclopsReactor.from(Flux.just("hello","world","c")); - - System.out.println(Flux.just("hello","world") - .map(a->a+"!") - .toList().get()); - - - String res = flux.map(a->a+"!") - .join("-"); - - assertThat(res,equalTo("hello!-world!-c!")); - } - - @Test - public void testFromFlux() { - - assertThat(CyclopsReactor.fromFlux(Flux.just(1,2,3)) - .toListX(),equalTo(ListX.of(1,2,3))); - } - - @Test - public void testFromMono() { - assertThat(CyclopsReactor.fromMono(Mono.just(2)) - .toMaybe(),equalTo(Maybe.just(2))); - } - - @Test - public void testReactiveSeq() { - assertThat(CyclopsReactor.reactiveSeq(Flux.just(1,2,3)) - .toListX(),equalTo(ListX.of(1,2,3))); - } - - @Test - public void testFutureStream() { - assertThat(CyclopsReactor.futureStream(Flux.just(1,2,3), new LazyReact()) - .toListX(),equalTo(ListX.of(1,2,3))); - } - - @Test - public void testFutureW() { - assertThat(CyclopsReactor.futureW(Mono.just(2)) - .toMaybe(),equalTo(Maybe.just(2))); - } - -} diff --git a/micro-reactive/src/test/java/com/aol/micro/server/reactive/EventQueueManagerTest.java b/micro-reactive/src/test/java/com/aol/micro/server/reactive/EventQueueManagerTest.java deleted file mode 100644 index 322acbb9a..000000000 --- a/micro-reactive/src/test/java/com/aol/micro/server/reactive/EventQueueManagerTest.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.aol.micro.server.reactive; - -import static org.hamcrest.CoreMatchers.anyOf; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.Before; -import org.junit.Test; - -import com.aol.cyclops.control.Eval; -import com.aol.cyclops.control.Maybe; -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.data.async.QueueFactories; - -public class EventQueueManagerTest { - - - private String processJob(int in){ - return null; - } - EventQueueManager manager; - Executor ex = Executors.newFixedThreadPool(10); - volatile String recieved; - @Before - public void setup(){ - recieved =null; - manager = EventQueueManager.of(ex,QueueFactories.boundedNonBlockingQueue(1000)); - } - - - @Test - public void testPush() { - manager.push("hello", "world"); - } - - public void handleEvent(String e){ - - } - @Test - public void testConfigure() throws InterruptedException { - String data = ""; - manager.forEach("bus-a",this::handleEvent); - - manager.push("bus-a", data); - - - manager.forEach("hello",a->recieved= a); - - manager.push("hello", "world"); - - Thread.sleep(100); - - System.out.println(recieved); - assertThat(recieved,equalTo("world")); - } - public String process(String s){ - return null; - } - @Test - public void testStream() throws InterruptedException { - - - - manager.stream("2") - .futureOperations(ex) - .forEach(a->recieved= a); - - manager.push("2", "world"); - - - Thread.sleep(100); - - System.out.println(recieved); - assertThat(recieved,equalTo("world")); - } - - @Test - public void testLazyValue() { - - ReactiveSeq.generate(()->"input") - .onePer(1,TimeUnit.SECONDS) - .futureOperations(ex) - .forEach(n->manager.push("lazy",n)); - - Eval lazy = manager.lazy("lazy"); - - lazy = lazy.map(in->in+"-message!") - .map(in->in+"!"); - - - - - - assertThat(lazy.get(),equalTo("input-message!!")); - assertThat(lazy.get(),equalTo("input-message!!")); - - - } - AtomicInteger count =new AtomicInteger(0); - @Test - public void testMaybe() { - - ReactiveSeq.generate(()->"input") - .onePer(1,TimeUnit.SECONDS) - .map(s->s+":"+count.incrementAndGet()) - .peek(System.out::println) - .futureOperations(ex) - .forEach(n->manager.push("lazy",n)); - - Maybe lazy1 = manager.maybe("lazy"); - Maybe lazy2 = manager.maybe("lazy"); - - - - - - assertThat(lazy1.get(),anyOf(equalTo("input:1"),equalTo("input:2"))); - assertThat(lazy2.get(),anyOf(equalTo("input:1"),equalTo("input:2"),equalTo("input:3"))); - - - } - - public String restCall(String in){ - return "hello"; - } - - @Test - public void testIoFutureStream() throws InterruptedException { - - - - - manager.ioFutureStream("futureStream") - .peek(a->recieved= a) - .run(); - - - manager.push("futureStream", "world"); - - Thread.sleep(100); - - System.out.println(recieved); - assertThat(recieved,equalTo("world")); - } - -} diff --git a/micro-reactive/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-reactive/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-reactive/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-reactive/src/test/java/com/aol/micro/server/reactive/ScheduledJobTest.java b/micro-reactive/src/test/java/com/oath/micro/server/reactive/ScheduledJobTest.java similarity index 91% rename from micro-reactive/src/test/java/com/aol/micro/server/reactive/ScheduledJobTest.java rename to micro-reactive/src/test/java/com/oath/micro/server/reactive/ScheduledJobTest.java index 87e797187..78b779ab2 100644 --- a/micro-reactive/src/test/java/com/aol/micro/server/reactive/ScheduledJobTest.java +++ b/micro-reactive/src/test/java/com/oath/micro/server/reactive/ScheduledJobTest.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.reactive; +package com.oath.micro.server.reactive; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; @@ -10,8 +10,8 @@ import org.junit.Test; -import com.aol.micro.server.events.ScheduledJob; -import com.aol.micro.server.events.SystemData; +import com.oath.micro.server.events.ScheduledJob; +import com.oath.micro.server.events.SystemData; public class ScheduledJobTest { diff --git a/micro-reactive/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-reactive/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-reactive/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-s3/README.md b/micro-s3/README.md new file mode 100644 index 000000000..11b13c9cf --- /dev/null +++ b/micro-s3/README.md @@ -0,0 +1,214 @@ +# S3 Plugin + +[micro-S3 example apps](https://github.com/aol/micro-server/tree/master/micro-S3/src/test/java/app) + +This adds a facility to use AmazonS3Client. The following APIs are provided + +1. S3ManifestComparator : Only download changed datasets from S3 +2. S3ObjectWriter : For writing Java Objects to S3. SSE AES236 available. +3. S3StringWriter : For writing UTF-8 Strings to S3. SSE AES236 available. +4. S3Reader : For reading data from S3 +5. S3Deleter : For deleting data from S3 +6. S3Utils : General S3 uploading / downloading utils. Creational entry point for the various CRUD Apis (S3ObjectWriter, S3StringWriter, S3Reader, S3Deleter) +7. DistributedMap implementation that uses S3 as distributed persistent map + +See also [micro-async-data-writer](https://github.com/aol/micro-server/tree/master/micro-async-data-writer) and [micro-async-data-loader](https://github.com/aol/micro-server/tree/master/micro-async-data-loader) for automated management of writing versioned data and loading versioned data from S3 (or couchbase via micro-couchbase), that builds on this plugin. + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-s3/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-s3) + +Simply add to the classpath + +Maven +```xml + + com.oath.microservices + micro-s3 + x.yz + +``` +Gradle +```groovy + compile 'com.oath.microservices:micro-s3:x.yz' +``` + +# Manifest comparison + +Manifest comparison stores a manifest along with each value. The manifest contains the version for the value, if the version has changed, the latest verson of the value will be loaded. + +Configure the S3 Bucket for Manifest comparision via this property + +s3.manifest.comparator.bucket + +You can also configure the key under which your data will be stored with + +s3.manifest.comparator.key:default + + + key : manifest [contains version info] + versionedKey : key with version + +This allows large immutable datastructures to be stored in as a key/value pair (with separate key/value pairing for version info), and reloaded automatically on change. + +## Injecting the manifest comparator + +Inject the Spring bean created by micro-s3 ManifestComparator into your own beans. Customise the key used (allows multiple ManifestComparators to be used) + +```java +public class ManifestComparatorResource { + + + private final ManifestComparator comparator; + @Autowired + public ManifestComparatorResource(ManifestComparator comparator) { + this.comparator = comparator.withKey("test-key"); + } +``` + +## Create a scheduled job + +See micro-events, for Microserver help in managing scheduled jobs. + +Create a scheduled job to check the manifest for changes & automatically reload data when stale. + +In the example below we run the versioned key cleaner once per day, and check for changes every minute. + + ```java +@Component +public class DataLoader implements ScheduledJob{ + + private final ManifestComparator comparator; + @Autowired + public DataLoader(ManifestComparator comparator) { + this.comparator = comparator.withKey("test-key"); + } + @Override + public SystemData scheduleAndLog() { + try{ + boolean changed = comparator.isOutOfDate(); + comparator.load(); + return SystemData.builder().errors(0).processed(isOutOfDate?1:0).build(); + }catch(Exception e){ + return SystemData.builder().errors(1).processed(0).build(); + } + } + +} + ``` + + ```java + +@Component +public class Schedular{ + + private final DataCleaner cleaner; + private final DataLoader loader; + + public Schedular(DataCleaner cleaner,DataLoader loader){ + this.cleaner = cleaner; + this.loader = loader; + } + + + @Scheduled(cron = "0 1 1 * * ?") + public synchronized void scheduleCleaner(){ + cleaner.scheduleAndLog(); + } + @Scheduled(cron = "0 * * * * *") + public synchronized void scheduleLoader(){ + loader.scheduleAndLog(); + } + +} + + ``` + +Elsewhere a single writer service can write data to the store for all services of a type to load. See micro-mysql or micro-curator for a DistributedLock implementation + +e.g. + + ```java + @Component + public class DataWriter { + + private final DistributedLockService lockService; + + private final ManifestComparator comparator; + @Autowired + public DataWriter(DistributedLockService lockService,ManifestComparator comparator) { + this.lockService = lockService; + this.comparator = comparator.withKey("test-key"); + } + + public void write(Supplier data){ + if(lockService.tryLock("single-writer-lock-a") { + comparator.saveAndIncrement(data.get()); + } + } + + + + } + + ``` + +## DistributedMap + + Configure the S3 to be used by the DistributedMap with the following property + + s3.distributed.map.bucket + +Then inject in either DistributedMap or it's concrete implementation S3DistributedMapClient into your code to use S3 as a remote persistent Key Value store. + + ```java + + @Component + public class MyService{ + + private final DistributedMap map; + + @Autowired + public MyService(DistributedMap map){ + this.map = map; + } + + } + + ``` + + + +## Usage AmazonS3Client + +This plugin also provides an AmazonS3Client implementation bean. + +You may configure AWS credentials in one of two ways. +The first is to use the AWS default chain for configuration, by setting `s3.useDefaultChain` to `true`. +This allows you to rely on instance roles if your client is hosted on AWS, or to specify your credentials as environment variables if not. +For full details on the default AWS chain, see the [official AWS docs](http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html) + +The second option is to define properties for `s3.accessKey`, `s3.secretKey` and optionally `s3.sessionToken` (optionally - only for short term keys) +[AmazonS3Client](http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html) + +Configure the S3 Bucket for Manifest comparision via this property + +s3.manifest.comparator.bucket + +You can also configure the key under which your data will be stored with + +s3.manifest.comparator.key:default + +```java +@Component +public class S3DAO{ + + private final AmazonS3Client client; + + public S3DAO(AmazonS3Client client){ + this.client = client; + } + + +} +``` diff --git a/micro-s3/build.gradle b/micro-s3/build.gradle index 955f1be1f..6c5c6dc0a 100644 --- a/micro-s3/build.gradle +++ b/micro-s3/build.gradle @@ -1,70 +1,75 @@ description = 'micro-s3' dependencies { - compile ("com.aol.simplereact:cyclops-react:$cyclopsReactVersion") - compile 'com.amazonaws:aws-java-sdk:' + s3Version - compile project(':micro-core') - - compile 'commons-io:commons-io:'+commonsIOVersion - testCompile project(':micro-grizzly-with-jersey') + compile("com.oath.cyclops:cyclops:$cyclopsVersion") + compile 'com.amazonaws:aws-java-sdk:' + s3Version + compile project(':micro-core') + compile project(':micro-manifest-comparator') + testCompile group: 'org.springframework', name: 'spring-test', version: springVersion + testCompile group: 'io.dropwizard.metrics', name: 'metrics-core', version: '3.1.0' + testCompile group: 'org.coursera', name: 'dropwizard-metrics-datadog', version: '1.1.6' + testCompile group: 'com.github.cbismuth', name: 'junit-repeat-rule', version: '1.1.0' + testCompile "com.oath.cyclops:cyclops-futurestream:$cyclopsVersion" + compile 'commons-io:commons-io:' + commonsIOVersion + testCompile project(':micro-grizzly-with-jersey') } modifyPom { - project { - name 'Microserver s3 integration' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver s3 integration' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' - groupId 'com.aol.microservices' - artifactId 'micro-s3' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + groupId 'com.oath.microservices' + artifactId 'micro-s3' + version "$version" - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - developer { - id 'earlzero' - name 'Nikita Sapozhnikov' - email 'nikita.sapozhnikov@teamaol.com' - } - } - - } + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-s3/readme.md b/micro-s3/readme.md deleted file mode 100644 index c566b9a08..000000000 --- a/micro-s3/readme.md +++ /dev/null @@ -1,40 +0,0 @@ -# S3 Plugin - -This adds a facility to use AmazonS3Client. - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-s3/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-s3) - -Simply add to the classpath - -Maven -```xml - - com.aol.microservices - micro-s3 - x.yz - -``` -Gradle -```groovy - compile 'com.aol.microservices:micro-s3:x.yz' -``` -## Usage -This plugin simply provides an AmazonS3Client implementation bean. You should just fill properties -s3.accessKey, s3.secretKey and s3.sessionToken (optionally - only for short term keys) -[AmazonS3Client](http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html) - -```java -@Component -public class S3DAO{ - - private final AmazonS3Client client; - - public S3DAO(AmazonS3Client client){ - this.client = client; - } - - -} -``` diff --git a/micro-s3/src/main/java/com/aol/micro/server/s3/CleanupFileVisitor.java b/micro-s3/src/main/java/com/aol/micro/server/s3/CleanupFileVisitor.java deleted file mode 100644 index acb6d7605..000000000 --- a/micro-s3/src/main/java/com/aol/micro/server/s3/CleanupFileVisitor.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aol.micro.server.s3; - -import java.io.IOException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; - -public class CleanupFileVisitor extends SimpleFileVisitor { - - private final Path tempDirectory; - - public CleanupFileVisitor(Path directory) { - this.tempDirectory = directory; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException { - if (e == null) { - if(!dir.equals(tempDirectory)) { - Files.delete(dir); - } - return FileVisitResult.CONTINUE; - } else { - throw e; - } - } -} diff --git a/micro-s3/src/main/java/com/aol/micro/server/s3/DirectoryCleaner.java b/micro-s3/src/main/java/com/aol/micro/server/s3/DirectoryCleaner.java deleted file mode 100644 index bf72e1cc2..000000000 --- a/micro-s3/src/main/java/com/aol/micro/server/s3/DirectoryCleaner.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aol.micro.server.s3; - -import java.io.File; -import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; - -import javax.annotation.PostConstruct; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -@Component -public class DirectoryCleaner { - - private final String temporaryDirectory; - - @Autowired - public DirectoryCleaner(@Value("${s3.temp.dir:#{null}") String temporaryDirectory) { - this.temporaryDirectory = temporaryDirectory; - } - - @PostConstruct - public void clean() throws IOException { - if (temporaryDirectory != null && new File(temporaryDirectory).exists()) { - Path directory = FileSystems.getDefault().getPath(temporaryDirectory); - Files.walkFileTree(directory, new CleanupFileVisitor(directory)); - } - } - -} diff --git a/micro-s3/src/main/java/com/aol/micro/server/s3/EmptyInputStream.java b/micro-s3/src/main/java/com/aol/micro/server/s3/EmptyInputStream.java deleted file mode 100644 index a395d4223..000000000 --- a/micro-s3/src/main/java/com/aol/micro/server/s3/EmptyInputStream.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.aol.micro.server.s3; - -import java.io.IOException; -import java.io.InputStream; - -class EmptyInputStream extends InputStream { - - @Override - public int available() { - return 0; - } - - @Override - public int read() throws IOException { - throw new IOException("Nothing to read here"); - } - -} diff --git a/micro-s3/src/main/java/com/aol/micro/server/s3/S3ClientProvider.java b/micro-s3/src/main/java/com/aol/micro/server/s3/S3ClientProvider.java deleted file mode 100644 index 6890a1f81..000000000 --- a/micro-s3/src/main/java/com/aol/micro/server/s3/S3ClientProvider.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.aol.micro.server.s3; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import com.amazonaws.auth.AWSCredentials; -import com.amazonaws.auth.BasicAWSCredentials; -import com.amazonaws.auth.BasicSessionCredentials; -import com.amazonaws.regions.Region; -import com.amazonaws.regions.Regions; -import com.amazonaws.services.s3.AmazonS3Client; - -@Configuration -public class S3ClientProvider { - - @Autowired - private S3Configuration s3Configuration; - - @Bean - public AmazonS3Client getClient() { - - AWSCredentials credentials; - - if (s3Configuration.getSessionToken() == null) { - credentials = new BasicAWSCredentials(s3Configuration.getAccessKey(), s3Configuration.getSecretKey()); - } else { - credentials = new BasicSessionCredentials(s3Configuration.getAccessKey(), s3Configuration.getSecretKey(), - s3Configuration.getSessionToken()); - } - - AmazonS3Client amazonS3Client = new AmazonS3Client(credentials); - - if (s3Configuration.getRegion() != null) { - Region region = Region.getRegion(Regions.fromName(s3Configuration.getRegion())); - amazonS3Client.setRegion(region); - } - - return amazonS3Client; - } -} diff --git a/micro-s3/src/main/java/com/aol/micro/server/s3/S3Configuration.java b/micro-s3/src/main/java/com/aol/micro/server/s3/S3Configuration.java deleted file mode 100644 index 70b86ca7b..000000000 --- a/micro-s3/src/main/java/com/aol/micro/server/s3/S3Configuration.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.aol.micro.server.s3; - -import lombok.Getter; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -@Component -@Getter -public class S3Configuration { - - private final String accessKey; - private final String secretKey; - private final String sessionToken; - private final String region; - private final int uploadThreads; - private final String uploadThreadNamePrefix; - - @Autowired - public S3Configuration(@Value("${s3.accessKey}") String accessKey, @Value("${s3.secretKey}") String secretKey, - @Value("${s3.sessionToken:#{null}}") String sessionToken, @Value("${s3.region:#{null}}") String region, - @Value("${s3.upload.threads:5}") int uploadThreads, - @Value("${s3.upload.thread.name.prefix:s3-transfer-manager-worker-}") String uploadThreadNamePrefix) { - this.accessKey = accessKey; - this.secretKey = secretKey; - this.sessionToken = sessionToken; - this.region = region; - this.uploadThreads = uploadThreads; - this.uploadThreadNamePrefix = uploadThreadNamePrefix; - } -} diff --git a/micro-s3/src/main/java/com/aol/micro/server/s3/S3ObjectSummaryIterator.java b/micro-s3/src/main/java/com/aol/micro/server/s3/S3ObjectSummaryIterator.java deleted file mode 100644 index 63ac45a39..000000000 --- a/micro-s3/src/main/java/com/aol/micro/server/s3/S3ObjectSummaryIterator.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.aol.micro.server.s3; - -import java.util.Iterator; - -import com.amazonaws.services.s3.AmazonS3Client; -import com.amazonaws.services.s3.model.ListObjectsRequest; -import com.amazonaws.services.s3.model.ObjectListing; -import com.amazonaws.services.s3.model.S3ObjectSummary; - -public class S3ObjectSummaryIterator implements Iterator { - - private final AmazonS3Client client; - private ListObjectsRequest req; - private Iterator iterator; - private boolean empty = true; - public S3ObjectSummaryIterator(AmazonS3Client client, ListObjectsRequest req) { - this.client = client; - this.req = req; - updateIterator(); - } - - @Override - public boolean hasNext() { - if(iterator.hasNext()) { - return true; - } else if(!empty){ - updateIterator(); - return iterator.hasNext(); - } else { - return false; - } - } - - private void updateIterator() { - if(iterator == null || !iterator.hasNext()) { - ObjectListing listing = client.listObjects(req); - req = req.withMarker(listing.getNextMarker()); - empty = !listing.isTruncated(); - iterator = listing.getObjectSummaries().iterator(); - } - } - - @Override - public S3ObjectSummary next() { - updateIterator(); - return iterator.next(); - } - -} diff --git a/micro-s3/src/main/java/com/aol/micro/server/s3/S3Plugin.java b/micro-s3/src/main/java/com/aol/micro/server/s3/S3Plugin.java deleted file mode 100644 index d5f5ac0be..000000000 --- a/micro-s3/src/main/java/com/aol/micro/server/s3/S3Plugin.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.aol.micro.server.s3; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; - -public class S3Plugin implements Plugin{ - - @Override - public PSetX springClasses() { - return PSetX.of(S3Configuration.class, S3ClientProvider.class, S3Utils.class, S3TransferManagerProvider.class, DirectoryCleaner.class); - } - -} diff --git a/micro-s3/src/main/java/com/aol/micro/server/s3/S3TransferManagerProvider.java b/micro-s3/src/main/java/com/aol/micro/server/s3/S3TransferManagerProvider.java deleted file mode 100644 index 28b478b7b..000000000 --- a/micro-s3/src/main/java/com/aol/micro/server/s3/S3TransferManagerProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.aol.micro.server.s3; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import com.amazonaws.services.s3.AmazonS3Client; -import com.amazonaws.services.s3.transfer.TransferManager; - - -@Configuration -public class S3TransferManagerProvider { - - @Autowired - private S3Configuration s3Configuration; - - @Autowired - private AmazonS3Client amazonS3Client; - - @Bean - public TransferManager getTransferManager() { - return new TransferManager(amazonS3Client, createExecutorService()); - } - - private ExecutorService createExecutorService() { - ThreadFactory threadFactory = new ThreadFactory() { - private int threadCount = 1; - - public Thread newThread(Runnable r) { - Thread thread = new Thread(r); - thread.setName(s3Configuration.getUploadThreadNamePrefix() + threadCount++); - return thread; - } - }; - return Executors.newFixedThreadPool(s3Configuration.getUploadThreads(), threadFactory); - } - -} diff --git a/micro-s3/src/main/java/com/aol/micro/server/s3/S3Utils.java b/micro-s3/src/main/java/com/aol/micro/server/s3/S3Utils.java deleted file mode 100644 index df44055bd..000000000 --- a/micro-s3/src/main/java/com/aol/micro/server/s3/S3Utils.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.aol.micro.server.s3; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; -import java.util.function.Supplier; - -import org.apache.commons.io.FileUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import com.amazonaws.AmazonClientException; -import com.amazonaws.AmazonServiceException; -import com.amazonaws.services.s3.AmazonS3Client; -import com.amazonaws.services.s3.model.DeleteObjectsRequest; -import com.amazonaws.services.s3.model.DeleteObjectsRequest.KeyVersion; -import com.amazonaws.services.s3.model.ListObjectsRequest; -import com.amazonaws.services.s3.model.ObjectListing; -import com.amazonaws.services.s3.model.S3ObjectSummary; -import com.amazonaws.services.s3.transfer.Download; -import com.amazonaws.services.s3.transfer.TransferManager; -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.util.ExceptionSoftener; - -@Component -public class S3Utils { - - private static final InputStream emptyInputStream = new EmptyInputStream(); - - private final AmazonS3Client client; - private final TransferManager transferManager; - private final String tmpDirectory; - - @Autowired - public S3Utils(AmazonS3Client client, TransferManager transferManager, - @Value("${s3.tmp.dir:#{null}}") String tmpDirectory) { - this.client = client; - this.transferManager = transferManager; - this.tmpDirectory = tmpDirectory; - } - - - /** - * Method returns list of all S3ObjectSummary objects, subject to req parameters. - * Multiple S3 calls will be performed if there are more than 1000 elements there - * @param req - ListObjectRequest to be used. - * @return List of S3ObjectSummary from bucket, - */ - public List getAllSummaries(ListObjectsRequest req) { - List result = new ArrayList<>(); - String marker = null; - ListObjectsRequest req2 = (ListObjectsRequest) req.clone(); - ObjectListing listing; - do { - listing = client.listObjects(req2.withMarker(marker)); - marker = listing.getNextMarker(); - result.addAll(listing.getObjectSummaries()); - } while (listing.isTruncated()); - - return result; - } - - /** - * Method return stream of S3ObjectSummary objects, subject to req parameters - * Method will perform one query for every 1000 elements (current s3 limitation). - * It is lazy, so there would be no unnecesarry calls - * @param req - ListObjectRequest to be used. - * @param processor - Function that convert S3ObjectSummary to any object - * @return ReactiveSeq of converted S3Object summary elements. - */ - public ReactiveSeq getSummariesStream(ListObjectsRequest req, Function processor) { - return ReactiveSeq.fromIterator(new S3ObjectSummaryIterator(client, req)).map(processor); - } - - /** - * Method delete all objects from bucketName in groups by 1000 elements - * @param bucketName - * @param objects - */ - public void delete(String bucketName, List objects) { - ReactiveSeq.fromList(objects).grouped(1000).forEach(l -> { - DeleteObjectsRequest req = new DeleteObjectsRequest(bucketName); - req.setKeys(l.toList()); - client.deleteObjects(req); - }); - } - - /** - * Method returns InputStream from S3Object. Multi-part download is used to get file. - * s3.tmp.dir property used to store temporary files. You can specify temporary file name by - * using tempFileSupplier object. - * @param bucketName - * @param key - - * @param tempFileSupplier - Supplier providing temporary filenames - * @return InputStream of - * @throws AmazonServiceException - * @throws AmazonClientException - * @throws InterruptedException - * @throws IOException - */ - public InputStream getInputStream(String bucketName, String key, Supplier tempFileSupplier) - throws AmazonServiceException, AmazonClientException, InterruptedException, IOException { - File file = tempFileSupplier.get(); - try { - Download download = transferManager.download(bucketName, key, file); - download.waitForCompletion(); - return new ByteArrayInputStream(FileUtils.readFileToByteArray(file)); - } finally { - file.delete(); - } - } - - /** - * Method returns InputStream from S3Object. Multi-part download is used to get file. - * s3.tmp.dir property used to store temporary files. - * @param bucketName - * @param key - * @return - * @throws AmazonServiceException - * @throws AmazonClientException - * @throws InterruptedException - * @throws IOException - */ - public InputStream getInputStream(String bucketName, String key) - throws AmazonServiceException, AmazonClientException, InterruptedException, IOException { - Supplier tempFileSupplier = ExceptionSoftener.softenSupplier(() -> Files - .createTempFile(FileSystems.getDefault().getPath(tmpDirectory), "micro-s3", "file").toFile()); - return getInputStream(bucketName, key, tempFileSupplier); - } - - /** Provide empty InputStream. - *

- * This implementation can be convenient - * if you need to place some empty value to s3 bucket. - * - * @return empty InputStream - */ - public static InputStream emptyInputStream() { - return emptyInputStream; - } - - -} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/DirectoryCleaner.java b/micro-s3/src/main/java/com/oath/micro/server/s3/DirectoryCleaner.java new file mode 100644 index 000000000..db36d0380 --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/DirectoryCleaner.java @@ -0,0 +1,69 @@ +package com.oath.micro.server.s3; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class DirectoryCleaner { + + private final String temporaryDirectory; + + @Autowired + public DirectoryCleaner(@Value("${s3.temp.dir:#{null}}") String temporaryDirectory) { + this.temporaryDirectory = temporaryDirectory; + } + + @PostConstruct + public void clean() throws IOException { + if (temporaryDirectory != null && new File(temporaryDirectory).exists()) { + Path directory = FileSystems.getDefault() + .getPath(temporaryDirectory); + Files.walkFileTree(directory, new CleanupFileVisitor(directory)); + } + } + + static class CleanupFileVisitor extends SimpleFileVisitor { + + private final Path tempDirectory; + + public CleanupFileVisitor(Path directory) { + this.tempDirectory = directory; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + deleteNotTopDirectory(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException { + if (e == null) { + deleteNotTopDirectory(dir); + return FileVisitResult.CONTINUE; + } else { + throw e; + } + } + + private void deleteNotTopDirectory(Path dir) throws IOException { + if (!dir.equals(tempDirectory)) { + Files.delete(dir); + } + } + + } + +} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/S3Configuration.java b/micro-s3/src/main/java/com/oath/micro/server/s3/S3Configuration.java new file mode 100644 index 000000000..4b1beac23 --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/S3Configuration.java @@ -0,0 +1,47 @@ +package com.oath.micro.server.s3; + +import lombok.Getter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.Objects; + +@Component +@Getter +public class S3Configuration { + + private final String accessKey; + private final String secretKey; + private final String sessionToken; + private final String region; + private final boolean defaultChainEnabled; + private final int uploadThreads; + private final String uploadThreadNamePrefix; + private final int maxConnections; + + @Autowired + public S3Configuration(@Value("${s3.accessKey:#{null}}") String accessKey, + @Value("${s3.secretKey:#{null}}") String secretKey, + @Value("${s3.useDefaultChain:false}") boolean defaultChainEnabled, + @Value("${s3.sessionToken:#{null}}") String sessionToken, + @Value("${s3.region:#{null}}") String region, + @Value("${s3.upload.threads:5}") int uploadThreads, + @Value("${s3.upload.thread.name.prefix:s3-transfer-manager-worker-}") String uploadThreadNamePrefix, + @Value("${s3.client.maxConnections:100}") int maxConnections) { + + if((Objects.isNull(accessKey) || Objects.isNull(secretKey)) && !defaultChainEnabled) { + throw new RuntimeException("No S3 authorization method provided. " + + "Please either enable the aws default credentials chain with s3.useDefaultChain, " + + "or provide access keys via s3.accessKey and s3.secretKey (and optionally s3.sessionToken)"); + } + this.accessKey = accessKey; + this.secretKey = secretKey; + this.sessionToken = sessionToken; + this.defaultChainEnabled = defaultChainEnabled; + this.region = region; + this.uploadThreads = uploadThreads; + this.uploadThreadNamePrefix = uploadThreadNamePrefix; + this.maxConnections = maxConnections; + } +} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/data/ReadUtils.java b/micro-s3/src/main/java/com/oath/micro/server/s3/data/ReadUtils.java new file mode 100644 index 000000000..8c9fddc02 --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/data/ReadUtils.java @@ -0,0 +1,97 @@ +package com.oath.micro.server.s3.data; + +import com.amazonaws.AmazonClientException; +import com.amazonaws.AmazonServiceException; +import com.amazonaws.services.s3.transfer.Download; +import com.amazonaws.services.s3.transfer.TransferManager; +import lombok.AllArgsConstructor; +import lombok.SneakyThrows; +import org.apache.commons.io.FileUtils; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.util.function.Supplier; + +import static java.nio.file.FileSystems.getDefault; + +@AllArgsConstructor +public class ReadUtils { + private final TransferManager transferManager; + private final String tmpDirectory; + + /** + * Method returns InputStream from S3Object. Multi-part download is used to + * get file. s3.tmp.dir property used to store temporary files. You can + * specify temporary file name by using tempFileSupplier object. + * + * @param bucketName + * @param key + * - + * @param tempFileSupplier + * - Supplier providing temporary filenames + * @return InputStream of + * @throws AmazonServiceException + * @throws AmazonClientException + * @throws InterruptedException + * @throws IOException + */ + public InputStream getInputStream(String bucketName, String key, Supplier tempFileSupplier) + throws AmazonServiceException, AmazonClientException, InterruptedException, IOException { + File file = tempFileSupplier.get(); + try { + Download download = transferManager.download(bucketName, key, file); + download.waitForCompletion(); + return new ByteArrayInputStream(FileUtils.readFileToByteArray(file)); + } finally { + file.delete(); + } + } + + /** + * Return the InputStream for an S3Object. This API download (via multi-part) S3 object to a local file and return a + * InputStream to that file. The local file will be deleted when the close is called on the stream. + * + * @param bucketName S3 bucket name + * @param key key for the S3Object + * + * @return input stream to the downloaded file + * + * @throws AmazonClientException + * @throws InterruptedException + * @throws IOException + */ + public InputStream getFileInputStream(String bucketName, String key) + throws AmazonClientException, InterruptedException, IOException { + File file = createTmpFile(); + + Download download = transferManager.download(bucketName, key, file); + download.waitForCompletion(); + return Files.newInputStream(file.toPath(), StandardOpenOption.DELETE_ON_CLOSE); + } + + /** + * Method returns InputStream from S3Object. Multi-part download is used to + * get file. s3.tmp.dir property used to store temporary files. + * + * @param bucketName + * @param key + * @return + * @throws AmazonServiceException + * @throws AmazonClientException + * @throws InterruptedException + * @throws IOException + */ + public InputStream getInputStream(String bucketName, String key) + throws AmazonServiceException, AmazonClientException, InterruptedException, IOException { + return getInputStream(bucketName, key, this::createTmpFile); + } + + @SneakyThrows + private File createTmpFile() { + return Files.createTempFile(getDefault().getPath(tmpDirectory), "micro-s3", "file").toFile(); + } +} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3Deleter.java b/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3Deleter.java new file mode 100644 index 000000000..e63557d41 --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3Deleter.java @@ -0,0 +1,15 @@ +package com.oath.micro.server.s3.data; + +import com.amazonaws.services.s3.AmazonS3Client; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class S3Deleter { + private final String bucket; + private final AmazonS3Client client; + + public void delete(String key) { + client.deleteObject(bucket, key); + } +} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3DistributedMapClient.java b/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3DistributedMapClient.java new file mode 100644 index 000000000..272371c32 --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3DistributedMapClient.java @@ -0,0 +1,46 @@ +package com.oath.micro.server.s3.data; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.distributed.DistributedMap; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +@Component +public class S3DistributedMapClient implements DistributedMap { + + private final S3Reader reader; + private final S3ObjectWriter writer; + private final S3Deleter deleter; + + @Autowired + public S3DistributedMapClient(@Value("${s3.distributed.map.bucket:}") String bucket, S3Utils utils) { + this.reader = utils.reader(bucket); + this.writer = utils.writer(bucket); + this.deleter = utils.deleter(bucket); + } + + @Override + public boolean put(String key, T value) { + return writer.put(key, value) + .isSuccess(); + } + + @Override + public Optional get(String key) { + return reader. getAsObject(key) + .toOptional(); + } + + @Override + public void delete(String key) { + deleter.delete(key); + + } + +} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3ObjectWriter.java b/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3ObjectWriter.java new file mode 100644 index 000000000..ddfe6058a --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3ObjectWriter.java @@ -0,0 +1,130 @@ +package com.oath.micro.server.s3.data; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.ObjectOutputStream; +import java.util.Random; + +import cyclops.control.Eval; +import cyclops.control.Try; +import cyclops.function.FluentFunctions; +import org.apache.commons.io.FileUtils; + +import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.PutObjectRequest; +import com.amazonaws.services.s3.transfer.TransferManager; +import com.amazonaws.services.s3.transfer.Upload; +import com.amazonaws.services.s3.transfer.model.UploadResult; + + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class S3ObjectWriter { + + private final TransferManager manager; + private final String bucket; + private final File dir; + private final boolean aes256Encryption; + private final Random r = new Random(); + + /** + * + * Writes java Objects to defined S3 bucket with provided key. Calling + * map / flatMap on the returned try instance will catch any exceptions, any + * exceptions thrown will convert a Success to a Failure + * + * This call is non-blocking. + * + * @param key + * To read + * @return Data as String + */ + public Try put(String key, Object value) { + + return createObjectRequest(key, value).map(por -> { + Upload upload = manager.upload(por); + return upload; + }); + + } + + private Try createObjectRequest(String key, Object value) { + + return writeToTmpFile(value).map(FluentFunctions.ofChecked(f -> { + byte[] ba = FileUtils.readFileToByteArray(f); + InputStream is = new ByteArrayInputStream( + ba); + + ObjectMetadata md = createMetadata(ba.length); + + PutObjectRequest pr = new PutObjectRequest( + bucket, key, is, md); + return pr; + })); + } + + private Try writeToTmpFile(Object value) { + String fileName = "" + System.currentTimeMillis() + "_" + r.nextLong(); + File file = new File( + dir, fileName); + + return Try.success(1, Throwable.class) + .map(FluentFunctions.ofChecked(i -> { + FileOutputStream fs = new FileOutputStream( + file); + + ObjectOutputStream oos = new ObjectOutputStream( + fs); + oos.writeObject(value); + oos.flush(); + oos.close(); + return file; + })); + } + + /** + * Metadata object creation + * @param length + * + * @return Metadata with AES_256 encryption if enabled + */ + private ObjectMetadata createMetadata(int length) { + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentLength(length); + if (aes256Encryption) + metadata.setSSEAlgorithm(ObjectMetadata.AES_256_SERVER_SIDE_ENCRYPTION); + return metadata; + } + + /** + * Blocking call + * + * @param key + * with which to store data + * @param value + * Data value + * @return Try with completed result of operation + */ + public Try putSync(String key, Object value) { + return put(key, value).map(FluentFunctions.ofChecked(i -> i.waitForUploadResult())); + } + + /** + * Non-blocking call that will throw any Exceptions in the traditional + * manner on access + * + * @param key + * @param value + * @return + */ + public Eval putAsync(String key, Object value) { + return Eval.later(() -> put(key, value)) + .map(t -> t.orElse(null)) + .map(FluentFunctions.ofChecked(up -> up.waitForUploadResult())); + + } + +} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3Reader.java b/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3Reader.java new file mode 100644 index 000000000..b82e9d7e1 --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3Reader.java @@ -0,0 +1,52 @@ +package com.oath.micro.server.s3.data; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.ObjectInputStream; +import java.util.Date; + +import com.amazonaws.services.s3.AmazonS3Client; + + +import cyclops.control.Try; +import cyclops.reactive.ReactiveSeq; +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class S3Reader { + + private final ReadUtils readUtils; + private final AmazonS3Client client; + private final String bucket; + + public Date getLastModified(String key) { + return this.client.getObjectMetadata(bucket, key) + .getLastModified(); + } + + /** + * + * Read data from defined S3 bucket with provided key to a String + * + * @param key + * To read + * @return Data as String + */ + public Try getAsString(String key) { + return Try.withCatch(() -> ReactiveSeq.fromStream(new BufferedReader( + new InputStreamReader( + readUtils.getInputStream(bucket, + key))).lines()) + .join("\n")); + + } + + public Try getAsObject(String key) { + return Try.withCatch(() -> { + ObjectInputStream ois = new ObjectInputStream( + readUtils.getInputStream(bucket, key)); + return (T) ois.readObject(); + }); + + } +} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3StringWriter.java b/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3StringWriter.java new file mode 100644 index 000000000..704217ed7 --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3StringWriter.java @@ -0,0 +1,78 @@ +package com.oath.micro.server.s3.data; + +import java.io.ByteArrayInputStream; +import java.util.concurrent.ExecutorService; + +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.PutObjectResult; + +import cyclops.control.Future; +import cyclops.control.Try; +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class S3StringWriter { + + private final AmazonS3Client client; + private final String bucket; + private final ExecutorService uploadService; + private final boolean aes256Encryption; + + S3StringWriter(AmazonS3Client client, String bucket, ExecutorService uploadService){ + this(client, bucket, uploadService, false); + } + + /** + * + * Writes String data to defined S3 bucket with provided key. Calling + * map / flatMap on the returned try instance will catch any exceptions, any + * exceptions thrown will convert a Success to a Failure + * + * This call is blocking. + * + * @param key + * To read + * @return Data as String + */ + public Try put(String key, String value) { + + return Try.withCatch(() -> { + + byte[] bytes = value.getBytes("UTF-8"); + ByteArrayInputStream stream = new ByteArrayInputStream( + bytes); + ObjectMetadata md = createMetadata(bytes.length); + return client.putObject(bucket, key, stream, md); + + }); + + } + + /** + * Non-blocking call + * + * @param key + * @param value + * @return + */ + public Future putAsync(String key, String value) { + return Future.of(() -> put(key, value), this.uploadService) + .flatMap(t->t.fold(p->Future.ofResult(p),e->Future.ofError(e))); + } + + /** + * Metadata object creation + * @param length + * + * @return Metadata with AES_256 encryption if enabled + */ + private ObjectMetadata createMetadata(int length) { + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentLength(length); + if (aes256Encryption) + metadata.setSSEAlgorithm(ObjectMetadata.AES_256_SERVER_SIDE_ENCRYPTION); + return metadata; + } + +} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3Utils.java b/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3Utils.java new file mode 100644 index 000000000..4ab371912 --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/data/S3Utils.java @@ -0,0 +1,248 @@ +package com.oath.micro.server.s3.data; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.function.Function; +import java.util.function.Supplier; + +import cyclops.reactive.ReactiveSeq; +import lombok.Getter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import com.amazonaws.AmazonClientException; +import com.amazonaws.AmazonServiceException; +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.model.DeleteObjectsRequest; +import com.amazonaws.services.s3.model.DeleteObjectsRequest.KeyVersion; +import com.amazonaws.services.s3.model.ListObjectsRequest; +import com.amazonaws.services.s3.model.ObjectListing; +import com.amazonaws.services.s3.model.S3ObjectSummary; +import com.amazonaws.services.s3.transfer.TransferManager; + + +@Component +public class S3Utils { + + private static final InputStream emptyInputStream = new EmptyInputStream(); + + private final AmazonS3Client client; + private final TransferManager transferManager; + private final String tmpDirectory; + private final ExecutorService uploaderService; + private final boolean aes256Encryption; + @Getter + private final ReadUtils readUtils; + + @Autowired + public S3Utils(AmazonS3Client client, TransferManager transferManager, + @Value("${s3.tmp.dir:#{systemProperties['java.io.tmpdir']}}") String tmpDirectory, + @Value("${s3.aes256.enabled:false}") boolean aes256Encryption, + @Qualifier("s3UploadExecutorService") ExecutorService uploaderService) { + this.client = client; + this.transferManager = transferManager; + this.tmpDirectory = tmpDirectory; + this.uploaderService = uploaderService; + this.aes256Encryption = aes256Encryption; + this.readUtils = new ReadUtils(transferManager, tmpDirectory); + } + + public S3Utils(AmazonS3Client client, TransferManager transferManager, String tmpDirectory, + ExecutorService uploaderService) { + this(client, transferManager, tmpDirectory, false, uploaderService); + } + + public S3Reader reader(String bucket) { + + return new S3Reader(readUtils, client, bucket); + } + + public S3ObjectWriter writer(String bucket) { + return new S3ObjectWriter(transferManager, bucket, new File(tmpDirectory), + aes256Encryption); + } + + public S3StringWriter stringWriter(String bucket) { + return new S3StringWriter(client, bucket, uploaderService, aes256Encryption); + } + + public S3Deleter deleter(String bucket) { + return new S3Deleter(bucket, client); + } + + /** + * Method returns list of all S3ObjectSummary objects, subject to + * req parameters. Multiple S3 calls will be performed if there are + * more than 1000 elements there + * + * @param req + * - ListObjectRequest to be used. + * @return List of S3ObjectSummary from bucket, + */ + public List getAllSummaries(ListObjectsRequest req) { + List result = new ArrayList<>(); + String marker = null; + ListObjectsRequest req2 = (ListObjectsRequest) req.clone(); + ObjectListing listing; + do { + listing = client.listObjects(req2.withMarker(marker)); + marker = listing.getNextMarker(); + result.addAll(listing.getObjectSummaries()); + } while (listing.isTruncated()); + + return result; + } + + /** + * Method return stream of S3ObjectSummary objects, subject to req + * parameters Method will perform one query for every 1000 elements (current + * s3 limitation). It is lazy, so there would be no unnecesarry calls + * + * @param req + * - ListObjectRequest to be used. + * @param processor + * - Function that convert S3ObjectSummary to any object + * @return ReactiveSeq of converted S3Object summary elements. + */ + public ReactiveSeq getSummariesStream(ListObjectsRequest req, Function processor) { + return ReactiveSeq.fromIterator(new S3ObjectSummaryIterator(client, req)) + .map(processor); + } + + /** + * Method delete all objects from bucketName in groups by 1000 + * elements + * + * @param bucketName + * @param objects + */ + public void delete(String bucketName, List objects) { + ReactiveSeq.fromList(objects) + .grouped(1000) + .forEach(l -> { + DeleteObjectsRequest req = new DeleteObjectsRequest(bucketName); + req.setKeys(l.toList()); + client.deleteObjects(req); + }); + } + + /** + * Provide empty InputStream. + *

+ * This implementation can be convenient if you need to place some empty + * value to s3 bucket. + * + * @return empty InputStream + */ + public static InputStream emptyInputStream() { + return emptyInputStream; + } + + /** + * Method returns InputStream from S3Object. Multi-part download is used to + * get file. s3.tmp.dir property used to store temporary files. + * + * @param bucketName + * @param key + * @return + * @throws AmazonServiceException + * @throws AmazonClientException + * @throws InterruptedException + * @throws IOException + * + * @deprecated see ReadUtils + */ + @Deprecated + public InputStream getInputStream(String bucketName, String key) + throws AmazonServiceException, AmazonClientException, InterruptedException, IOException{ + return readUtils.getInputStream(bucketName, key); + } + + /** + * Method returns InputStream from S3Object. Multi-part download is used to + * get file. s3.tmp.dir property used to store temporary files. You can + * specify temporary file name by using tempFileSupplier object. + * + * @param bucketName + * @param key + * - + * @param tempFileSupplier + * - Supplier providing temporary filenames + * @return InputStream of + * @throws AmazonServiceException + * @throws AmazonClientException + * @throws InterruptedException + * @throws IOException + * + * @deprecated see ReadUtils + */ + @Deprecated + public InputStream getInputStream(String bucketName, String key, Supplier tempFileSupplier) throws AmazonServiceException, AmazonClientException, InterruptedException, IOException{ + return readUtils.getInputStream(bucketName, key, tempFileSupplier); + } + + static class EmptyInputStream extends InputStream { + + @Override + public int available() { + return 0; + } + + @Override + public int read() throws IOException { + throw new IOException("Nothing to read here"); + } + + } + + static class S3ObjectSummaryIterator implements Iterator { + + private final AmazonS3Client client; + private ListObjectsRequest req; + private Iterator iterator; + private boolean empty = true; + + public S3ObjectSummaryIterator(AmazonS3Client client, ListObjectsRequest req) { + this.client = client; + this.req = req; + updateIterator(); + } + + @Override + public boolean hasNext() { + if (iterator.hasNext()) { + return true; + } else if (!empty) { + updateIterator(); + return iterator.hasNext(); + } else { + return false; + } + } + + private void updateIterator() { + if (iterator == null || !iterator.hasNext()) { + ObjectListing listing = client.listObjects(req); + req = req.withMarker(listing.getNextMarker()); + empty = !listing.isTruncated(); + iterator = listing.getObjectSummaries() + .iterator(); + } + } + + @Override + public S3ObjectSummary next() { + updateIterator(); + return iterator.next(); + } + + } + +} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/manifest/comparator/S3ManifestComparator.java b/micro-s3/src/main/java/com/oath/micro/server/s3/manifest/comparator/S3ManifestComparator.java new file mode 100644 index 000000000..d7b13158d --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/manifest/comparator/S3ManifestComparator.java @@ -0,0 +1,326 @@ +package com.oath.micro.server.s3.manifest.comparator; + +import java.util.Date; + +import com.oath.cyclops.util.ExceptionSoftener; +import cyclops.control.Try; +import cyclops.control.Either; +import cyclops.data.tuple.Tuple; +import cyclops.data.tuple.Tuple2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +import com.oath.micro.server.manifest.Data; +import com.oath.micro.server.manifest.ManifestComparator; +import com.oath.micro.server.manifest.ManifestComparatorKeyNotFoundException; +import com.oath.micro.server.manifest.VersionedKey; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.s3.data.S3Deleter; +import com.oath.micro.server.s3.data.S3ObjectWriter; +import com.oath.micro.server.s3.data.S3Reader; +import com.oath.micro.server.s3.data.S3StringWriter; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.SneakyThrows; +import lombok.val; +import lombok.experimental.Wither; + +/** + * Manifest comparator for use with a distributed map -assumes single producer / + * multiple consumers + * + * Uses to entries in the map + * + * key : versioned key versioned key : actual data + * + * ManifestComparator stores the current version number, only when the version + * changes is the full data set loaded from the remote store. + * + * Usage as a Spring Bean - inject into the host class, and use withKey to + * customise for the targeted Key. + * + * + *

+ * {@code 
+ *  
+    {@literal @}Rest
+	public class MyDataService {
+	
+    private final ManifestComparator comparator;
+	   
+	{@literal @}Autowired
+	public  MyDataService(ManifestComparator comparator) {
+		this.comparator = comparator.withKey("test-key");
+	}
+ * 
+ *  }
+ * }
+ * 
+ * + * micro-couchbase configures a single ManifestComparator bean that can be + * customized for multiple different keys via withKey + * + * When your bean is injected save via saveAndIncrement, and periodically call + * load() to refresh data if (and only if) it has changed. + * + * ManifestComparator will automatically remove old versions on + * saveAndIncrement, but system outages may occasionally cause old keys to + * linger, you can also use clean and cleanAll to periodically to remove old key + * versions. + * + * + * @author johnmcclean + * + * @param + */ +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class S3ManifestComparator implements ManifestComparator { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + private final String key; + + private volatile Either data = Either.left(null); + private volatile long modified = -1; + + @Getter + private volatile String versionedKey; + private final S3Reader reader; + private final S3ObjectWriter writer; + private final S3StringWriter stringWriter; + private final S3Deleter deleter; + + @Wither + private long backoff; + + /** + * Create a ManifestComparator with the supplied distributed map client Data + * stored by ManifestComparator will be + * + * key : versioned key versioned key : actual data + * + * @param connection + * DistributedMapClient to store comparison data + */ + public S3ManifestComparator(S3Reader connection, S3ObjectWriter writer, S3Deleter deleter, + S3StringWriter stringWriter) { + this.key = "default"; + this.versionedKey = newKey(1L).toJson(); + this.reader = connection; + this.writer = writer; + this.deleter = deleter; + this.stringWriter = stringWriter; + backoff = 500l; + } + + @Override + @SneakyThrows + public T getData() { + while (data.isLeft()) { + Thread.sleep(500); + } + return data.orElse(null); + } + + @Override + public T getCurrentData() { + return data.fold(present -> present, () -> null); + } + + /** + * Create a ManifestComparator with the supplied distributed map client + * + * Data stored by ManifestComparator will be + * + * key : versioned key versioned key : actual data + * + * @param key + * To store actual data with + * @param connection + * DistributeMapClient connection + */ + public S3ManifestComparator(String key, S3Reader connection, S3ObjectWriter writer, S3Deleter deleter, + S3StringWriter stringWriter) { + this.key = key; + this.versionedKey = newKey(1L).toJson(); + this.reader = connection; + this.writer = writer; + this.deleter = deleter; + this.stringWriter = stringWriter; + backoff = 500l; + } + + /** + * Create a new ManifestComparator with the same distributed map connection + * that targets a different key + * + * @param key + * Key to store data with + * @return new ManifestComparator that targets specified key + */ + @Override + public S3ManifestComparator withKey(String key) { + return new S3ManifestComparator<>( + key, reader, writer, deleter, stringWriter); + } + + private VersionedKey newKey(Long version) { + return new VersionedKey( + key, version); + } + + private VersionedKey increment() { + VersionedKey currentVersionedKey = loadKeyFromS3(); + return currentVersionedKey.withVersion(currentVersionedKey.getVersion() + 1); + } + + private VersionedKey loadKeyFromS3() { + Try optionalKey = reader.getAsString(key); + return optionalKey.flatMap(val -> Try.success(JacksonUtil.convertFromJson(val, VersionedKey.class))) + .orElse(newKey(0L)); + + } + + /** + * @return true - if current data is stale and needs refreshed + */ + @Override + public boolean isOutOfDate() { + + return !versionedKey.equals(loadKeyFromS3().toJson()); + } + + /** + * @return true - if current data is stale and needs refreshed + */ + private boolean needsData() { + return this.data.isLeft(); + } + + /** + * Load data from remote store if stale + */ + @Override + public synchronized boolean load() { + Either oldData = data; + long oldModified = modified; + String oldKey = versionedKey; + try { + if (isOutOfDate() || needsData()) { + String newVersionedKey = reader.getAsString(key) + .orElse(null); + val loaded = nonAtomicload(newVersionedKey); + data = Either.right((T) loaded._2()); + modified = loaded._1(); + versionedKey = newVersionedKey; + } else { + return false; + } + } catch (Throwable e) { + data = oldData; + versionedKey = oldKey; + modified = oldModified; + logger.info(e.getMessage(), e); + throw ExceptionSoftener.throwSoftenedException(e); + } + return true; + } + + @SuppressWarnings("unchecked") + private Tuple2 nonAtomicload(String newVersionedKey) throws Throwable { + long lastMod = -1; + while (modified >= lastMod) { + lastMod = reader.getLastModified(newVersionedKey) + .getTime(); + if (modified < lastMod) + Thread.sleep(backoff); + } + Data data = reader. getAsObject(newVersionedKey) + .fold(t->t,e-> { + throw new ManifestComparatorKeyNotFoundException( + "Missing versioned key " + + newVersionedKey + + " - likely data changed during read"); + }); + logger.info("Loaded new data with date {} for key {}, versionedKey {}, versionedKey from data ", + new Object[] { data.getDate(), key, newVersionedKey, data.getVersionedKey() }); + return Tuple.tuple(lastMod, data.getData()); + } + + /** + * Clean all old (not current) versioned keys + */ + @Override + public void cleanAll() { + clean(-1); + } + + /** + * Clean specified number of old (not current) versioned keys) + * + * @param numberToClean + */ + @Override + public void clean(int numberToClean) { + logger.info("Attempting to delete the last {} records for key {}", numberToClean, key); + VersionedKey currentVersionedKey = loadKeyFromS3(); + long start = 0; + if (numberToClean != -1) + start = currentVersionedKey.getVersion() - numberToClean; + for (long i = start; i < currentVersionedKey.getVersion(); i++) { + delete(currentVersionedKey.withVersion(i) + .toJson()); + } + logger.info("Finished deleting the last {} records for key {}", numberToClean, key); + } + + private void delete(String withVersion) { + deleter.delete(withVersion); + } + + /** + * Save provided data with the key this ManifestComparator manages bump the + * versioned key version. + * + * NB : To avoid race conditions - make sure only one service (an elected + * leader) can write at a time (see micro-mysql for a mysql distributed + * lock, or micro-curator for a curator / zookeeper distributed lock + * implementation). + * + * @param data + * to save + */ + @Override + public synchronized void saveAndIncrement(T data) { + Either oldData = this.data; + final String oldKey = versionedKey; + VersionedKey newVersionedKey = increment(); + final String newKey = newVersionedKey.toJson(); + logger.info("Saving data with key {}, new version is {}", key, newVersionedKey.toJson()); + + try { + writer.putSync(newVersionedKey.toJson(), new Data( + data, new Date(), newVersionedKey.toJson())) + .flatMap(res -> stringWriter.put(key, newVersionedKey.toJson())) + .peek(res -> { + this.data = Either.right(data); + delete(versionedKey); + }).peekFailed((err) -> { + String message = String.format("Failed to update manifest comparator file from %s to %s", oldKey, newKey); + logger.warn(message, err); + }); + + } finally { + versionedKey = newVersionedKey.toJson(); + } + } + + @Override + public String toString() { + return "[S3ManifestComparator:key:" + key + ",versionedKey:" + JacksonUtil.serializeToJson(versionedKey) + "]"; + } + +} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/plugin/S3ClientProvider.java b/micro-s3/src/main/java/com/oath/micro/server/s3/plugin/S3ClientProvider.java new file mode 100644 index 000000000..851101871 --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/plugin/S3ClientProvider.java @@ -0,0 +1,57 @@ +package com.oath.micro.server.s3.plugin; + +import com.amazonaws.ClientConfiguration; +import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.auth.BasicSessionCredentials; +import com.amazonaws.regions.Region; +import com.amazonaws.regions.Regions; +import com.amazonaws.services.s3.AmazonS3Client; +import com.oath.micro.server.s3.S3Configuration; + +@Configuration +@ComponentScan(basePackages = {"com.oath.micro.server.s3"}) +public class S3ClientProvider { + + @Autowired + private S3Configuration s3Configuration; + + @Bean + public AmazonS3Client getClient() { + + AWSCredentials credentials = getAwsCredentials(); + + AmazonS3Client amazonS3Client = new AmazonS3Client(credentials, getClientConfiguration()); + + if (s3Configuration.getRegion() != null) { + Region region = Region.getRegion(Regions.fromName(s3Configuration.getRegion())); + amazonS3Client.setRegion(region); + } + + return amazonS3Client; + } + + AWSCredentials getAwsCredentials() { + AWSCredentials credentials; + + if(s3Configuration.isDefaultChainEnabled()) { + credentials = new DefaultAWSCredentialsProviderChain().getCredentials(); + } else if (s3Configuration.getSessionToken() == null) { + credentials = new BasicAWSCredentials(s3Configuration.getAccessKey(), s3Configuration.getSecretKey()); + } else { + credentials = new BasicSessionCredentials(s3Configuration.getAccessKey(), s3Configuration.getSecretKey(), + s3Configuration.getSessionToken()); + } + return credentials; + } + + private ClientConfiguration getClientConfiguration() { + return new ClientConfiguration().withMaxConnections(s3Configuration.getMaxConnections()); + } +} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/plugin/S3ManifestComparatorProvider.java b/micro-s3/src/main/java/com/oath/micro/server/s3/plugin/S3ManifestComparatorProvider.java new file mode 100644 index 000000000..993efc7ca --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/plugin/S3ManifestComparatorProvider.java @@ -0,0 +1,29 @@ +package com.oath.micro.server.s3.plugin; + +import java.io.IOException; +import java.net.URISyntaxException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.s3.data.S3Utils; +import com.oath.micro.server.s3.manifest.comparator.S3ManifestComparator; + +@Configuration +public class S3ManifestComparatorProvider { + + @Value("${s3.manifest.comparator.bucket:}") + private String bucket; + @Value("${s3.manifest.comparator.key:default}") + private String key; + @Autowired + private S3Utils s3Utils; + + @Bean + public S3ManifestComparator s3ManifestComparator() throws IOException, URISyntaxException { + return new S3ManifestComparator(s3Utils.reader(bucket), s3Utils.writer(bucket), s3Utils.deleter(bucket), + s3Utils.stringWriter(bucket)).withKey(key); + } +} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/plugin/S3Plugin.java b/micro-s3/src/main/java/com/oath/micro/server/s3/plugin/S3Plugin.java new file mode 100644 index 000000000..7701a08cf --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/plugin/S3Plugin.java @@ -0,0 +1,21 @@ +package com.oath.micro.server.s3.plugin; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.s3.DirectoryCleaner; +import com.oath.micro.server.s3.S3Configuration; +import com.oath.micro.server.s3.data.S3DistributedMapClient; +import com.oath.micro.server.s3.data.S3Utils; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +public class S3Plugin implements Plugin { + + @Override + public Set springClasses() { + return SetX.of(S3ManifestComparatorProvider.class, S3DistributedMapClient.class, S3Configuration.class, + S3ClientProvider.class, S3Utils.class, S3TransferManagerProvider.class, DirectoryCleaner.class); + } + +} diff --git a/micro-s3/src/main/java/com/oath/micro/server/s3/plugin/S3TransferManagerProvider.java b/micro-s3/src/main/java/com/oath/micro/server/s3/plugin/S3TransferManagerProvider.java new file mode 100644 index 000000000..9e7cf936a --- /dev/null +++ b/micro-s3/src/main/java/com/oath/micro/server/s3/plugin/S3TransferManagerProvider.java @@ -0,0 +1,45 @@ +package com.oath.micro.server.s3.plugin; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.transfer.TransferManager; +import com.oath.micro.server.s3.S3Configuration; + +@Configuration +public class S3TransferManagerProvider { + + @Autowired + private S3Configuration s3Configuration; + + @Autowired + private AmazonS3Client amazonS3Client; + + @Bean + public TransferManager getTransferManager() { + return new TransferManager( + amazonS3Client, s3UploadExecutorService()); + } + + @Bean + public ExecutorService s3UploadExecutorService() { + ThreadFactory threadFactory = new ThreadFactory() { + private int threadCount = 1; + + public Thread newThread(Runnable r) { + Thread thread = new Thread( + r); + thread.setName(s3Configuration.getUploadThreadNamePrefix() + threadCount++); + return thread; + } + }; + return Executors.newFixedThreadPool(s3Configuration.getUploadThreads(), threadFactory); + } + +} diff --git a/micro-s3/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-s3/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 44c6a38b4..000000000 --- a/micro-s3/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.s3.S3Plugin \ No newline at end of file diff --git a/micro-s3/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-s3/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..2f2ec9682 --- /dev/null +++ b/micro-s3/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.s3.plugin.S3Plugin \ No newline at end of file diff --git a/micro-s3/src/test/java/app/s3/distributed/map/com/oath/micro/server/S3Resource.java b/micro-s3/src/test/java/app/s3/distributed/map/com/oath/micro/server/S3Resource.java new file mode 100644 index 000000000..50cad3450 --- /dev/null +++ b/micro-s3/src/test/java/app/s3/distributed/map/com/oath/micro/server/S3Resource.java @@ -0,0 +1,35 @@ +package app.s3.distributed.map.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.distributed.DistributedMap; + +@Path("/s3") +@Rest +public class S3Resource { + + private final DistributedMap client; + + @Autowired + public S3Resource(DistributedMap client) { + this.client = client; + } + + @GET + @Path("/get") + public String bucket() { + return client.get("hello") + .toString(); + } + + @GET + @Path("/put") + public String put() { + client.put("hello", "world"); + return "added"; + } +} diff --git a/micro-s3/src/test/java/app/s3/distributed/map/com/oath/micro/server/S3RunnerTest.java b/micro-s3/src/test/java/app/s3/distributed/map/com/oath/micro/server/S3RunnerTest.java new file mode 100644 index 000000000..65facba5d --- /dev/null +++ b/micro-s3/src/test/java/app/s3/distributed/map/com/oath/micro/server/S3RunnerTest.java @@ -0,0 +1,46 @@ +package app.s3.distributed.map.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; + +@Ignore +public class S3RunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + + server = new MicroserverApp( + () -> "simple-app"); + + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + rest.get("http://localhost:8080/simple-app/s3/put"); + System.out.println("hello"); + assertThat(rest.get("http://localhost:8080/simple-app/s3/get"), containsString("world")); + + } + +} diff --git a/micro-s3/src/test/java/app/s3/manifest/comparator/com/oath/micro/server/second/ManifestComparatorResource.java b/micro-s3/src/test/java/app/s3/manifest/comparator/com/oath/micro/server/second/ManifestComparatorResource.java new file mode 100644 index 000000000..78d4a44b1 --- /dev/null +++ b/micro-s3/src/test/java/app/s3/manifest/comparator/com/oath/micro/server/second/ManifestComparatorResource.java @@ -0,0 +1,45 @@ +package app.s3.manifest.comparator.com.oath.micro.server.second; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.manifest.ManifestComparator; + +@Path("/comparator") +@Rest +public class ManifestComparatorResource { + + private volatile int count = 1; + private final ManifestComparator comparator; + + @Autowired + public ManifestComparatorResource(ManifestComparator comparator) { + this.comparator = comparator. withKey("test-key5"); + } + + @GET + @Path("/increment") + public String bucket() { + comparator.saveAndIncrement("hello" + (count++)); + return "increment"; + } + + @GET + @Path("/get") + public String get() { + comparator.load(); + return comparator.getData() + .toString(); + + } + + @GET + @Path("/check") + public String check() { + return "" + !comparator.isOutOfDate(); + + } +} diff --git a/micro-s3/src/test/java/app/s3/manifest/comparator/com/oath/micro/server/second/ManifestComparatorRunnerTest.java b/micro-s3/src/test/java/app/s3/manifest/comparator/com/oath/micro/server/second/ManifestComparatorRunnerTest.java new file mode 100644 index 000000000..8f43dbb5c --- /dev/null +++ b/micro-s3/src/test/java/app/s3/manifest/comparator/com/oath/micro/server/second/ManifestComparatorRunnerTest.java @@ -0,0 +1,54 @@ +package app.s3.manifest.comparator.com.oath.micro.server.second; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; + +public class ManifestComparatorRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + + server = new MicroserverApp( + () -> "simple-app"); + + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + @Ignore + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + rest.get("http://localhost:8080/simple-app/comparator/increment"); + + assertThat(rest.get("http://localhost:8080/simple-app/comparator/check"), equalTo("true")); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"), equalTo("hello1")); + rest.get("http://localhost:8080/simple-app/comparator/increment"); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"), equalTo("hello2")); + + rest.get("http://localhost:8080/simple-app/comparator2/increment"); + + assertThat(rest.get("http://localhost:8080/simple-app/comparator/check"), equalTo("false")); + assertThat(rest.get("http://localhost:8080/simple-app/comparator/get"), equalTo("hellob")); + + } + +} diff --git a/micro-s3/src/test/java/app/s3/manifest/comparator/com/oath/micro/server/second/SecondComparatorResource.java b/micro-s3/src/test/java/app/s3/manifest/comparator/com/oath/micro/server/second/SecondComparatorResource.java new file mode 100644 index 000000000..ef75b6f2c --- /dev/null +++ b/micro-s3/src/test/java/app/s3/manifest/comparator/com/oath/micro/server/second/SecondComparatorResource.java @@ -0,0 +1,44 @@ +package app.s3.manifest.comparator.com.oath.micro.server.second; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.manifest.ManifestComparator; + +@Path("/comparator2") +@Rest +public class SecondComparatorResource { + + private final ManifestComparator comparator; + + @Autowired + public SecondComparatorResource(ManifestComparator comparator) { + this.comparator = comparator.withKey("test-key5"); + } + + @GET + @Path("/increment") + public String bucket() { + comparator.saveAndIncrement("hellob"); + return "increment"; + } + + @GET + @Path("/get") + public String get() { + comparator.load(); + return comparator.getData() + .toString(); + + } + + @GET + @Path("/check") + public String check() { + return "" + !comparator.isOutOfDate(); + + } +} \ No newline at end of file diff --git a/micro-s3/src/test/java/app/s3/rw/map/com/oath/micro/server/S3Resource.java b/micro-s3/src/test/java/app/s3/rw/map/com/oath/micro/server/S3Resource.java new file mode 100644 index 000000000..7ee2a569f --- /dev/null +++ b/micro-s3/src/test/java/app/s3/rw/map/com/oath/micro/server/S3Resource.java @@ -0,0 +1,45 @@ +package app.s3.rw.map.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import com.oath.micro.server.s3.data.S3ObjectWriter; +import com.oath.micro.server.s3.data.S3Reader; +import com.oath.micro.server.s3.data.S3Utils; +import cyclops.control.Try; +import org.springframework.beans.factory.annotation.Autowired; + +import com.amazonaws.services.s3.transfer.Upload; + +import com.oath.micro.server.auto.discovery.Rest; + + +@Path("/s3") +@Rest +public class S3Resource { + + private final S3Reader client; + private final S3ObjectWriter writer; + + @Autowired + public S3Resource(S3Utils utils) { + this.client = utils.reader("aolp-lana-dev-test-partition-us-east-1"); + this.writer = utils.writer("aolp-lana-dev-test-partition-us-east-1"); + } + + @GET + @Path("/get") + public String bucket() { + return client.getAsString("hello") + .orElse(""); + } + + @GET + @Path("/put") + public String put() { + Try operation = writer.put("hello", "world"); + if(operation.isSuccess()) + return "added"; + return operation.failureGet().orElse(null).getMessage(); + } +} diff --git a/micro-s3/src/test/java/app/s3/rw/map/com/oath/micro/server/S3RunnerTest.java b/micro-s3/src/test/java/app/s3/rw/map/com/oath/micro/server/S3RunnerTest.java new file mode 100644 index 000000000..4ddeecb26 --- /dev/null +++ b/micro-s3/src/test/java/app/s3/rw/map/com/oath/micro/server/S3RunnerTest.java @@ -0,0 +1,45 @@ +package app.s3.rw.map.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; + +public class S3RunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + + server = new MicroserverApp( + () -> "simple-app"); + + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + @Ignore + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + rest.get("http://localhost:8080/simple-app/s3/put"); + assertThat(rest.get("http://localhost:8080/simple-app/s3/get"), containsString("world")); + + } + +} diff --git a/micro-s3/src/test/java/com/aol/micro/server/s3/DirectoryCleanerTest.java b/micro-s3/src/test/java/com/aol/micro/server/s3/DirectoryCleanerTest.java deleted file mode 100644 index 694868f44..000000000 --- a/micro-s3/src/test/java/com/aol/micro/server/s3/DirectoryCleanerTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.aol.micro.server.s3; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import org.junit.Assert; -import org.junit.Test; - -public class DirectoryCleanerTest { - - @Test - public void clean() throws IOException { - - - Path dir = Files.createTempDirectory("test"); - DirectoryCleaner cleaner = new DirectoryCleaner(dir.toString()); - Path file = Files.createTempFile(dir, "a", "b"); - Assert.assertTrue(Files.exists(file)); - cleaner.clean(); - Assert.assertFalse(Files.exists(file)); - - } -} diff --git a/micro-s3/src/test/java/com/aol/micro/server/s3/S3RunnerTest.java b/micro-s3/src/test/java/com/aol/micro/server/s3/S3RunnerTest.java deleted file mode 100644 index 5a5e68cde..000000000 --- a/micro-s3/src/test/java/com/aol/micro/server/s3/S3RunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.s3; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.amazonaws.services.s3.AmazonS3Client; -import com.amazonaws.services.s3.transfer.TransferManager; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; - -@Microserver(properties = { "s3.accessKey", "", "s3.secretKey", "" }) -public class S3RunnerTest { - - MicroserverApp server; - - @Before - public void startServer() { - - server = new MicroserverApp(() -> "s3"); - server.start(); - - } - - @After - public void stopServer() { - server.stop(); - } - - @Test - public void runAppAndBasicTest() { - - AmazonS3Client s3client = server.getSpringContext().getBean(AmazonS3Client.class); - assertThat(s3client != null, is(true)); - - S3Configuration s3Configuration = server.getSpringContext().getBean(S3Configuration.class); - assertThat(s3Configuration.getAccessKey(), is("")); - assertThat(s3Configuration.getSecretKey(), is("")); - assertThat(s3Configuration.getSessionToken() == null, is(true)); - assertThat(s3Configuration.getRegion() == null, is(true)); - assertThat(s3Configuration.getUploadThreads(), is(5)); - assertThat(s3Configuration.getUploadThreadNamePrefix(), is("s3-transfer-manager-worker-")); - - S3Utils s3Utils = server.getSpringContext().getBean(S3Utils.class); - assertThat(s3Utils != null, is(true)); - - TransferManager tm = server.getSpringContext().getBean(TransferManager.class); - assertThat(tm != null, is(true)); - - } - -} diff --git a/micro-s3/src/test/java/com/aol/micro/server/s3/S3UtilsTest.java b/micro-s3/src/test/java/com/aol/micro/server/s3/S3UtilsTest.java deleted file mode 100644 index b3768aa48..000000000 --- a/micro-s3/src/test/java/com/aol/micro/server/s3/S3UtilsTest.java +++ /dev/null @@ -1,184 +0,0 @@ -package com.aol.micro.server.s3; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Stream; - -import org.junit.Assert; -import org.junit.Test; - -import com.amazonaws.AmazonClientException; -import com.amazonaws.AmazonServiceException; -import com.amazonaws.services.s3.AmazonS3Client; -import com.amazonaws.services.s3.model.DeleteObjectsRequest.KeyVersion; -import com.amazonaws.services.s3.model.ListObjectsRequest; -import com.amazonaws.services.s3.model.ObjectListing; -import com.amazonaws.services.s3.model.S3Object; -import com.amazonaws.services.s3.model.S3ObjectSummary; -import com.amazonaws.services.s3.transfer.Download; -import com.amazonaws.services.s3.transfer.TransferManager; - -public class S3UtilsTest { - - private boolean answer = true; - - @Test - public void getAllSummaries() { - answer = true; - AmazonS3Client client = mock(AmazonS3Client.class); - ObjectListing objectListing = mock(ObjectListing.class); - when(client.listObjects(any(ListObjectsRequest.class))).thenReturn(objectListing); - when(objectListing.isTruncated()).thenAnswer(__ -> { - try { - return answer; - } finally { - answer = false; - } - }); - S3Utils utils = new S3Utils(client, null, null); - utils.getAllSummaries(new ListObjectsRequest()); - verify(objectListing, times(2)).getObjectSummaries(); - } - - @Test - public void getSummariesStream() { - answer = true; - AmazonS3Client client = mock(AmazonS3Client.class); - - - ObjectListing objectListing = mock(ObjectListing.class); - - when(objectListing.getObjectSummaries()).thenReturn(createSummaries()); - when(client.listObjects(any(ListObjectsRequest.class))).thenReturn(objectListing); - when(objectListing.isTruncated()).thenAnswer(__ -> { - try { - return answer; - } finally { - answer = false; - } - }); - // when(objectListing.getObjectSummaries()).thenReturn(summaries); - - S3Utils utils = new S3Utils(client, null, null); - verify(objectListing, times(0)).getObjectSummaries(); - Stream stream = utils.getSummariesStream(new ListObjectsRequest(), s -> { - return s.getKey(); - }); - - assertEquals(500, stream.limit(500).count()); - - verify(objectListing, times(1)).getObjectSummaries(); - - } - - @Test - public void getSummariesStreamFull() { - answer = true; - AmazonS3Client client = mock(AmazonS3Client.class); - - - ObjectListing objectListing = mock(ObjectListing.class); - - when(objectListing.getObjectSummaries()).thenReturn(createSummaries()); - when(client.listObjects(any(ListObjectsRequest.class))).thenReturn(objectListing); - when(objectListing.isTruncated()).thenAnswer(__ -> { - try { - return answer; - } finally { - answer = false; - } - }); - // when(objectListing.getObjectSummaries()).thenReturn(summaries); - - S3Utils utils = new S3Utils(client, null, null); - verify(objectListing, times(0)).getObjectSummaries(); - Stream stream = utils.getSummariesStream(new ListObjectsRequest(), s -> { - return s.getKey(); - }); - - assertEquals(2000,stream.limit(2000).count()); - - } - - - - private List createSummaries() { - List summaries = new ArrayList<>(); - - for (int i = 0; i < 1000; i++) { - S3ObjectSummary summary = new S3ObjectSummary(); - summary.setKey("" + i); - summaries.add(summary); - } - - return summaries; - } - - @Test - public void deleteObjects() { - AmazonS3Client client = mock(AmazonS3Client.class); - S3Utils utils = new S3Utils(client, null, null); - List keys = new ArrayList<>(); - for (int i = 0; i < 2000; i++) { - keys.add(new KeyVersion("")); - } - - utils.delete("", keys); - - verify(client, times(2)).deleteObjects(any()); - } - - @Test - public void getInputStreamSupplier() - throws AmazonServiceException, AmazonClientException, InterruptedException, IOException { - AmazonS3Client client = mock(AmazonS3Client.class); - TransferManager transferManager = mock(TransferManager.class); - Download download = mock(Download.class); - - when(transferManager.download(anyString(), anyString(), any())).thenReturn(download); - - File file = Files.createTempFile("micro-s3", "test").toFile(); - Assert.assertTrue(file.exists()); - S3Utils utils = new S3Utils(client, transferManager, "test"); - - utils.getInputStream("", "", () -> file); - - Assert.assertFalse(file.exists()); - } - - @Test - public void getInputStreamDefaultSupplier() - throws AmazonServiceException, AmazonClientException, InterruptedException, IOException { - AmazonS3Client client = mock(AmazonS3Client.class); - TransferManager transferManager = mock(TransferManager.class); - Download download = mock(Download.class); - - when(transferManager.download(anyString(), anyString(), any())).thenReturn(download); - - S3Utils utils = new S3Utils(client, transferManager, System.getProperty("java.io.tmpdir")); - utils.getInputStream("", ""); - verify(download).waitForCompletion(); - } - - @Test - public void emptyInputStream() throws IOException { - assertEquals(0, S3Utils.emptyInputStream().available()); - } - - @Test(expected = IOException.class) - public void emptyInputStreamException() throws IOException { - S3Utils.emptyInputStream().read(); - } - -} diff --git a/micro-s3/src/test/java/com/oath/micro/server/s3/DirectoryCleanerTest.java b/micro-s3/src/test/java/com/oath/micro/server/s3/DirectoryCleanerTest.java new file mode 100644 index 000000000..8dabccb3b --- /dev/null +++ b/micro-s3/src/test/java/com/oath/micro/server/s3/DirectoryCleanerTest.java @@ -0,0 +1,24 @@ +package com.oath.micro.server.s3; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.junit.Assert; +import org.junit.Test; + +public class DirectoryCleanerTest { + + @Test + public void clean() throws IOException { + + Path dir = Files.createTempDirectory("test"); + DirectoryCleaner cleaner = new DirectoryCleaner( + dir.toString()); + Path file = Files.createTempFile(dir, "a", "b"); + Assert.assertTrue(Files.exists(file)); + cleaner.clean(); + Assert.assertFalse(Files.exists(file)); + + } +} diff --git a/micro-s3/src/test/java/com/oath/micro/server/s3/ReadUtilsTest.java b/micro-s3/src/test/java/com/oath/micro/server/s3/ReadUtilsTest.java new file mode 100644 index 000000000..1a1105b9b --- /dev/null +++ b/micro-s3/src/test/java/com/oath/micro/server/s3/ReadUtilsTest.java @@ -0,0 +1,78 @@ +package com.oath.micro.server.s3; + +import com.amazonaws.AmazonClientException; +import com.amazonaws.services.s3.transfer.Download; +import com.amazonaws.services.s3.transfer.TransferManager; +import com.oath.micro.server.s3.data.ReadUtils; +import lombok.SneakyThrows; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class ReadUtilsTest { + + @Test + public void getInputStreamSupplier() + throws AmazonClientException, InterruptedException, IOException { + TransferManager transferManager = mock(TransferManager.class); + Download download = mock(Download.class); + + when(transferManager.download(anyString(), anyString(), any())).thenReturn(download); + + File file = Files.createTempFile("micro-s3", "test") + .toFile(); + assertTrue(file.exists()); + ReadUtils utils = new ReadUtils(transferManager, "test"); + + InputStream stream = utils.getInputStream("", "", () -> file); + assertNotNull(stream); + + assertFalse(file.exists()); + } + + @Test + public void getInputStreamDefaultSupplier() + throws AmazonClientException, InterruptedException, IOException { + TransferManager transferManager = mock(TransferManager.class); + Download download = mock(Download.class); + + when(transferManager.download(anyString(), anyString(), any())).thenReturn(download); + + ReadUtils utils = new ReadUtils(transferManager, System.getProperty("java.io.tmpdir")); + InputStream stream = utils.getInputStream("", ""); + assertNotNull(stream); + verify(download).waitForCompletion(); + } + + + @Test + @SneakyThrows + public void getFileInputStream() { + TransferManager transferManager = mock(TransferManager.class); + Download download = mock(Download.class); + when(transferManager.download(anyString(), anyString(), any())).thenReturn(download); + + ReadUtils readUtils = new ReadUtils(transferManager,System.getProperty("java.io.tmpdir")); + + InputStream fileInputStream = readUtils.getFileInputStream("bucket", "key"); + assertNotNull(fileInputStream); + + verify(transferManager, times(1)).download(anyString(), anyString(), any(File.class)); + verify(download, times(1)).waitForCompletion(); + + fileInputStream.close(); + } +} diff --git a/micro-s3/src/test/java/com/oath/micro/server/s3/S3RunnerTest.java b/micro-s3/src/test/java/com/oath/micro/server/s3/S3RunnerTest.java new file mode 100644 index 000000000..404edb4a6 --- /dev/null +++ b/micro-s3/src/test/java/com/oath/micro/server/s3/S3RunnerTest.java @@ -0,0 +1,61 @@ +package com.oath.micro.server.s3; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.transfer.TransferManager; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.s3.data.S3Utils; + +@Microserver(properties = { "s3.accessKey", "", "s3.secretKey", "" }) +public class S3RunnerTest { + + MicroserverApp server; + + @Before + public void startServer() { + + server = new MicroserverApp( + () -> "s3"); + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() { + + AmazonS3Client s3client = server.getSpringContext() + .getBean(AmazonS3Client.class); + assertThat(s3client != null, is(true)); + + S3Configuration s3Configuration = server.getSpringContext() + .getBean(S3Configuration.class); + assertThat(s3Configuration.getAccessKey(), is("")); + assertThat(s3Configuration.getSecretKey(), is("")); + assertThat(s3Configuration.getSessionToken() == null, is(true)); + assertThat(s3Configuration.getRegion() == null, is(true)); + assertThat(s3Configuration.getUploadThreads(), is(5)); + assertThat(s3Configuration.getUploadThreadNamePrefix(), is("s3-transfer-manager-worker-")); + + S3Utils s3Utils = server.getSpringContext() + .getBean(S3Utils.class); + assertThat(s3Utils != null, is(true)); + + TransferManager tm = server.getSpringContext() + .getBean(TransferManager.class); + assertThat(tm != null, is(true)); + + } + +} diff --git a/micro-s3/src/test/java/com/oath/micro/server/s3/S3UtilsTest.java b/micro-s3/src/test/java/com/oath/micro/server/s3/S3UtilsTest.java new file mode 100644 index 000000000..5bbe2b6e1 --- /dev/null +++ b/micro-s3/src/test/java/com/oath/micro/server/s3/S3UtilsTest.java @@ -0,0 +1,149 @@ +package com.oath.micro.server.s3; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import org.junit.Test; + +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.model.DeleteObjectsRequest.KeyVersion; +import com.amazonaws.services.s3.model.ListObjectsRequest; +import com.amazonaws.services.s3.model.ObjectListing; +import com.amazonaws.services.s3.model.S3ObjectSummary; +import com.oath.micro.server.s3.data.S3Utils; + +public class S3UtilsTest { + + private boolean answer = true; + + @Test + public void getAllSummaries() { + answer = true; + AmazonS3Client client = mock(AmazonS3Client.class); + ObjectListing objectListing = mock(ObjectListing.class); + when(client.listObjects(any(ListObjectsRequest.class))).thenReturn(objectListing); + when(objectListing.isTruncated()).thenAnswer(__ -> { + try { + return answer; + } finally { + answer = false; + } + }); + S3Utils utils = new S3Utils( + client, null, null, false, null); + utils.getAllSummaries(new ListObjectsRequest()); + verify(objectListing, times(2)).getObjectSummaries(); + } + + @Test + public void getSummariesStream() { + answer = true; + AmazonS3Client client = mock(AmazonS3Client.class); + + ObjectListing objectListing = mock(ObjectListing.class); + + when(objectListing.getObjectSummaries()).thenReturn(createSummaries()); + when(client.listObjects(any(ListObjectsRequest.class))).thenReturn(objectListing); + when(objectListing.isTruncated()).thenAnswer(__ -> { + try { + return answer; + } finally { + answer = false; + } + }); + // when(objectListing.getObjectSummaries()).thenReturn(summaries); + + S3Utils utils = new S3Utils( + client, null, null, false, null); + verify(objectListing, times(0)).getObjectSummaries(); + Stream stream = utils.getSummariesStream(new ListObjectsRequest(), s -> { + return s.getKey(); + }); + + assertEquals(500, stream.limit(500) + .count()); + + verify(objectListing, times(1)).getObjectSummaries(); + + } + + @Test + public void getSummariesStreamFull() { + answer = true; + AmazonS3Client client = mock(AmazonS3Client.class); + + ObjectListing objectListing = mock(ObjectListing.class); + + when(objectListing.getObjectSummaries()).thenReturn(createSummaries()); + when(client.listObjects(any(ListObjectsRequest.class))).thenReturn(objectListing); + when(objectListing.isTruncated()).thenAnswer(__ -> { + try { + return answer; + } finally { + answer = false; + } + }); + // when(objectListing.getObjectSummaries()).thenReturn(summaries); + + S3Utils utils = new S3Utils( + client, null, null, false, null); + verify(objectListing, times(0)).getObjectSummaries(); + Stream stream = utils.getSummariesStream(new ListObjectsRequest(), s -> { + return s.getKey(); + }); + + assertEquals(2000, stream.limit(2000) + .count()); + + } + + private List createSummaries() { + List summaries = new ArrayList<>(); + + for (int i = 0; i < 1000; i++) { + S3ObjectSummary summary = new S3ObjectSummary(); + summary.setKey("" + i); + summaries.add(summary); + } + + return summaries; + } + + @Test + public void deleteObjects() { + AmazonS3Client client = mock(AmazonS3Client.class); + S3Utils utils = new S3Utils( + client, null, null, false, null); + List keys = new ArrayList<>(); + for (int i = 0; i < 2000; i++) { + keys.add(new KeyVersion( + "")); + } + + utils.delete("", keys); + + verify(client, times(2)).deleteObjects(any()); + } + + @Test + public void emptyInputStream() throws IOException { + assertEquals(0, S3Utils.emptyInputStream() + .available()); + } + + @Test(expected = IOException.class) + public void emptyInputStreamException() throws IOException { + S3Utils.emptyInputStream() + .read(); + } + +} diff --git a/micro-s3/src/test/java/com/oath/micro/server/s3/data/S3DownloadSystemTest.java b/micro-s3/src/test/java/com/oath/micro/server/s3/data/S3DownloadSystemTest.java new file mode 100644 index 000000000..83b4de2a0 --- /dev/null +++ b/micro-s3/src/test/java/com/oath/micro/server/s3/data/S3DownloadSystemTest.java @@ -0,0 +1,120 @@ +package com.oath.micro.server.s3.data; + +import static org.coursera.metrics.datadog.DatadogReporter.Expansion.COUNT; +import static org.coursera.metrics.datadog.DatadogReporter.Expansion.MEAN; +import static org.coursera.metrics.datadog.DatadogReporter.Expansion.MEDIAN; +import static org.coursera.metrics.datadog.DatadogReporter.Expansion.P95; +import static org.coursera.metrics.datadog.DatadogReporter.Expansion.P99; +import static org.coursera.metrics.datadog.DatadogReporter.Expansion.RATE_15_MINUTE; +import static org.coursera.metrics.datadog.DatadogReporter.Expansion.RATE_1_MINUTE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import java.io.File; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.TimeUnit; + +import cyclops.control.Try; +import org.coursera.metrics.datadog.DatadogReporter; +import org.coursera.metrics.datadog.transport.HttpTransport; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.transfer.TransferManager; +import com.amazonaws.services.s3.transfer.model.UploadResult; + +import com.codahale.metrics.Histogram; +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.SharedMetricRegistries; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class S3DownloadSystemTest{ + private static final String BUCKET = System.getProperty("s3.bucket"); + + private static TransferManager manager; + private static File tmpDir; + private static Random r; + private static MetricRegistry metricsRegistry = SharedMetricRegistries.getOrCreate("default"); + private final Histogram downloadHist = getHistogram("com.oath.micro.server.s3.test.latency.download"); + + static { + manager = createManager(); + tmpDir = new File( + System.getProperty("java.io.tmpdir")); + r = new Random(); + + } + + private static Histogram getHistogram(String meterName) { + return metricsRegistry.histogram(MetricRegistry.name(S3DownloadSystemTest.class, meterName)); + } + + private static TransferManager createManager() { + AWSCredentials credentials = new AWSCredentials() { + + @Override + public String getAWSAccessKeyId() { + return System.getProperty("s3.accessKey"); + } + + @Override + public String getAWSSecretKey() { + return System.getProperty("s3.secretKey"); + } + + }; + return new TransferManager( + credentials); + } + + @BeforeClass + public static void setupMetrics() { + EnumSet expansions = EnumSet.of(COUNT, RATE_1_MINUTE, RATE_15_MINUTE, MEDIAN, MEAN, + P95, P99); + HttpTransport httpTransport = new HttpTransport.Builder().withApiKey(System.getProperty("datadog.key")) + .build(); + DatadogReporter.Builder builder = DatadogReporter.forRegistry(metricsRegistry) + .withTransport(httpTransport) + .withExpansions(expansions) + .withTags(Arrays.asList("stage:dev")); + DatadogReporter reporter = builder.build(); + int reportPeriod = 5; + TimeUnit reportUnit = TimeUnit.valueOf("SECONDS"); + log.info("Reporting to datadog every {} {}", reportPeriod, reportUnit); + reporter.start(reportPeriod, reportUnit); + } + + @Test + @Ignore + public void download(){ + S3ObjectWriter writerWithEncryption = buildWriterWithEncryption(true); + String name = "uploadWithEncryption" + r.nextLong(); + Try uploadWithEncryption = writerWithEncryption.putSync(name, "Microserver"); + assertTrue(uploadWithEncryption.isSuccess()); + + ExecutorService executorService = mock(ExecutorService.class); + S3Utils s3Utils = new S3Utils((AmazonS3Client) manager.getAmazonS3Client(), manager, tmpDir.getAbsolutePath(), true, executorService); + S3Reader s3Reader = s3Utils.reader(BUCKET); + long startD = System.currentTimeMillis(); + Try download = s3Reader.getAsObject(name); + long endD = System.currentTimeMillis(); + assertTrue(download.isSuccess()); + assertEquals("Microserver",download.orElse("")); + downloadHist.update(endD - startD); + } + + private S3ObjectWriter buildWriterWithEncryption(boolean aesEncryption) { + return new S3ObjectWriter( + manager, BUCKET, tmpDir, aesEncryption); + } + +} diff --git a/micro-s3/src/test/java/com/oath/micro/server/s3/data/S3UploadSystemTest.java b/micro-s3/src/test/java/com/oath/micro/server/s3/data/S3UploadSystemTest.java new file mode 100644 index 000000000..e4c574bc4 --- /dev/null +++ b/micro-s3/src/test/java/com/oath/micro/server/s3/data/S3UploadSystemTest.java @@ -0,0 +1,140 @@ +package com.oath.micro.server.s3.data; + +import static org.coursera.metrics.datadog.DatadogReporter.Expansion.*; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Optional; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +import cyclops.control.Try; +import cyclops.function.FluentFunctions; +import org.apache.commons.io.FileUtils; +import org.coursera.metrics.datadog.DatadogReporter; +import org.coursera.metrics.datadog.transport.HttpTransport; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; + +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.services.s3.transfer.TransferManager; +import com.amazonaws.services.s3.transfer.model.UploadResult; + +import com.codahale.metrics.Histogram; +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.SharedMetricRegistries; + +import lombok.extern.slf4j.Slf4j; +import repeat.Repeat; +import repeat.RepeatRule; + +@Slf4j +public class S3UploadSystemTest{ + private static final String BUCKET = System.getProperty("s3.bucket"); + private static final Optional nullableFile; + + private static TransferManager manager; + private static File tmpDir; + private static Random r; + private static MetricRegistry metricsRegistry = SharedMetricRegistries.getOrCreate("default"); + private final Histogram unencryptedHist = getHistogram("com.oath.micro.server.s3.test.latency.unencrypted"); + private final Histogram aes256Hist = getHistogram("com.oath.micro.server.s3.test.latency.aes256"); + + static { + nullableFile = createNullableFile(); + + assertTrue(nullableFile.isPresent()); + + manager = createManager(); + tmpDir = new File( + System.getProperty("java.io.tmpdir")); + r = new Random(); + + } + + private static Histogram getHistogram(String meterName) { + return metricsRegistry.histogram(MetricRegistry.name(S3UploadSystemTest.class, meterName)); + } + + private static Optional createNullableFile() { + final File file = new File( + System.getProperty("test.file.full.path")); + Try loadFileOperation = Try.success(1, Throwable.class) + .map(FluentFunctions.ofChecked(i -> { + return FileUtils.readFileToByteArray(file); + })); + loadFileOperation.onFail(e -> log.error(e.getMessage())); + Optional nFile = loadFileOperation.toOptional(); + + return nFile; + } + + private static TransferManager createManager() { + AWSCredentials credentials = new AWSCredentials() { + + @Override + public String getAWSAccessKeyId() { + return System.getProperty("s3.accessKey"); + } + + @Override + public String getAWSSecretKey() { + return System.getProperty("s3.secretKey"); + } + + }; + return new TransferManager( + credentials); + } + + @BeforeClass + public static void setupMetrics() { + EnumSet expansions = EnumSet.of(COUNT, RATE_1_MINUTE, RATE_15_MINUTE, MEDIAN, MEAN, + P95, P99); + HttpTransport httpTransport = new HttpTransport.Builder().withApiKey(System.getProperty("datadog.key")) + .build(); + DatadogReporter.Builder builder = DatadogReporter.forRegistry(metricsRegistry) + .withTransport(httpTransport) + .withExpansions(expansions) + .withTags(Arrays.asList("stage:dev")); + DatadogReporter reporter = builder.build(); + int reportPeriod = 5; + TimeUnit reportUnit = TimeUnit.valueOf("SECONDS"); + log.info("Reporting to datadog every {} {}", 5, reportUnit); + reporter.start(reportPeriod, reportUnit); + } + + @Rule + public RepeatRule rule = new RepeatRule(); + + @Test + @Ignore + @Repeat(times = 1, threads = 4) + public void upload() { + S3ObjectWriter writerWithoutEncryption = buildWriterWithEncryption(false); + long startNE = System.currentTimeMillis(); + Try uploadWithoutEncryption = writerWithoutEncryption.putSync("uploadWithoutEncryption" + r.nextLong(), nullableFile.get()); + long endNE = System.currentTimeMillis(); + assertTrue(uploadWithoutEncryption.isSuccess()); + unencryptedHist.update(endNE - startNE); + + S3ObjectWriter writerWithEncryption = buildWriterWithEncryption(true); + long startWE = System.currentTimeMillis(); + Try uploadWithEncryption = writerWithEncryption.putSync("uploadWithEncryption" + r.nextLong(), nullableFile.get()); + assertTrue(uploadWithEncryption.isSuccess()); + long endWE = System.currentTimeMillis(); + aes256Hist.update(endWE - startWE); + + + } + + private S3ObjectWriter buildWriterWithEncryption(boolean aesEncryption) { + return new S3ObjectWriter( + manager, BUCKET, tmpDir, aesEncryption); + } + +} diff --git a/micro-s3/src/test/java/com/oath/micro/server/s3/manifest/comparator/S3ManifestComparatorTest.java b/micro-s3/src/test/java/com/oath/micro/server/s3/manifest/comparator/S3ManifestComparatorTest.java new file mode 100644 index 000000000..14f6fc8d1 --- /dev/null +++ b/micro-s3/src/test/java/com/oath/micro/server/s3/manifest/comparator/S3ManifestComparatorTest.java @@ -0,0 +1,82 @@ +package com.oath.micro.server.s3.manifest.comparator; + + +import com.oath.micro.server.manifest.Data; +import com.oath.micro.server.manifest.VersionedKey; +import com.oath.micro.server.s3.data.S3Deleter; +import com.oath.micro.server.s3.data.S3ObjectWriter; +import com.oath.micro.server.s3.data.S3Reader; +import com.oath.micro.server.s3.data.S3StringWriter; +import cyclops.control.Try; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.util.Date; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class S3ManifestComparatorTest { + + @Mock + private S3Reader reader; + @Mock + private S3StringWriter stringWriter; + @Mock + private S3Deleter deleter; + @Mock + private S3ObjectWriter objectWriter; + + private String versionKey; + private Date lastModTime; + private Data expectedData; + + @Before + public void setup() { + lastModTime = new Date(); + setupExpectedData(lastModTime, "foobar", "data", 1L); + } + + private void setupExpectedData(Date lastModTime, String key, String data, long version) { + expectedData = new Data<>(data, lastModTime, versionKey); + versionKey = new VersionedKey(key, version).toJson(); + when(reader.getAsString(key)).thenReturn(Try.success(versionKey)); + when(reader.getAsObject(versionKey)).thenReturn(Try.success(expectedData)); + when(reader.getLastModified(versionKey)).thenReturn(lastModTime); + } + + @Test + public void loadInitial() throws Exception { + S3ManifestComparator comparator = new S3ManifestComparator<>("foobar", reader, objectWriter, deleter, stringWriter); + comparator.load(); + assertEquals("data", comparator.getData()); + verify(reader, times(1)).getAsObject(versionKey); + } + + @Test + public void loadUnchanged() throws Exception { + S3ManifestComparator comparator = new S3ManifestComparator<>("foobar", reader, objectWriter, deleter, stringWriter); + comparator.load(); + assertEquals("data", comparator.getData()); + comparator.load(); + assertEquals("data", comparator.getData()); + verify(reader, times(1)).getAsObject(versionKey); + } + + @Test + public void loadUpdated() throws Exception { + S3ManifestComparator comparator = new S3ManifestComparator<>("foobar", reader, objectWriter, deleter, stringWriter); + comparator.load(); + assertEquals("data", comparator.getData()); + setupExpectedData(new Date(), "foobar", "data2", 2L); + comparator.load(); + assertEquals("data2", comparator.getData()); + } + +} \ No newline at end of file diff --git a/micro-s3/src/test/java/com/oath/micro/server/s3/plugin/S3ClientProviderTest.java b/micro-s3/src/test/java/com/oath/micro/server/s3/plugin/S3ClientProviderTest.java new file mode 100644 index 000000000..19f22ac2f --- /dev/null +++ b/micro-s3/src/test/java/com/oath/micro/server/s3/plugin/S3ClientProviderTest.java @@ -0,0 +1,94 @@ +package com.oath.micro.server.s3.plugin; + +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.BasicSessionCredentials; +import com.amazonaws.services.s3.AmazonS3Client; +import com.oath.micro.server.s3.S3Configuration; +import lombok.SneakyThrows; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes=S3ClientProvider.class, loader = AnnotationConfigContextLoader.class) +@TestPropertySource(properties = { + "s3.accessKey=", + "s3.secretKey=" +}) +public class S3ClientProviderTest { + + @Autowired + ApplicationContext ctx; + + @Test + @SneakyThrows + public void getClient() { + AmazonS3Client client = ctx.getBean(AmazonS3Client.class); + assertNotNull(client); + } + + @Test + public void defaultChain() { + S3ClientProvider provider = new S3ClientProvider(); + S3Configuration s3Configuration = new S3Configuration(null, + null, + true, + null, + null, + 5, + "s3-transfer-manager-worker-", + 100); + ReflectionTestUtils.setField(provider, "s3Configuration", s3Configuration); + // system properties used here as they're the easiest to test + // but it can also pull them from the metadata service on ec2 + System.setProperty("aws.accessKeyId", "fakeKeyId"); + System.setProperty("aws.secretKey", "fakeSecretKey"); + AWSCredentials credentials = provider.getAwsCredentials(); + assertEquals("fakeKeyId", credentials.getAWSAccessKeyId()); + assertEquals("fakeSecretKey", credentials.getAWSSecretKey()); + } + + @Test + public void accessKey() { + S3ClientProvider provider = new S3ClientProvider(); + S3Configuration s3Configuration = new S3Configuration("fakeProvidedKeyId", + "fakeProvidedSecretKey", + false, + null, + null, + 5, + "s3-transfer-manager-worker-", + 100); + ReflectionTestUtils.setField(provider, "s3Configuration", s3Configuration); + AWSCredentials credentials = provider.getAwsCredentials(); + assertEquals("fakeProvidedKeyId", credentials.getAWSAccessKeyId()); + assertEquals("fakeProvidedSecretKey", credentials.getAWSSecretKey()); + } + + @Test + public void sessionToken() { + S3ClientProvider provider = new S3ClientProvider(); + S3Configuration s3Configuration = new S3Configuration("fakeProvidedKeyId", + "fakeProvidedSecretKey", + false, + "fakeProvidedSessionToken", + null, + 5, + "s3-transfer-manager-worker-", + 100); + ReflectionTestUtils.setField(provider, "s3Configuration", s3Configuration); + BasicSessionCredentials credentials = (BasicSessionCredentials) provider.getAwsCredentials(); + assertEquals("fakeProvidedKeyId", credentials.getAWSAccessKeyId()); + assertEquals("fakeProvidedSecretKey", credentials.getAWSSecretKey()); + assertEquals("fakeProvidedSessionToken", credentials.getSessionToken()); + } +} \ No newline at end of file diff --git a/micro-s3/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-s3/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-s3/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-spring-boot/README.md b/micro-spring-boot/README.md new file mode 100644 index 000000000..36775823c --- /dev/null +++ b/micro-spring-boot/README.md @@ -0,0 +1,110 @@ +# Spring Boot entry point for Microserver + +[micro-spring-boot example apps](https://github.com/aol/micro-server/tree/master/micro-spring-boot/src/test/java/app) + +Micro-spring-boot allows Microserver Jersey annotations and Microserver plugins to be used on applications where the full-stack is managed by Spring Boot. To use Microserver front-ends and Spring Boot backends see the micro-boot plugin. + + +## A simple example with one resource + +* Annotate your classes with @Microboot to let Spring Boot know the base package for auto-scanning Spring beans. + +* Create a MicroserverApp and run. + +* You can now use the @Microserver annotation for configuration (except for base auto-scan packages) + + +```java + +@MicroSpringBoot //configure this package as the base for autoscan +//optionally use @Microserver here for more configuration options +public class SimpleExample { + + RestClient rest = new RestClient(10_000,1_000); + + + public static void main (String[] args){ + + new MicroserverApp(()-> "simple-app"); //note unlike traditional microserver apps, there is no need to call start or run here + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),equalTo("ok")); + + } + + + +} +@Rest +@Path("/status") +public class SimpleResource{ + + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + return "ok"; + } + + +} +``` + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-boot/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-boot) + +Add micro-spring-boot to the classpath + +Maven + + + com.oath.microservices + micro-spring-boot + x.yz + + +Gradle + + compile 'com.oath.microservices:micro-spring-boot:x.yz' + + + +## Create a simple server + +```java + +@MicroSpringBoot +@Path("/simple") +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()->"test-app"); + } + + @GET + public String ping() { + return "ok"; + } +} + +``` + + +@MicroSpringBoot is simply syntax sugar for + + ```java + +@Component +@SpringBootApplication(exclude = SpringDataWebAutoConfiguration.class) + ``` + +You can also define your own SpringBoot configuration if required. + +## A note on overriding Module properties + +1. micro-spring-boot currently only uses the context provided in the Module passed to MicroserverApp, all other properties aren't used at that stage. +2. To pass a Module with overrides into micro-spring-boot, you need to make the Module a Spring Bean. The easiest way to do this is have your main class implement Module and override getContext(), then pass an instance to MicroserverApp +3. See https://github.com/aol/micro-server/blob/master/micro-spring-boot/src/test/java/app/swagger/com/aol/micro/server/SwaggerRunnerTest.java for an example diff --git a/micro-spring-boot/build.gradle b/micro-spring-boot/build.gradle index ef29dc2ed..8d4ff79f6 100644 --- a/micro-spring-boot/build.gradle +++ b/micro-spring-boot/build.gradle @@ -1,99 +1,99 @@ description = 'micro-spring-boot' + dependencies { - - - compile 'org.springframework.boot:spring-boot:'+springBootVersion - compile 'org.springframework.boot:spring-boot-autoconfigure:'+springBootVersion - compile project(':micro-core') - compile group: 'org.glassfish.jersey.core', name: 'jersey-server', version:"$jerseyVersion" - compile(group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version:"$jerseyVersion") { - exclude(module: 'jackson-xc') - exclude(module: 'jackson-core-asl') - exclude(module: 'jackson-jaxrs') - exclude(module: 'jackson-mapper-asl') - } - compile group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version:"$jerseyVersion" - - compile "org.glassfish.jersey.media:jersey-media-multipart:$jerseyVersion" - compile "org.glassfish.jersey.ext:jersey-spring3:$jerseyVersion" - compile "org.glassfish.jersey.ext:jersey-bean-validation:$jerseyVersion" - compile project(':micro-jackson-configuration') - - testCompile 'org.springframework.boot:spring-boot-starter-test:'+springBootVersion - testCompile group: 'org.glassfish.jersey.core', name: 'jersey-client', version:"$jerseyVersion" - - - - testCompile 'org.apache.tomcat.embed:tomcat-embed-core:'+tomcatVersion - testCompile 'org.apache.tomcat.embed:tomcat-embed-logging-juli:'+tomcatVersion - - testCompile project(':micro-cors') - testCompile project(':micro-swagger') - testCompile project(':micro-client') - testCompile project(':micro-events') - testCompile project(':micro-metrics') + compile 'org.springframework.boot:spring-boot:' + springBootVersion + compile 'org.springframework.boot:spring-boot-autoconfigure:' + springBootVersion + compile project(':micro-core') + + compile group: 'org.glassfish.jersey.core', name: 'jersey-server', version: "$jerseyVersion" + compile(group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: "$jerseyVersion") { + exclude(module: 'jackson-xc') + exclude(module: 'jackson-core-asl') + exclude(module: 'jackson-jaxrs') + exclude(module: 'jackson-mapper-asl') + } + compile group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version: "$jerseyVersion" + + compile "org.glassfish.jersey.media:jersey-media-multipart:$jerseyVersion" + compile "org.glassfish.jersey.ext:jersey-spring4:$jerseyVersion" + compile "org.glassfish.jersey.ext:jersey-bean-validation:$jerseyVersion" + compile project(':micro-jackson-configuration') + testCompile("org.springframework.boot:spring-boot-starter-web:"+ springBootVersion) + testCompile 'org.springframework.boot:spring-boot-starter-test:' + springBootVersion + testCompile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: "$jerseyVersion" + testCompile 'org.apache.tomcat.embed:tomcat-embed-core:' + tomcatVersion + + testCompile project(':micro-cors') + testCompile project(':micro-swagger') + testCompile project(':micro-client') + testCompile project(':micro-events') + testCompile project(':micro-metrics') + testCompile project(':micro-guava') + + testCompile "com.oath.cyclops:cyclops-futurestream:$cyclopsVersion" } + test { - forkEvery = 1 + forkEvery = 1 } modifyPom { - project { - name 'Microserver-spring-boot' - description 'Opinionated rest microservices with Spring Boot' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-spring-boot' - version "$version" - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'earlzero' - name 'Nikita Sapozhnikov' - email 'nikita.sapozhnikov@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - - } - } + project { + name 'Microserver-spring-boot' + description 'Opinionated rest microservices with Spring Boot' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-spring-boot' + version "$version" + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + + } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-spring-boot/readme.md b/micro-spring-boot/readme.md deleted file mode 100644 index a51ec4ba4..000000000 --- a/micro-spring-boot/readme.md +++ /dev/null @@ -1,110 +0,0 @@ -# Spring Boot entry point for Microserver - -[micro-spring-boot example apps](https://github.com/aol/micro-server/tree/master/micro-spring-boot/src/test/java/app) - -Micro-spring-boot allows Microserver Jersey annotations and Microserver plugins to be used on applications where the full-stack is managed by Spring Boot. To use Microserver front-ends and Spring Boot backends see the micro-boot plugin. - - -## A simple example with one resource - -* Annotate your classes with @Microboot to let Spring Boot know the base package for auto-scanning Spring beans. - -* Create a MicroserverApp and run. - -* You can now use the @Microserver annotation for configuration (except for base auto-scan packages) - - -```java - -@MicroSpringBoot //configure this package as the base for autoscan -//optionally use @Microserver here for more configuration options -public class SimpleExample { - - RestClient rest = new RestClient(10_000,1_000); - - - public static void main (String[] args){ - - new MicroserverApp(()-> "simple-app"); //note unlike traditional microserver apps, there is no need to call start or run here - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),equalTo("ok")); - - } - - - -} -@Rest -@Path("/status") -public class SimpleResource{ - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return "ok"; - } - - -} -``` - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-boot/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-boot) - -Add micro-spring-boot to the classpath - -Maven - - - com.aol.microservices - micro-spring-boot - x.yz - - -Gradle - - compile 'com.aol.microservices:micro-spring-boot:x.yz' - - - -## Create a simple server - -```java - -@MicroSpringBoot -@Path("/simple") -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()->"test-app"); - } - - @GET - public String ping() { - return "ok"; - } -} - -``` - - -@MicroSpringBoot is simply syntax sugar for - - ```java - -@Component -@SpringBootApplication(exclude = SpringDataWebAutoConfiguration.class) - ``` - -You can also define your own SpringBoot configuration if required. - -## A note on overriding Module properties - -1. micro-spring-boot currently only uses the context provided in the Module passed to MicroserverApp, all other properties aren't used at that stage. -2. To pass a Module with overrides into micro-spring-boot, you need to make the Module a Spring Bean. The easiest way to do this is have your main class implement Module and override getContext(), then pass an instance to MicroserverApp -3. See https://github.com/aol/micro-server/blob/master/micro-spring-boot/src/test/java/app/swagger/com/aol/micro/server/SwaggerRunnerTest.java for an example diff --git a/micro-spring-boot/src/main/java/com/aol/micro/server/rest/jersey/SpringBootJerseyRestApplication.java b/micro-spring-boot/src/main/java/com/aol/micro/server/rest/jersey/SpringBootJerseyRestApplication.java deleted file mode 100644 index 4865a6b48..000000000 --- a/micro-spring-boot/src/main/java/com/aol/micro/server/rest/jersey/SpringBootJerseyRestApplication.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.aol.micro.server.rest.jersey; - -import java.util.List; -import java.util.Map; - -import org.glassfish.hk2.utilities.binding.AbstractBinder; -import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.server.ServerProperties; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; - -import com.aol.micro.server.GlobalState; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.module.JaxRsProvider; -import com.aol.micro.server.module.Module; -import com.aol.micro.server.module.ModuleDataExtractor; - -public class SpringBootJerseyRestApplication extends ResourceConfig { - - @Autowired(required=false) - public SpringBootJerseyRestApplication(ApplicationContext context){ - this(context, GlobalState.state.getModules().firstValue()); - } - - @Autowired(required=false) - public SpringBootJerseyRestApplication(ApplicationContext context,Module module){ - ModuleDataExtractor extractor = new ModuleDataExtractor(module); - - List allResources = extractor.getRestResources(context); - - System.out.println("Resources " + allResources); - Map serverProperties = module.getServerProperties(); - if (allResources != null) { - for (Object next : allResources) { - if(isSingleton(next)) - register(next); - else - register(next.getClass()); - } - } - - if (serverProperties.isEmpty()) { - property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true); - //http://stackoverflow.com/questions/25755773/bean-validation-400-errors-are-returning-default-error-page-html-instead-of-re - property(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, "true"); - } else { - for (Map.Entry entry : serverProperties.entrySet()) { - property(entry.getKey(), entry.getValue()); - } - } - - context.getBeansOfType(AbstractBinder.class).forEach((n,e)->register(e)); - - - module.getDefaultJaxRsPackages().stream().forEach( e -> packages(e)); - module.getDefaultResources().stream().forEach( e -> register(e)); - - - module.getResourceConfigManager().accept(new JaxRsProvider<>(this)); - } - - - private boolean isSingleton(Object next) { - if(next instanceof RestResource) - return ((RestResource)next).isSingleton(); - Rest rest = next.getClass().getAnnotation(Rest.class); - if(rest == null) - return !(next instanceof Class); - return rest.isSingleton(); - } - - - - -} diff --git a/micro-spring-boot/src/main/java/com/aol/micro/server/spring/boot/BootFrontEndApplicationConfigurator.java b/micro-spring-boot/src/main/java/com/aol/micro/server/spring/boot/BootFrontEndApplicationConfigurator.java deleted file mode 100644 index 16a6a4714..000000000 --- a/micro-spring-boot/src/main/java/com/aol/micro/server/spring/boot/BootFrontEndApplicationConfigurator.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.aol.micro.server.spring.boot; - - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletException; -import javax.servlet.ServletRequestListener; - -import org.pcollections.PStack; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.embedded.ServletContextInitializer; -import org.springframework.boot.context.web.SpringBootServletInitializer; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.stereotype.Component; -import org.springframework.web.context.ContextLoader; - -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.module.Environment; -import com.aol.micro.server.module.Module; -import com.aol.micro.server.module.ModuleDataExtractor; -import com.aol.micro.server.servers.FilterConfigurer; -import com.aol.micro.server.servers.ServletConfigurer; -import com.aol.micro.server.servers.ServletContextListenerConfigurer; -import com.aol.micro.server.servers.model.FilterData; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.servers.model.ServletData; -import com.aol.micro.server.spring.SpringBuilder; - -public class BootFrontEndApplicationConfigurator extends SpringBootServletInitializer implements SpringBuilder { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public ConfigurableApplicationContext createSpringApp(Config config, Class...classes) { - - - List classList = new ArrayList(); - classList.addAll(Arrays.asList(classes)); - classList.add(JerseySpringBootFrontEndApplication.class); - classList.add(MyWebAppInitializer.class); - SpringApplicationBuilder builder = new SpringApplicationBuilder(classList.toArray(new Class[0])); - - new JerseySpringBootFrontEndApplication(classList).config(builder); - - - return builder.application().run(); - } - - @Component - static class MyWebAppInitializer implements ServletContextInitializer{ - - private final Environment environment; - private final Module module; - private final ApplicationContext rootContext; - @Autowired(required=false) - public MyWebAppInitializer(Environment env,ApplicationContext rootContext,Module m){ - this.environment = env; - this.rootContext = rootContext; - this.module = m; - } - @Autowired(required=false) - public MyWebAppInitializer(Environment env,ApplicationContext rootContext){ - this(env,rootContext,()->""); - } - - @Override - public void onStartup(ServletContext webappContext) throws ServletException { - - ModuleDataExtractor extractor = new ModuleDataExtractor(module); - environment.assureModule(module); - String fullRestResource = "/" + module.getContext() + "/*"; - - ServerData serverData = new ServerData(environment.getModuleBean(module).getPort(), - Arrays.asList(), - rootContext, fullRestResource, module); - List filterDataList = extractor.createFilteredDataList(serverData); - List servletDataList = extractor.createServletDataList(serverData); - new ServletConfigurer(serverData, PStackX.fromIterable(servletDataList)).addServlets(webappContext); - - new FilterConfigurer(serverData, PStackX.fromIterable(filterDataList)).addFilters(webappContext); - PStack servletContextListenerData = PStackX.fromCollection(module.getListeners(serverData)).filter(i->!(i instanceof ContextLoader)); - PStack servletRequestListenerData = PStackX.fromCollection(module.getRequestListeners(serverData)); - - new ServletContextListenerConfigurer(serverData, servletContextListenerData, servletRequestListenerData).addListeners(webappContext); - - } - - } - - -} diff --git a/micro-spring-boot/src/main/java/com/aol/micro/server/spring/boot/BootPlugin.java b/micro-spring-boot/src/main/java/com/aol/micro/server/spring/boot/BootPlugin.java deleted file mode 100644 index 8dbebaa06..000000000 --- a/micro-spring-boot/src/main/java/com/aol/micro/server/spring/boot/BootPlugin.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.aol.micro.server.spring.boot; - -import java.util.Map; -import java.util.function.Function; - -import javax.ws.rs.core.FeatureContext; - -import org.glassfish.jersey.CommonProperties; - -import com.aol.cyclops.data.collections.extensions.persistent.PMapX; -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.cyclops.data.collections.extensions.standard.MapXs; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.rest.jersey.SpringBootJerseyRestApplication; -import com.aol.micro.server.spring.SpringBuilder; - -/** - * - * @author johnmcclean - * - */ -public class BootPlugin implements Plugin{ - - - /** - * @return Engine for building Spring Context - */ - public SpringBuilder springBuilder(){ - return new BootFrontEndApplicationConfigurator(); - } - - @Override - public PSetX springClasses() { - return PSetX.of(SpringBootJerseyRestApplication.class); - } - - - @Override - public Function> jacksonFeatureProperties(){ - return context->PMapX.fromMap(MapXs.of( CommonProperties.MOXY_JSON_FEATURE_DISABLE + '.' - + context.getConfiguration().getRuntimeType().name().toLowerCase(),true)); - } - - - - -} diff --git a/micro-spring-boot/src/main/java/com/aol/micro/server/spring/boot/JerseySpringBootFrontEndApplication.java b/micro-spring-boot/src/main/java/com/aol/micro/server/spring/boot/JerseySpringBootFrontEndApplication.java deleted file mode 100644 index 9f65adbf3..000000000 --- a/micro-spring-boot/src/main/java/com/aol/micro/server/spring/boot/JerseySpringBootFrontEndApplication.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.aol.micro.server.spring.boot; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.Properties; - -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.web.SpringBootServletInitializer; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; - -import com.aol.micro.server.module.Environment; -import com.aol.micro.server.servers.AccessLogLocationBean; -import com.aol.micro.server.spring.properties.PropertyFileConfig; - - -@Configuration -@PropertySource("classpath:spring-boot-microserver.properties") -public class JerseySpringBootFrontEndApplication extends SpringBootServletInitializer { - - List classes; - - public JerseySpringBootFrontEndApplication(){ - classes = new ArrayList<>(); - } - - public JerseySpringBootFrontEndApplication(List classes2) { - classes = new ArrayList<>(); - classes.addAll(classes2); - classes.add(JerseySpringBootFrontEndApplication.class); - classes.add(PropertyFileConfig.class); - classes.add(Environment.class); - classes.add(AccessLogLocationBean.class); - } - - - @Override - protected SpringApplicationBuilder configure( - SpringApplicationBuilder application) { - - return application.sources(classes.toArray(new Class[0])); - } - - public SpringApplicationBuilder config(SpringApplicationBuilder builder) { - return configure(builder); - - } - - @Bean - public AccessLogLocationBean createAccessLogLocationBean( - ApplicationContext rootContext) { - Properties props = (Properties) rootContext.getBean("propertyFactory"); - String location = Optional.ofNullable( - (String) props.get("access.log.output")).orElse("./logs/"); - return new AccessLogLocationBean(location); - } - - - - - - - -} diff --git a/micro-spring-boot/src/main/java/com/oath/micro/server/rest/jersey/SpringBootJerseyRestApplication.java b/micro-spring-boot/src/main/java/com/oath/micro/server/rest/jersey/SpringBootJerseyRestApplication.java new file mode 100644 index 000000000..c73694cf7 --- /dev/null +++ b/micro-spring-boot/src/main/java/com/oath/micro/server/rest/jersey/SpringBootJerseyRestApplication.java @@ -0,0 +1,83 @@ +package com.oath.micro.server.rest.jersey; + +import java.util.Map; + +import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import cyclops.reactive.collections.immutable.LinkedListX; +import org.glassfish.hk2.utilities.binding.AbstractBinder; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.ServerProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; + +import com.oath.micro.server.GlobalState; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.module.JaxRsProvider; +import com.oath.micro.server.module.Module; +import com.oath.micro.server.module.ModuleDataExtractor; + +import javax.ws.rs.ext.Provider; + +public class SpringBootJerseyRestApplication extends ResourceConfig { + + @Autowired(required=false) + public SpringBootJerseyRestApplication(ApplicationContext context){ + this(context, GlobalState.state.getModules().firstValue(null)); + } + + @Autowired(required=false) + public SpringBootJerseyRestApplication(ApplicationContext context,Module module){ + ModuleDataExtractor extractor = new ModuleDataExtractor(module); + + LinkedListX allResources = extractor.getRestResources(context); + + System.out.println("Resources " + allResources); + Map serverProperties = module.getServerProperties(); + if (allResources != null) { + for (Object next : allResources) { + if(isSingleton(next)) + register(next); + else + register(next.getClass()); + } + } + + if (serverProperties.isEmpty()) { + property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true); + //http://stackoverflow.com/questions/25755773/bean-validation-400-errors-are-returning-default-error-page-html-instead-of-re + property(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, "true"); + } else { + for (Map.Entry entry : serverProperties.entrySet()) { + property(entry.getKey(), entry.getValue()); + } + } + + + context.getBeansOfType(AbstractBinder.class).forEach((n,e)->register(e)); + + JacksonJaxbJsonProvider p = new JacksonJaxbJsonProvider(); + p.setMapper(JacksonUtil.getMapper()); + register(p); + module.getDefaultJaxRsPackages().stream().forEach( e -> packages(e)); + module.getDefaultResources().stream().forEach( e -> register(e)); + + + module.getResourceConfigManager().accept(new JaxRsProvider<>(this)); + } + + + private boolean isSingleton(Object next) { + if(next instanceof RestResource) + return ((RestResource)next).isSingleton(); + Rest rest = next.getClass().getAnnotation(Rest.class); + if(rest == null) + return !(next instanceof Class); + return rest.isSingleton(); + } + + + + +} diff --git a/micro-spring-boot/src/main/java/com/oath/micro/server/spring/boot/BootFrontEndApplicationConfigurator.java b/micro-spring-boot/src/main/java/com/oath/micro/server/spring/boot/BootFrontEndApplicationConfigurator.java new file mode 100644 index 000000000..a93c987e2 --- /dev/null +++ b/micro-spring-boot/src/main/java/com/oath/micro/server/spring/boot/BootFrontEndApplicationConfigurator.java @@ -0,0 +1,117 @@ +package com.oath.micro.server.spring.boot; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletException; +import javax.servlet.ServletRequestListener; + +import com.oath.cyclops.types.persistent.PersistentList; +import com.oath.micro.server.GlobalState; +import com.oath.micro.server.module.MicroserverEnvironment; +import cyclops.reactive.ReactiveSeq; +import cyclops.reactive.collections.immutable.LinkedListX; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.builder.SpringApplicationBuilder; + +import org.springframework.boot.web.servlet.ServletContextInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.stereotype.Component; +import org.springframework.web.context.ContextLoader; + + +import com.oath.micro.server.config.Config; +import com.oath.micro.server.module.Module; +import com.oath.micro.server.module.ModuleDataExtractor; +import com.oath.micro.server.servers.FilterConfigurer; +import com.oath.micro.server.servers.ServletConfigurer; +import com.oath.micro.server.servers.ServletContextListenerConfigurer; +import com.oath.micro.server.servers.model.FilterData; +import com.oath.micro.server.servers.model.ServerData; +import com.oath.micro.server.servers.model.ServletData; +import com.oath.micro.server.spring.SpringBuilder; + +public class BootFrontEndApplicationConfigurator extends SpringBootServletInitializer implements SpringBuilder { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public ConfigurableApplicationContext createSpringApp(Config config, Class...classes) { + + + List classList = new ArrayList(); + classList.addAll(Arrays.asList(classes)); + classList.add(JerseySpringBootFrontEndApplication.class); + classList.add(MyWebAppInitializer.class); + + SpringApplicationBuilder builder = new SpringApplicationBuilder(classList.toArray(new Class[0])); + + new JerseySpringBootFrontEndApplication(classList).config(builder); + + + + return builder.application().run(); + } + + @Override + public Class[] classes(Config config, Class... classes) { + List classList = new ArrayList(); + classList.addAll(Arrays.asList(classes)); + classList.add(JerseySpringBootFrontEndApplication.class); + classList.add(MyWebAppInitializer.class); + + return ReactiveSeq.fromIterable(new JerseySpringBootFrontEndApplication(classList).classes).appendAll(classList) + .toArray(i->new Class[i]); + + } + + @Component + static class MyWebAppInitializer implements ServletContextInitializer { + + private final MicroserverEnvironment microserverEnvironment; + private final Module module; + private final ApplicationContext rootContext; + @Autowired(required=false) + public MyWebAppInitializer(MicroserverEnvironment env, ApplicationContext rootContext, Module m){ + this.microserverEnvironment = env; + this.rootContext = rootContext; + this.module = m; + } + @Autowired(required=false) + public MyWebAppInitializer(MicroserverEnvironment env, ApplicationContext rootContext){ + this(env,rootContext, GlobalState.state.getModules().firstValue(null)); + } + + @Override + public void onStartup(ServletContext webappContext) throws ServletException { + + ModuleDataExtractor extractor = new ModuleDataExtractor(module); + microserverEnvironment.assureModule(module); + String fullRestResource = "/" + module.getContext() + "/*"; + + ServerData serverData = new ServerData(microserverEnvironment.getModuleBean(module).getPort(), + Arrays.asList(), + rootContext, fullRestResource, module); + List filterDataList = extractor.createFilteredDataList(serverData); + List servletDataList = extractor.createServletDataList(serverData); + new ServletConfigurer(serverData, LinkedListX.fromIterable(servletDataList)).addServlets(webappContext); + + new FilterConfigurer(serverData, LinkedListX.fromIterable(filterDataList)).addFilters(webappContext); + PersistentList servletContextListenerData = LinkedListX.fromIterable(module.getListeners(serverData)).filter(i->!(i instanceof ContextLoader)); + PersistentList servletRequestListenerData = LinkedListX.fromIterable(module.getRequestListeners(serverData)); + + new ServletContextListenerConfigurer(serverData, servletContextListenerData, servletRequestListenerData).addListeners(webappContext); + + } + + } + + +} diff --git a/micro-spring-boot/src/main/java/com/oath/micro/server/spring/boot/BootPlugin.java b/micro-spring-boot/src/main/java/com/oath/micro/server/spring/boot/BootPlugin.java new file mode 100644 index 000000000..f093199a3 --- /dev/null +++ b/micro-spring-boot/src/main/java/com/oath/micro/server/spring/boot/BootPlugin.java @@ -0,0 +1,49 @@ +package com.oath.micro.server.spring.boot; + +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + +import javax.ws.rs.core.FeatureContext; + +import cyclops.reactive.collections.mutable.MapX; +import cyclops.reactive.collections.mutable.SetX; +import cyclops.reactive.companion.MapXs; +import org.glassfish.jersey.CommonProperties; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.rest.jersey.SpringBootJerseyRestApplication; +import com.oath.micro.server.spring.SpringBuilder; + +/** + * + * @author johnmcclean + * + */ +public class BootPlugin implements Plugin{ + + + /** + * @return Engine for building Spring Context + */ + public SpringBuilder springBuilder(){ + return new BootFrontEndApplicationConfigurator(); + } + + @Override + public Set springClasses() { + return SetX.of(SpringBootJerseyRestApplication.class); + } + + + @Override + public Function> jacksonFeatureProperties(){ + return context-> MapX.fromMap(MapXs.of( CommonProperties.MOXY_JSON_FEATURE_DISABLE + '.' + + context.getConfiguration().getRuntimeType().name().toLowerCase(),true)); + } + + + + +} diff --git a/micro-spring-boot/src/main/java/com/oath/micro/server/spring/boot/JerseySpringBootFrontEndApplication.java b/micro-spring-boot/src/main/java/com/oath/micro/server/spring/boot/JerseySpringBootFrontEndApplication.java new file mode 100644 index 000000000..c3dbc9a1f --- /dev/null +++ b/micro-spring-boot/src/main/java/com/oath/micro/server/spring/boot/JerseySpringBootFrontEndApplication.java @@ -0,0 +1,67 @@ +package com.oath.micro.server.spring.boot; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Properties; + +import com.oath.micro.server.servers.AccessLogLocationBean; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +import com.oath.micro.server.module.MicroserverEnvironment; +import com.oath.micro.server.spring.properties.PropertyFileConfig; + + +@Configuration +@PropertySource("classpath:spring-boot-microserver.properties") +public class JerseySpringBootFrontEndApplication extends SpringBootServletInitializer { + + public List classes; + + public JerseySpringBootFrontEndApplication(){ + classes = new ArrayList<>(); + } + + public JerseySpringBootFrontEndApplication(List classes2) { + classes = new ArrayList<>(); + classes.addAll(classes2); + classes.add(JerseySpringBootFrontEndApplication.class); + classes.add(PropertyFileConfig.class); + classes.add(MicroserverEnvironment.class); + classes.add(AccessLogLocationBean.class); + } + + + @Override + protected SpringApplicationBuilder configure( + SpringApplicationBuilder application) { + + return application.sources(classes.toArray(new Class[0])); + } + + public SpringApplicationBuilder config(SpringApplicationBuilder builder) { + return configure(builder); + + } + + @Bean + public AccessLogLocationBean createAccessLogLocationBean( + ApplicationContext rootContext) { + Properties props = (Properties) rootContext.getBean("propertyFactory"); + String location = Optional.ofNullable( + (String) props.get("access.log.output")).orElse("./logs/"); + return new AccessLogLocationBean(location); + } + + + + + + + +} diff --git a/micro-spring-boot/src/main/java/com/aol/micro/server/spring/boot/MicroSpringBoot.java b/micro-spring-boot/src/main/java/com/oath/micro/server/spring/boot/MicroSpringBoot.java similarity index 92% rename from micro-spring-boot/src/main/java/com/aol/micro/server/spring/boot/MicroSpringBoot.java rename to micro-spring-boot/src/main/java/com/oath/micro/server/spring/boot/MicroSpringBoot.java index b9b916860..636ddcc04 100644 --- a/micro-spring-boot/src/main/java/com/aol/micro/server/spring/boot/MicroSpringBoot.java +++ b/micro-spring-boot/src/main/java/com/oath/micro/server/spring/boot/MicroSpringBoot.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.spring.boot; +package com.oath.micro.server.spring.boot; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/micro-spring-boot/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-spring-boot/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 3e9503978..000000000 --- a/micro-spring-boot/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.spring.boot.BootPlugin \ No newline at end of file diff --git a/micro-spring-boot/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-spring-boot/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..e726bf190 --- /dev/null +++ b/micro-spring-boot/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.spring.boot.BootPlugin \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/boot/com/aol/micro/server/AsyncAppRunner.java b/micro-spring-boot/src/test/java/app/boot/com/aol/micro/server/AsyncAppRunner.java deleted file mode 100644 index eb720cb1b..000000000 --- a/micro-spring-boot/src/test/java/app/boot/com/aol/micro/server/AsyncAppRunner.java +++ /dev/null @@ -1,38 +0,0 @@ -package app.boot.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; - -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.spring.boot.MicroSpringBoot; - -@Microserver @MicroSpringBoot -public class AsyncAppRunner { - - - AsyncRestClient rest = new AsyncRestClient(1000,1000).withAccept("text/plain"); - - - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - new MicroserverApp( ()-> "async-app"); - Thread.sleep(2000); - - assertThat(rest.get("http://localhost:8080/async-app/async/expensive").get(),is(";test!;test!;test!")); - - } - - - -} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/boot/com/aol/micro/server/AsyncResource.java b/micro-spring-boot/src/test/java/app/boot/com/aol/micro/server/AsyncResource.java deleted file mode 100644 index 56d3c4af5..000000000 --- a/micro-spring-boot/src/test/java/app/boot/com/aol/micro/server/AsyncResource.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.boot.com.aol.micro.server; - -import java.util.List; -import java.util.concurrent.CompletableFuture; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.container.Suspended; - -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.google.common.collect.ImmutableList; - -@Path("/async") -@Component -public class AsyncResource implements RestResource{ - - private final SimpleReact simpleReact =new SimpleReact(); - private final ImmutableList urls = ImmutableList.of("http://localhost:8080/async-app/async/ping2", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping"); - - private final AsyncRestClient client = new AsyncRestClient(1000,1000).withAccept("text/plain"); - - @GET - @Path("/expensive") - @Produces("text/plain") - public void expensive(@Suspended AsyncResponse asyncResponse){ - - simpleReact.fromStream(urls.stream() - .>map(it -> client.get(it))) - .onFail(it -> "") - .peek(it -> - System.out.println(it)) - .allOf(data -> { - System.out.println(data); - return asyncResponse.resume(String.join(";", (List)data)); }); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - -} diff --git a/micro-spring-boot/src/test/java/app/boot/com/aol/micro/server/SimpleApp.java b/micro-spring-boot/src/test/java/app/boot/com/aol/micro/server/SimpleApp.java deleted file mode 100644 index 41cdbc63e..000000000 --- a/micro-spring-boot/src/test/java/app/boot/com/aol/micro/server/SimpleApp.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.boot.com.aol.micro.server; - -import com.aol.micro.server.MicroserverApp; - - -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()->"test-app").run(); - } - -} diff --git a/micro-spring-boot/src/test/java/app/boot/com/oath/micro/server/AsyncAppRunner.java b/micro-spring-boot/src/test/java/app/boot/com/oath/micro/server/AsyncAppRunner.java new file mode 100644 index 000000000..9e6cd7950 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/boot/com/oath/micro/server/AsyncAppRunner.java @@ -0,0 +1,36 @@ +package app.boot.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; + +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.spring.boot.MicroSpringBoot; + +@Microserver @MicroSpringBoot +public class AsyncAppRunner { + + + AsyncRestClient rest = new AsyncRestClient(1000,1000).withAccept("text/plain"); + + + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + new MicroserverApp( ()-> "async-app"); + Thread.sleep(2000); + + assertThat(rest.get("http://localhost:8080/async-app/async/expensive").get(),is(";test!;test!;test!")); + + } + + + +} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/boot/com/oath/micro/server/AsyncResource.java b/micro-spring-boot/src/test/java/app/boot/com/oath/micro/server/AsyncResource.java new file mode 100644 index 000000000..7c666271a --- /dev/null +++ b/micro-spring-boot/src/test/java/app/boot/com/oath/micro/server/AsyncResource.java @@ -0,0 +1,52 @@ +package app.boot.com.oath.micro.server; + +import com.google.common.collect.ImmutableList; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import cyclops.futurestream.SimpleReact; +import org.springframework.stereotype.Component; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; +import java.util.concurrent.CompletableFuture; + +@Path("/async") +@Component +public class AsyncResource implements RestResource{ + + private final SimpleReact simpleReact =new SimpleReact(); + private final ImmutableList urls = ImmutableList.of("http://localhost:8080/async-app/async/ping2", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping"); + + private final AsyncRestClient client = new AsyncRestClient(1000,1000).withAccept("text/plain"); + + @GET + @Path("/expensive") + @Produces("text/plain") + public void expensive(@Suspended AsyncResponse asyncResponse){ + + simpleReact.fromStream(urls.stream() + .>map(client::get)) + .onFail(it -> "") + .peek(System.out::println) + .allOf(data -> { + System.out.println(data); + return asyncResponse.resume(String.join(";", data)); + }); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "test!"; + } + + +} diff --git a/micro-spring-boot/src/test/java/app/boot/com/oath/micro/server/SimpleApp.java b/micro-spring-boot/src/test/java/app/boot/com/oath/micro/server/SimpleApp.java new file mode 100644 index 000000000..29820978c --- /dev/null +++ b/micro-spring-boot/src/test/java/app/boot/com/oath/micro/server/SimpleApp.java @@ -0,0 +1,12 @@ +package app.boot.com.oath.micro.server; + +import com.oath.micro.server.MicroserverApp; + + +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()->"test-app").run(); + } + +} diff --git a/micro-spring-boot/src/test/java/app/boot/events/com/aol/micro/server/EventRunnerTest.java b/micro-spring-boot/src/test/java/app/boot/events/com/aol/micro/server/EventRunnerTest.java deleted file mode 100644 index 75990110a..000000000 --- a/micro-spring-boot/src/test/java/app/boot/events/com/aol/micro/server/EventRunnerTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package app.boot.events.com.aol.micro.server; - - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.testing.RestAgent; -import com.aol.micro.server.spring.boot.MicroSpringBoot; - -@Microserver -@MicroSpringBoot -public class EventRunnerTest { - - RestAgent rest = new RestAgent(); - private final AsyncRestClient client = new AsyncRestClient(1000,1000).withAccept("application/json"); - MicroserverApp server; - - - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "event-app"); - - - } - - - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/event-app/status/ping"),is("ok")); - - assertThat(client.get("http://localhost:8080/event-app/active/jobs").get(), - containsString("startedAt")); - assertThat(client.get("http://localhost:8080/event-app/active/requests").get(), - containsString("startedAt")); -// assertThat(client.get("http://localhost:8080/event-app/manifest").get(), -// containsString("Manifest")); - - } - - - -} diff --git a/micro-spring-boot/src/test/java/app/boot/events/com/aol/micro/server/EventStatusResource.java b/micro-spring-boot/src/test/java/app/boot/events/com/aol/micro/server/EventStatusResource.java deleted file mode 100644 index 4a17b5de9..000000000 --- a/micro-spring-boot/src/test/java/app/boot/events/com/aol/micro/server/EventStatusResource.java +++ /dev/null @@ -1,40 +0,0 @@ -package app.boot.events.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.events.RequestEvents; -import com.google.common.eventbus.EventBus; - -@Component -@Path("/status") -public class EventStatusResource implements RestResource { - - - - - private final EventBus bus; - - @Autowired - public EventStatusResource(EventBus bus ){ - this.bus = bus; - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - bus.post(RequestEvents.start("get", 1l)); - try{ - return "ok"; - }finally{ - bus.post(RequestEvents.finish("get",1l)); - } - } - -} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/boot/events/com/aol/micro/server/Job.java b/micro-spring-boot/src/test/java/app/boot/events/com/aol/micro/server/Job.java deleted file mode 100644 index 8978963fd..000000000 --- a/micro-spring-boot/src/test/java/app/boot/events/com/aol/micro/server/Job.java +++ /dev/null @@ -1,16 +0,0 @@ -package app.boot.events.com.aol.micro.server; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.events.ScheduledJob; -import com.aol.micro.server.events.SystemData; - -@Component -public class Job implements ScheduledJob{ - - @Override - public SystemData scheduleAndLog() { - return SystemData.builder().errors(0).processed(2).build(); - } - -} diff --git a/micro-spring-boot/src/test/java/app/boot/events/com/aol/micro/server/Schedular.java b/micro-spring-boot/src/test/java/app/boot/events/com/aol/micro/server/Schedular.java deleted file mode 100644 index d68afd75c..000000000 --- a/micro-spring-boot/src/test/java/app/boot/events/com/aol/micro/server/Schedular.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.boot.events.com.aol.micro.server; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - - -@Component -public class Schedular { - - private final Job job; - - @Autowired - public Schedular(final Job job){ - this.job=job; - } - - @Scheduled(fixedDelay=1) - public synchronized void scheduleTask(){ - job.scheduleAndLog(); - } -} diff --git a/micro-spring-boot/src/test/java/app/boot/events/com/oath/micro/server/EventRunnerTest.java b/micro-spring-boot/src/test/java/app/boot/events/com/oath/micro/server/EventRunnerTest.java new file mode 100644 index 000000000..3599ebc9c --- /dev/null +++ b/micro-spring-boot/src/test/java/app/boot/events/com/oath/micro/server/EventRunnerTest.java @@ -0,0 +1,56 @@ +package app.boot.events.com.oath.micro.server; + + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.testing.RestAgent; +import com.oath.micro.server.spring.boot.MicroSpringBoot; + +@Microserver +@MicroSpringBoot +public class EventRunnerTest { + + RestAgent rest = new RestAgent(); + private final AsyncRestClient client = new AsyncRestClient(1000,1000).withAccept("application/json"); + MicroserverApp server; + + + @Before + public void startServer(){ + + server = new MicroserverApp(()-> "event-app"); + + + } + + + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/event-app/status/ping"),is("ok")); + + assertThat(client.get("http://localhost:8080/event-app/active/jobs").get(), + containsString("startedAt")); + assertThat(client.get("http://localhost:8080/event-app/active/requests").get(), + containsString("startedAt")); +// assertThat(client.get("http://localhost:8080/event-app/manifest").get(), +// containsString("Manifest")); + + } + + + +} diff --git a/micro-spring-boot/src/test/java/app/boot/events/com/oath/micro/server/EventStatusResource.java b/micro-spring-boot/src/test/java/app/boot/events/com/oath/micro/server/EventStatusResource.java new file mode 100644 index 000000000..1694b2360 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/boot/events/com/oath/micro/server/EventStatusResource.java @@ -0,0 +1,36 @@ +package app.boot.events.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.events.RequestEvents; +import com.google.common.eventbus.EventBus; + +@Component +@Path("/status") +public class EventStatusResource implements RestResource { + + private final EventBus bus; + + @Autowired + public EventStatusResource(EventBus bus ){ + this.bus = bus; + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + bus.post(RequestEvents.start("get", "1")); + try { + return "ok"; + } finally { + bus.post(RequestEvents.finish("get", "1")); + } + } +} diff --git a/micro-spring-boot/src/test/java/app/boot/events/com/oath/micro/server/Job.java b/micro-spring-boot/src/test/java/app/boot/events/com/oath/micro/server/Job.java new file mode 100644 index 000000000..733a8c2ae --- /dev/null +++ b/micro-spring-boot/src/test/java/app/boot/events/com/oath/micro/server/Job.java @@ -0,0 +1,16 @@ +package app.boot.events.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.events.ScheduledJob; +import com.oath.micro.server.events.SystemData; + +@Component +public class Job implements ScheduledJob{ + + @Override + public SystemData scheduleAndLog() { + return SystemData.builder().errors(0).processed(2).build(); + } + +} diff --git a/micro-spring-boot/src/test/java/app/boot/events/com/oath/micro/server/Schedular.java b/micro-spring-boot/src/test/java/app/boot/events/com/oath/micro/server/Schedular.java new file mode 100644 index 000000000..a14db58f9 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/boot/events/com/oath/micro/server/Schedular.java @@ -0,0 +1,22 @@ +package app.boot.events.com.oath.micro.server; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + + +@Component +public class Schedular { + + private final Job job; + + @Autowired + public Schedular(final Job job){ + this.job=job; + } + + @Scheduled(fixedDelay=1) + public synchronized void scheduleTask(){ + job.scheduleAndLog(); + } +} diff --git a/micro-spring-boot/src/test/java/app/boot/front/end/BootExample.java b/micro-spring-boot/src/test/java/app/boot/front/end/BootExample.java new file mode 100644 index 000000000..3defe87b4 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/boot/front/end/BootExample.java @@ -0,0 +1,19 @@ +package app.boot.front.end; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +@SpringBootApplication +public class BootExample extends SpringBootServletInitializer { + + public static void main(String[] args){ + SpringApplication.run(BootExample.class, args); + /** new BootExample() + .configure(new SpringApplicationBuilder(BootExample.class)) + .run(args); + **/ + + } +} diff --git a/micro-spring-boot/src/test/java/app/boot/front/end/SampleJerseyApplication.java b/micro-spring-boot/src/test/java/app/boot/front/end/SampleJerseyApplication.java index c31f28042..c1cbad75a 100644 --- a/micro-spring-boot/src/test/java/app/boot/front/end/SampleJerseyApplication.java +++ b/micro-spring-boot/src/test/java/app/boot/front/end/SampleJerseyApplication.java @@ -1,8 +1,8 @@ package app.boot.front.end; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.spring.boot.MicroSpringBoot; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.spring.boot.MicroSpringBoot; @Microserver @MicroSpringBoot @@ -10,7 +10,8 @@ public class SampleJerseyApplication { public static void main(String[] args) { - MicroserverApp app = new MicroserverApp(()->"hello"); + MicroserverApp app = new MicroserverApp(()->"hello"); + } diff --git a/micro-spring-boot/src/test/java/app/boot/front/end/SimpleStatusResource.java b/micro-spring-boot/src/test/java/app/boot/front/end/SimpleStatusResource.java index f2721e392..84c4dea93 100644 --- a/micro-spring-boot/src/test/java/app/boot/front/end/SimpleStatusResource.java +++ b/micro-spring-boot/src/test/java/app/boot/front/end/SimpleStatusResource.java @@ -7,7 +7,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; -import com.aol.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.auto.discovery.RestResource; @Component @Qualifier("simpleStatusResource") diff --git a/micro-spring-boot/src/test/java/app/boot/front/end/SimpleTest.java b/micro-spring-boot/src/test/java/app/boot/front/end/SimpleTest.java index 0ec77f91b..345cdad63 100644 --- a/micro-spring-boot/src/test/java/app/boot/front/end/SimpleTest.java +++ b/micro-spring-boot/src/test/java/app/boot/front/end/SimpleTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import org.springframework.beans.factory.annotation.Value; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.testing.RestAgent; public class SimpleTest { diff --git a/micro-spring-boot/src/test/java/app/custom/binder/direct/BinderDirectTest.java b/micro-spring-boot/src/test/java/app/custom/binder/direct/BinderDirectTest.java index 12f84a24e..5aa46d39f 100644 --- a/micro-spring-boot/src/test/java/app/custom/binder/direct/BinderDirectTest.java +++ b/micro-spring-boot/src/test/java/app/custom/binder/direct/BinderDirectTest.java @@ -11,13 +11,11 @@ import org.junit.Before; import org.junit.Test; -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.module.Module; -import com.aol.micro.server.spring.boot.MicroSpringBoot; -import com.aol.micro.server.testing.RestAgent; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.spring.boot.MicroSpringBoot; +import com.oath.micro.server.testing.RestAgent; @MicroSpringBoot public class BinderDirectTest { diff --git a/micro-spring-boot/src/test/java/app/custom/binder/direct/CustomBinder4.java b/micro-spring-boot/src/test/java/app/custom/binder/direct/CustomBinder4.java index 9c2b15310..1cd4458e0 100644 --- a/micro-spring-boot/src/test/java/app/custom/binder/direct/CustomBinder4.java +++ b/micro-spring-boot/src/test/java/app/custom/binder/direct/CustomBinder4.java @@ -2,8 +2,6 @@ import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.server.spi.internal.ResourceMethodInvocationHandlerProvider; -import com.aol.micro.server.auto.discovery.JaxRsResource; - public class CustomBinder4 extends AbstractBinder { @Override diff --git a/micro-spring-boot/src/test/java/app/custom/binder/direct/SimpleApp.java b/micro-spring-boot/src/test/java/app/custom/binder/direct/SimpleApp.java index 95150b9e9..b909890af 100644 --- a/micro-spring-boot/src/test/java/app/custom/binder/direct/SimpleApp.java +++ b/micro-spring-boot/src/test/java/app/custom/binder/direct/SimpleApp.java @@ -3,12 +3,7 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; -import org.glassfish.jersey.server.ResourceConfig; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.module.ConfigurableModule; - +import com.oath.micro.server.auto.discovery.Rest; @Rest diff --git a/micro-spring-boot/src/test/java/app/custom/binder/noanno/BinderTest.java b/micro-spring-boot/src/test/java/app/custom/binder/noanno/BinderTest.java index efa7a605d..364a6ec0a 100644 --- a/micro-spring-boot/src/test/java/app/custom/binder/noanno/BinderTest.java +++ b/micro-spring-boot/src/test/java/app/custom/binder/noanno/BinderTest.java @@ -10,10 +10,9 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.spring.boot.MicroSpringBoot; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.spring.boot.MicroSpringBoot; +import com.oath.micro.server.testing.RestAgent; @MicroSpringBoot public class BinderTest { diff --git a/micro-spring-boot/src/test/java/app/custom/binder/noanno/Config.java b/micro-spring-boot/src/test/java/app/custom/binder/noanno/Config.java index 024b965a7..3bafd3e1b 100644 --- a/micro-spring-boot/src/test/java/app/custom/binder/noanno/Config.java +++ b/micro-spring-boot/src/test/java/app/custom/binder/noanno/Config.java @@ -3,7 +3,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import com.aol.micro.server.auto.discovery.JaxRsResourceWrapper; +import com.oath.micro.server.auto.discovery.JaxRsResourceWrapper; @Configuration public class Config { diff --git a/micro-spring-boot/src/test/java/app/custom/binder/noanno/CustomBinder2.java b/micro-spring-boot/src/test/java/app/custom/binder/noanno/CustomBinder2.java index e42284b21..706ab300e 100644 --- a/micro-spring-boot/src/test/java/app/custom/binder/noanno/CustomBinder2.java +++ b/micro-spring-boot/src/test/java/app/custom/binder/noanno/CustomBinder2.java @@ -2,8 +2,6 @@ import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.server.spi.internal.ResourceMethodInvocationHandlerProvider; -import com.aol.micro.server.auto.discovery.JaxRsResource; - public class CustomBinder2 extends AbstractBinder { @Override diff --git a/micro-spring-boot/src/test/java/app/custom/binder/noanno/SimpleApp.java b/micro-spring-boot/src/test/java/app/custom/binder/noanno/SimpleApp.java index bfa784520..62668fa46 100644 --- a/micro-spring-boot/src/test/java/app/custom/binder/noanno/SimpleApp.java +++ b/micro-spring-boot/src/test/java/app/custom/binder/noanno/SimpleApp.java @@ -3,12 +3,7 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; -import org.glassfish.jersey.server.ResourceConfig; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.module.ConfigurableModule; - +import com.oath.micro.server.auto.discovery.Rest; @Rest diff --git a/micro-spring-boot/src/test/java/app/custom/binder/resource/objects/BinderTest.java b/micro-spring-boot/src/test/java/app/custom/binder/resource/objects/BinderTest.java index b945551c0..23bff8bcd 100644 --- a/micro-spring-boot/src/test/java/app/custom/binder/resource/objects/BinderTest.java +++ b/micro-spring-boot/src/test/java/app/custom/binder/resource/objects/BinderTest.java @@ -6,17 +6,15 @@ import java.util.concurrent.ExecutionException; +import cyclops.reactive.collections.mutable.SetX; import org.junit.After; import org.junit.Before; import org.junit.Test; -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.module.Module; -import com.aol.micro.server.spring.boot.MicroSpringBoot; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.spring.boot.MicroSpringBoot; +import com.oath.micro.server.testing.RestAgent; @MicroSpringBoot public class BinderTest { @@ -26,7 +24,7 @@ public class BinderTest { public void startServer(){ - server = new MicroserverApp(ConfigurableModule.builder().context("binder").jaxRsResourceObjects(PSetX.of(new CustomBinder3())).build()); + server = new MicroserverApp(ConfigurableModule.builder().context("binder").jaxRsResourceObjects(SetX.of(new CustomBinder3())).build()); diff --git a/micro-spring-boot/src/test/java/app/custom/binder/resource/objects/CustomBinder3.java b/micro-spring-boot/src/test/java/app/custom/binder/resource/objects/CustomBinder3.java index b10bf9ce1..c08aed638 100644 --- a/micro-spring-boot/src/test/java/app/custom/binder/resource/objects/CustomBinder3.java +++ b/micro-spring-boot/src/test/java/app/custom/binder/resource/objects/CustomBinder3.java @@ -2,8 +2,6 @@ import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.server.spi.internal.ResourceMethodInvocationHandlerProvider; -import com.aol.micro.server.auto.discovery.JaxRsResource; - public class CustomBinder3 extends AbstractBinder { @Override diff --git a/micro-spring-boot/src/test/java/app/custom/binder/resource/objects/SimpleApp.java b/micro-spring-boot/src/test/java/app/custom/binder/resource/objects/SimpleApp.java index 84728cf63..36a9da879 100644 --- a/micro-spring-boot/src/test/java/app/custom/binder/resource/objects/SimpleApp.java +++ b/micro-spring-boot/src/test/java/app/custom/binder/resource/objects/SimpleApp.java @@ -3,12 +3,7 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; -import org.glassfish.jersey.server.ResourceConfig; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.module.ConfigurableModule; - +import com.oath.micro.server.auto.discovery.Rest; @Rest diff --git a/micro-spring-boot/src/test/java/app/custom/binder/test/BinderTest.java b/micro-spring-boot/src/test/java/app/custom/binder/test/BinderTest.java index ad88c931e..419777590 100644 --- a/micro-spring-boot/src/test/java/app/custom/binder/test/BinderTest.java +++ b/micro-spring-boot/src/test/java/app/custom/binder/test/BinderTest.java @@ -3,19 +3,15 @@ import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; -import java.util.Arrays; import java.util.concurrent.ExecutionException; -import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.junit.After; import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.spring.boot.MicroSpringBoot; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.spring.boot.MicroSpringBoot; +import com.oath.micro.server.testing.RestAgent; @MicroSpringBoot public class BinderTest { diff --git a/micro-spring-boot/src/test/java/app/custom/binder/test/CustomBinder.java b/micro-spring-boot/src/test/java/app/custom/binder/test/CustomBinder.java index 0e23b79a7..299a46bf4 100644 --- a/micro-spring-boot/src/test/java/app/custom/binder/test/CustomBinder.java +++ b/micro-spring-boot/src/test/java/app/custom/binder/test/CustomBinder.java @@ -2,7 +2,7 @@ import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.server.spi.internal.ResourceMethodInvocationHandlerProvider; -import com.aol.micro.server.auto.discovery.JaxRsResource; +import com.oath.micro.server.auto.discovery.JaxRsResource; @JaxRsResource public class CustomBinder extends AbstractBinder { diff --git a/micro-spring-boot/src/test/java/app/custom/binder/test/SimpleApp.java b/micro-spring-boot/src/test/java/app/custom/binder/test/SimpleApp.java index 7a2c74e08..2e275f0bd 100644 --- a/micro-spring-boot/src/test/java/app/custom/binder/test/SimpleApp.java +++ b/micro-spring-boot/src/test/java/app/custom/binder/test/SimpleApp.java @@ -5,9 +5,9 @@ import org.glassfish.jersey.server.ResourceConfig; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.module.ConfigurableModule; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.module.ConfigurableModule; diff --git a/micro-spring-boot/src/test/java/app/ebay/com/aol/micro/server/CorsResource.java b/micro-spring-boot/src/test/java/app/ebay/com/oath/micro/server/CorsResource.java similarity index 75% rename from micro-spring-boot/src/test/java/app/ebay/com/aol/micro/server/CorsResource.java rename to micro-spring-boot/src/test/java/app/ebay/com/oath/micro/server/CorsResource.java index 391647a0e..12d9ee641 100644 --- a/micro-spring-boot/src/test/java/app/ebay/com/aol/micro/server/CorsResource.java +++ b/micro-spring-boot/src/test/java/app/ebay/com/oath/micro/server/CorsResource.java @@ -1,4 +1,4 @@ -package app.ebay.com.aol.micro.server; +package app.ebay.com.oath.micro.server; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -6,7 +6,7 @@ import org.springframework.stereotype.Component; -import com.aol.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.auto.discovery.RestResource; @Path("/single") @Component diff --git a/micro-spring-boot/src/test/java/app/ebay/com/aol/micro/server/FilterTest.java b/micro-spring-boot/src/test/java/app/ebay/com/oath/micro/server/FilterTest.java similarity index 83% rename from micro-spring-boot/src/test/java/app/ebay/com/aol/micro/server/FilterTest.java rename to micro-spring-boot/src/test/java/app/ebay/com/oath/micro/server/FilterTest.java index b9cb01e19..c618b6501 100644 --- a/micro-spring-boot/src/test/java/app/ebay/com/aol/micro/server/FilterTest.java +++ b/micro-spring-boot/src/test/java/app/ebay/com/oath/micro/server/FilterTest.java @@ -1,4 +1,4 @@ -package app.ebay.com.aol.micro.server; +package app.ebay.com.oath.micro.server; import static org.junit.Assert.assertFalse; @@ -16,10 +16,10 @@ import org.junit.Ignore; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.spring.boot.MicroSpringBoot; -import com.aol.micro.server.testing.RestAgent; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.spring.boot.MicroSpringBoot; +import com.oath.micro.server.testing.RestAgent; @Microserver @MicroSpringBoot diff --git a/micro-spring-boot/src/test/java/app/guava/com/aol/micro/server/GuavaAppResource.java b/micro-spring-boot/src/test/java/app/guava/com/aol/micro/server/GuavaAppResource.java deleted file mode 100644 index baeb5aed2..000000000 --- a/micro-spring-boot/src/test/java/app/guava/com/aol/micro/server/GuavaAppResource.java +++ /dev/null @@ -1,30 +0,0 @@ -package app.guava.com.aol.micro.server; - -import java.util.List; -import java.util.Optional; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -@Component -@Path("/status") -public class GuavaAppResource implements RestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public List ping(ImmutableGuavaEntity entity) { - return entity.getList(); - } - @POST - @Produces("application/json") - @Path("/optional") - public Optional optional(Jdk8Entity entity) { - return entity.getName(); - } - -} diff --git a/micro-spring-boot/src/test/java/app/guava/com/aol/micro/server/GuavaAppTest.java b/micro-spring-boot/src/test/java/app/guava/com/aol/micro/server/GuavaAppTest.java deleted file mode 100644 index 642564773..000000000 --- a/micro-spring-boot/src/test/java/app/guava/com/aol/micro/server/GuavaAppTest.java +++ /dev/null @@ -1,91 +0,0 @@ -package app.guava.com.aol.micro.server; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.List; -import java.util.Optional; -import java.util.concurrent.ExecutionException; - -import org.junit.Before; -import org.junit.Test; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.SimpleReactStream; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.jackson.JacksonUtil; -import com.aol.micro.server.spring.boot.MicroSpringBoot; -import com.aol.micro.server.testing.RestAgent; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableSet; -@Microserver @MicroSpringBoot -public class GuavaAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - ImmutableGuavaEntity entity; - Jdk8Entity present; - Jdk8Entity absent; - - SimpleReact simpleReact = new SimpleReact(); - SimpleReactStream stream; - - boolean run = false; - @Before - public void startServer() { - if(run) - return; - run =true; - stream = simpleReact.ofAsync( - () -> server = new MicroserverApp(GuavaAppTest.class, - () -> "guava-app")); - - entity = ImmutableGuavaEntity.builder().value("value") - .list(ImmutableList.of("hello", "world")) - .mapOfSets(ImmutableMap.of("key1", ImmutableSet.of(1, 2, 3))) - .multiMap(ImmutableMultimap.of("1", 2, "1", 2, "2", 4)).build(); - - JacksonUtil.convertFromJson(JacksonUtil.serializeToJson(entity), - ImmutableGuavaEntity.class); - - present = Jdk8Entity.builder().name(Optional.of("test")).build(); - - JacksonUtil.convertFromJson(JacksonUtil.serializeToJson(present), - Optional.class); - absent = Jdk8Entity.builder().name(Optional.empty()).build(); - } - - - @Test - public void confirmExpectedUrlsPresentTest() throws InterruptedException, - ExecutionException { - - stream.block(); - - assertThat((List) rest.post( - "http://localhost:8080/guava-app/status/ping", entity, - List.class), hasItem("hello")); - - } - - @Test - public void confirmOptionalConversionWorking() throws InterruptedException, - ExecutionException { - - stream.block(); - - assertThat(rest.post("http://localhost:8080/guava-app/status/optional", - present, String.class), is("\"test\"")); - - assertThat(rest.post("http://localhost:8080/guava-app/status/optional", - absent, String.class), is("null")); - - } - -} diff --git a/micro-spring-boot/src/test/java/app/guava/com/aol/micro/server/ImmutableGuavaEntity.java b/micro-spring-boot/src/test/java/app/guava/com/aol/micro/server/ImmutableGuavaEntity.java deleted file mode 100644 index 8ee2bb325..000000000 --- a/micro-spring-boot/src/test/java/app/guava/com/aol/micro/server/ImmutableGuavaEntity.java +++ /dev/null @@ -1,34 +0,0 @@ -package app.guava.com.aol.micro.server; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableSet; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableGuavaEntity { - - private final String value; - private final ImmutableList list; - private final ImmutableMap mapOfSets; - private final ImmutableMultimap multiMap; - - public ImmutableGuavaEntity() { - this(null,null,null,null); - } - -} diff --git a/micro-spring-boot/src/test/java/app/guava/com/aol/micro/server/Jdk8Entity.java b/micro-spring-boot/src/test/java/app/guava/com/aol/micro/server/Jdk8Entity.java deleted file mode 100644 index 039cb2645..000000000 --- a/micro-spring-boot/src/test/java/app/guava/com/aol/micro/server/Jdk8Entity.java +++ /dev/null @@ -1,27 +0,0 @@ -package app.guava.com.aol.micro.server; - -import java.util.Optional; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "optional") -@Getter -@AllArgsConstructor -@Builder -public class Jdk8Entity { - - private final Optional name; - - public Jdk8Entity(){ - name = Optional.empty(); - } -} diff --git a/micro-spring-boot/src/test/java/app/guava/com/oath/micro/server/GuavaAppResource.java b/micro-spring-boot/src/test/java/app/guava/com/oath/micro/server/GuavaAppResource.java new file mode 100644 index 000000000..cce09ece4 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/guava/com/oath/micro/server/GuavaAppResource.java @@ -0,0 +1,30 @@ +package app.guava.com.oath.micro.server; + +import java.util.List; +import java.util.Optional; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +@Component +@Path("/status") +public class GuavaAppResource implements RestResource { + + @POST + @Produces("application/json") + @Path("/ping") + public List ping(ImmutableGuavaEntity entity) { + return entity.getList(); + } + @POST + @Produces("application/json") + @Path("/optional") + public Optional optional(Jdk8Entity entity) { + return entity.getName(); + } + +} diff --git a/micro-spring-boot/src/test/java/app/guava/com/oath/micro/server/GuavaAppTest.java b/micro-spring-boot/src/test/java/app/guava/com/oath/micro/server/GuavaAppTest.java new file mode 100644 index 000000000..e5dbaaebc --- /dev/null +++ b/micro-spring-boot/src/test/java/app/guava/com/oath/micro/server/GuavaAppTest.java @@ -0,0 +1,93 @@ +package app.guava.com.oath.micro.server; + +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +import com.oath.cyclops.types.futurestream.SimpleReactStream; +import cyclops.futurestream.SimpleReact; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.spring.boot.MicroSpringBoot; +import com.oath.micro.server.testing.RestAgent; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; +@Ignore +@Microserver @MicroSpringBoot +public class GuavaAppTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + ImmutableGuavaEntity entity; + Jdk8Entity present; + Jdk8Entity absent; + + SimpleReact simpleReact = new SimpleReact(); + SimpleReactStream stream; + + boolean run = false; + @Before + public void startServer() { + if(run) + return; + run =true; + stream = simpleReact.ofAsync( + () -> server = new MicroserverApp(GuavaAppTest.class, + () -> "guava-app")); + + entity = ImmutableGuavaEntity.builder().value("value") + .list(ImmutableList.of("hello", "world")) + .mapOfSets(ImmutableMap.of("key1", ImmutableSet.of(1, 2, 3))) + .multiMap(ImmutableMultimap.of("1", 2, "1", 2, "2", 4)).build(); + + JacksonUtil.convertFromJson(JacksonUtil.serializeToJson(entity), + ImmutableGuavaEntity.class); + + present = Jdk8Entity.builder().name(Optional.of("test")).build(); + + JacksonUtil.convertFromJson(JacksonUtil.serializeToJson(present), + Optional.class); + absent = Jdk8Entity.builder().name(Optional.empty()).build(); + } + + + @Test + public void confirmExpectedUrlsPresentTest() throws InterruptedException, + ExecutionException { + + stream.block(); + + assertThat((List) rest.post( + "http://localhost:8080/guava-app/status/ping", entity, + List.class), hasItem("hello")); + + } + + @Test + public void confirmOptionalConversionWorking() throws InterruptedException, + ExecutionException { + + stream.block(); + + assertThat(rest.post("http://localhost:8080/guava-app/status/optional", + present, String.class), is("\"test\"")); + + assertThat(rest.post("http://localhost:8080/guava-app/status/optional", + absent, String.class), is("null")); + + } + +} diff --git a/micro-spring-boot/src/test/java/app/guava/com/oath/micro/server/ImmutableGuavaEntity.java b/micro-spring-boot/src/test/java/app/guava/com/oath/micro/server/ImmutableGuavaEntity.java new file mode 100644 index 000000000..e4e706907 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/guava/com/oath/micro/server/ImmutableGuavaEntity.java @@ -0,0 +1,34 @@ +package app.guava.com.oath.micro.server; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "immutable") +@Getter +@AllArgsConstructor +@Builder +public class ImmutableGuavaEntity { + + private final String value; + private final ImmutableList list; + private final ImmutableMap mapOfSets; + private final ImmutableMultimap multiMap; + + public ImmutableGuavaEntity() { + this(null,null,null,null); + } + +} diff --git a/micro-spring-boot/src/test/java/app/guava/com/oath/micro/server/Jdk8Entity.java b/micro-spring-boot/src/test/java/app/guava/com/oath/micro/server/Jdk8Entity.java new file mode 100644 index 000000000..df2b8662e --- /dev/null +++ b/micro-spring-boot/src/test/java/app/guava/com/oath/micro/server/Jdk8Entity.java @@ -0,0 +1,27 @@ +package app.guava.com.oath.micro.server; + +import java.util.Optional; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "optional") +@Getter +@AllArgsConstructor +@Builder +public class Jdk8Entity { + + private final Optional name; + + public Jdk8Entity(){ + name = Optional.empty(); + } +} diff --git a/micro-spring-boot/src/test/java/app/metrics/boot/com/aol/micro/server/MetricsRunnerTest.java b/micro-spring-boot/src/test/java/app/metrics/boot/com/aol/micro/server/MetricsRunnerTest.java deleted file mode 100644 index 1c8591487..000000000 --- a/micro-spring-boot/src/test/java/app/metrics/boot/com/aol/micro/server/MetricsRunnerTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package app.metrics.boot.com.aol.micro.server; - - -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.io.IOException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.spring.boot.MicroSpringBoot; -import com.aol.micro.server.spring.metrics.CodahaleMetricsConfigurer; -import com.aol.micro.server.testing.RestAgent; - -@MicroSpringBoot @Microserver -public class MetricsRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - CodahaleMetricsConfigurer.setInit( metricRegistry -> TestReporter - .forRegistry(metricRegistry) - .build() - .start(10, TimeUnit.MILLISECONDS)); - - server = new MicroserverApp( ()-> "simple-app"); - - - } - - - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException, IOException{ - - - - - - assertThat(rest.get("http://localhost:8080/simple-app/metrics/ping"),is("ok")); - - - assertThat(TestReporter.getTimer().size(),greaterThan(0)); - } - - - -} diff --git a/micro-spring-boot/src/test/java/app/metrics/boot/com/aol/micro/server/MetricsStatusResource.java b/micro-spring-boot/src/test/java/app/metrics/boot/com/aol/micro/server/MetricsStatusResource.java deleted file mode 100644 index 48bd138ee..000000000 --- a/micro-spring-boot/src/test/java/app/metrics/boot/com/aol/micro/server/MetricsStatusResource.java +++ /dev/null @@ -1,28 +0,0 @@ -package app.metrics.boot.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - - - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/metrics") -public class MetricsStatusResource implements RestResource { - - @Autowired - TimedResource timed; - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - timed.times(); - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/metrics/boot/com/aol/micro/server/TestReporter.java b/micro-spring-boot/src/test/java/app/metrics/boot/com/aol/micro/server/TestReporter.java deleted file mode 100644 index a75b93ca4..000000000 --- a/micro-spring-boot/src/test/java/app/metrics/boot/com/aol/micro/server/TestReporter.java +++ /dev/null @@ -1,169 +0,0 @@ -package app.metrics.boot.com.aol.micro.server; - -import java.io.PrintStream; -import java.util.Locale; -import java.util.SortedMap; -import java.util.TimeZone; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - -import lombok.Getter; - -import com.codahale.metrics.Clock; -import com.codahale.metrics.ConsoleReporter; -import com.codahale.metrics.Counter; -import com.codahale.metrics.Gauge; -import com.codahale.metrics.Histogram; -import com.codahale.metrics.Meter; -import com.codahale.metrics.MetricFilter; -import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.ScheduledReporter; -import com.codahale.metrics.Timer; - - -public class TestReporter extends ScheduledReporter { - - @Getter - private static volatile SortedMap timer = new TreeMap<>(); - - protected TestReporter(MetricRegistry registry, String name, - MetricFilter filter, TimeUnit rateUnit, TimeUnit durationUnit) { - super(registry, name, filter, rateUnit, durationUnit); - - } - - - public static Builder forRegistry(MetricRegistry registry) { - return new Builder(registry); - } - - @Override - public void report(SortedMap gauges, - SortedMap counters, - SortedMap histograms, - SortedMap meters, SortedMap timers) { - this.timer = timers; - - - } - - public static class Builder { - private final MetricRegistry registry; - private PrintStream output; - private Locale locale; - private Clock clock; - private TimeZone timeZone; - private TimeUnit rateUnit; - private TimeUnit durationUnit; - private MetricFilter filter; - - private Builder(MetricRegistry registry) { - this.registry = registry; - this.output = System.out; - this.locale = Locale.getDefault(); - this.clock = Clock.defaultClock(); - this.timeZone = TimeZone.getDefault(); - this.rateUnit = TimeUnit.SECONDS; - this.durationUnit = TimeUnit.MILLISECONDS; - this.filter = MetricFilter.ALL; - } - - /** - * Write to the given {@link PrintStream}. - * - * @param output a {@link PrintStream} instance. - * @return {@code this} - */ - public Builder outputTo(PrintStream output) { - this.output = output; - return this; - } - - /** - * Format numbers for the given {@link Locale}. - * - * @param locale a {@link Locale} - * @return {@code this} - */ - public Builder formattedFor(Locale locale) { - this.locale = locale; - return this; - } - - /** - * Use the given {@link Clock} instance for the time. - * - * @param clock a {@link Clock} instance - * @return {@code this} - */ - public Builder withClock(Clock clock) { - this.clock = clock; - return this; - } - - /** - * Use the given {@link TimeZone} for the time. - * - * @param timeZone a {@link TimeZone} - * @return {@code this} - */ - public Builder formattedFor(TimeZone timeZone) { - this.timeZone = timeZone; - return this; - } - - /** - * Convert rates to the given time unit. - * - * @param rateUnit a unit of time - * @return {@code this} - */ - public Builder convertRatesTo(TimeUnit rateUnit) { - this.rateUnit = rateUnit; - return this; - } - - /** - * Convert durations to the given time unit. - * - * @param durationUnit a unit of time - * @return {@code this} - */ - public Builder convertDurationsTo(TimeUnit durationUnit) { - this.durationUnit = durationUnit; - return this; - } - - /** - * Only report metrics which match the given filter. - * - * @param filter a {@link MetricFilter} - * @return {@code this} - */ - public Builder filter(MetricFilter filter) { - this.filter = filter; - return this; - } - - /** - * Builds a {@link ConsoleReporter} with the given properties. - * - * @return a {@link ConsoleReporter} - */ - public TestReporter build() { - return new TestReporter(registry, - // output, - "name", - // locale, - // clock, - // timeZone, - this.filter, - rateUnit, - durationUnit - ); - } - } - - -} - diff --git a/micro-spring-boot/src/test/java/app/metrics/boot/com/aol/micro/server/TimedResource.java b/micro-spring-boot/src/test/java/app/metrics/boot/com/aol/micro/server/TimedResource.java deleted file mode 100644 index af197479b..000000000 --- a/micro-spring-boot/src/test/java/app/metrics/boot/com/aol/micro/server/TimedResource.java +++ /dev/null @@ -1,17 +0,0 @@ -package app.metrics.boot.com.aol.micro.server; - -import org.springframework.stereotype.Component; - -import com.codahale.metrics.annotation.Timed; -import com.ryantenney.metrics.annotation.Counted; - -@Component -public class TimedResource { - - - @Timed - public String times(){ - - return "ok!"; - } -} diff --git a/micro-spring-boot/src/test/java/app/metrics/boot/com/oath/micro/server/MetricsRunnerTest.java b/micro-spring-boot/src/test/java/app/metrics/boot/com/oath/micro/server/MetricsRunnerTest.java new file mode 100644 index 000000000..cdf358455 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/metrics/boot/com/oath/micro/server/MetricsRunnerTest.java @@ -0,0 +1,56 @@ +package app.metrics.boot.com.oath.micro.server; + + +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.spring.boot.MicroSpringBoot; +import com.oath.micro.server.spring.metrics.CodahaleMetricsConfigurer; +import com.oath.micro.server.testing.RestAgent; + +@MicroSpringBoot @Microserver +public class MetricsRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + CodahaleMetricsConfigurer.setInit( metricRegistry -> TestReporter + .forRegistry(metricRegistry) + .build() + .start(10, TimeUnit.MILLISECONDS)); + + server = new MicroserverApp( ()-> "simple-app"); + + + } + + + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException, IOException{ + + + + + + assertThat(rest.get("http://localhost:8080/simple-app/metrics/ping"),is("ok")); + + + assertThat(TestReporter.getTimer().size(),greaterThan(0)); + } + + + +} diff --git a/micro-spring-boot/src/test/java/app/metrics/boot/com/oath/micro/server/MetricsStatusResource.java b/micro-spring-boot/src/test/java/app/metrics/boot/com/oath/micro/server/MetricsStatusResource.java new file mode 100644 index 000000000..c7389afdd --- /dev/null +++ b/micro-spring-boot/src/test/java/app/metrics/boot/com/oath/micro/server/MetricsStatusResource.java @@ -0,0 +1,28 @@ +package app.metrics.boot.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + + + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/metrics") +public class MetricsStatusResource implements RestResource { + + @Autowired + TimedResource timed; + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + timed.times(); + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/metrics/boot/com/oath/micro/server/TestReporter.java b/micro-spring-boot/src/test/java/app/metrics/boot/com/oath/micro/server/TestReporter.java new file mode 100644 index 000000000..8c69aa2e3 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/metrics/boot/com/oath/micro/server/TestReporter.java @@ -0,0 +1,169 @@ +package app.metrics.boot.com.oath.micro.server; + +import java.io.PrintStream; +import java.util.Locale; +import java.util.SortedMap; +import java.util.TimeZone; +import java.util.TreeMap; +import java.util.concurrent.TimeUnit; + +import lombok.Getter; + +import com.codahale.metrics.Clock; +import com.codahale.metrics.ConsoleReporter; +import com.codahale.metrics.Counter; +import com.codahale.metrics.Gauge; +import com.codahale.metrics.Histogram; +import com.codahale.metrics.Meter; +import com.codahale.metrics.MetricFilter; +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.ScheduledReporter; +import com.codahale.metrics.Timer; + + +public class TestReporter extends ScheduledReporter { + + @Getter + private static volatile SortedMap timer = new TreeMap<>(); + + protected TestReporter(MetricRegistry registry, String name, + MetricFilter filter, TimeUnit rateUnit, TimeUnit durationUnit) { + super(registry, name, filter, rateUnit, durationUnit); + + } + + + public static Builder forRegistry(MetricRegistry registry) { + return new Builder(registry); + } + + @Override + public void report(SortedMap gauges, + SortedMap counters, + SortedMap histograms, + SortedMap meters, SortedMap timers) { + this.timer = timers; + + + } + + public static class Builder { + private final MetricRegistry registry; + private PrintStream output; + private Locale locale; + private Clock clock; + private TimeZone timeZone; + private TimeUnit rateUnit; + private TimeUnit durationUnit; + private MetricFilter filter; + + private Builder(MetricRegistry registry) { + this.registry = registry; + this.output = System.out; + this.locale = Locale.getDefault(); + this.clock = Clock.defaultClock(); + this.timeZone = TimeZone.getDefault(); + this.rateUnit = TimeUnit.SECONDS; + this.durationUnit = TimeUnit.MILLISECONDS; + this.filter = MetricFilter.ALL; + } + + /** + * Write to the given {@link PrintStream}. + * + * @param output a {@link PrintStream} instance. + * @return {@code this} + */ + public Builder outputTo(PrintStream output) { + this.output = output; + return this; + } + + /** + * Format numbers for the given {@link Locale}. + * + * @param locale a {@link Locale} + * @return {@code this} + */ + public Builder formattedFor(Locale locale) { + this.locale = locale; + return this; + } + + /** + * Use the given {@link Clock} instance for the time. + * + * @param clock a {@link Clock} instance + * @return {@code this} + */ + public Builder withClock(Clock clock) { + this.clock = clock; + return this; + } + + /** + * Use the given {@link TimeZone} for the time. + * + * @param timeZone a {@link TimeZone} + * @return {@code this} + */ + public Builder formattedFor(TimeZone timeZone) { + this.timeZone = timeZone; + return this; + } + + /** + * Convert rates to the given time unit. + * + * @param rateUnit a unit of time + * @return {@code this} + */ + public Builder convertRatesTo(TimeUnit rateUnit) { + this.rateUnit = rateUnit; + return this; + } + + /** + * Convert durations to the given time unit. + * + * @param durationUnit a unit of time + * @return {@code this} + */ + public Builder convertDurationsTo(TimeUnit durationUnit) { + this.durationUnit = durationUnit; + return this; + } + + /** + * Only report metrics which match the given filter. + * + * @param filter a {@link MetricFilter} + * @return {@code this} + */ + public Builder filter(MetricFilter filter) { + this.filter = filter; + return this; + } + + /** + * Builds a {@link ConsoleReporter} with the given properties. + * + * @return a {@link ConsoleReporter} + */ + public TestReporter build() { + return new TestReporter(registry, + // output, + "name", + // locale, + // clock, + // timeZone, + this.filter, + rateUnit, + durationUnit + ); + } + } + + +} + diff --git a/micro-spring-boot/src/test/java/app/metrics/boot/com/oath/micro/server/TimedResource.java b/micro-spring-boot/src/test/java/app/metrics/boot/com/oath/micro/server/TimedResource.java new file mode 100644 index 000000000..efafe3099 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/metrics/boot/com/oath/micro/server/TimedResource.java @@ -0,0 +1,16 @@ +package app.metrics.boot.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +import com.codahale.metrics.annotation.Timed; + +@Component +public class TimedResource { + + + @Timed + public String times(){ + + return "ok!"; + } +} diff --git a/micro-spring-boot/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java b/micro-spring-boot/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java deleted file mode 100644 index 14a9344b0..000000000 --- a/micro-spring-boot/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package app.minimal.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.testing.RestAgent; -import com.aol.micro.server.spring.boot.MicroSpringBoot; - -@Rest -@Path("/single") @MicroSpringBoot -public class MinimalClassTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "minimal-app"); - - - } - - - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok1")); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok1"; - } - - -} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java b/micro-spring-boot/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java new file mode 100644 index 000000000..d56c2bf2b --- /dev/null +++ b/micro-spring-boot/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java @@ -0,0 +1,54 @@ +package app.minimal.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.testing.RestAgent; +import com.oath.micro.server.spring.boot.MicroSpringBoot; + +@Rest +@Path("/single") @MicroSpringBoot +public class MinimalClassTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp(()-> "minimal-app"); + + + } + + + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok1")); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok1"; + } + + +} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/rest/client/com/aol/micro/server/GenericRestClientResource.java b/micro-spring-boot/src/test/java/app/rest/client/com/aol/micro/server/GenericRestClientResource.java deleted file mode 100644 index 8aa6fdec9..000000000 --- a/micro-spring-boot/src/test/java/app/rest/client/com/aol/micro/server/GenericRestClientResource.java +++ /dev/null @@ -1,56 +0,0 @@ -package app.rest.client.com.aol.micro.server; - -import java.util.List; - -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -@Component -@Path("/rest") -public class GenericRestClientResource implements RestResource { - - - @GET - @Produces("application/json") - @Path("/get") - public List get() { - - return ImmutableList.of("ok"); - } - - @POST - @Produces("application/json") - @Path("/post") - public ImmutableSet post(ImmutableMap map) { - - return ImmutableSet.copyOf(map.values()); - } - - @PUT - @Produces("application/json") - @Path("/put") - public ImmutableSet put(ImmutableMap map) { - - return ImmutableSet.copyOf(map.values()); - } - @DELETE - @Produces("application/json") - @Path("/delete") - public List delete(ImmutableMap map) { - - return ImmutableList.of("ok"); - } - - -} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/rest/client/com/aol/micro/server/MyEntity.java b/micro-spring-boot/src/test/java/app/rest/client/com/aol/micro/server/MyEntity.java deleted file mode 100644 index 1d2fa9b71..000000000 --- a/micro-spring-boot/src/test/java/app/rest/client/com/aol/micro/server/MyEntity.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.rest.client.com.aol.micro.server; - -import lombok.EqualsAndHashCode; -import lombok.Getter; - -@EqualsAndHashCode -@Getter -public class MyEntity { - - private final String name ="myEntity"; - -} diff --git a/micro-spring-boot/src/test/java/app/rest/client/com/aol/micro/server/RestClientResource.java b/micro-spring-boot/src/test/java/app/rest/client/com/aol/micro/server/RestClientResource.java deleted file mode 100644 index c784b47d7..000000000 --- a/micro-spring-boot/src/test/java/app/rest/client/com/aol/micro/server/RestClientResource.java +++ /dev/null @@ -1,54 +0,0 @@ -package app.rest.client.com.aol.micro.server; - -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -@Component -@Path("/generics") -public class RestClientResource implements RestResource { - - private final ImmutableList result = ImmutableList.of(new MyEntity()); - @GET - @Produces("application/json") - @Path("/get") - public ImmutableList get() { - - return result; - } - - @POST - @Produces("application/json") - @Path("/post") - public ImmutableList post(ImmutableMap map) { - - return result; - } - - @PUT - @Produces("application/json") - @Path("/put") - public ImmutableList put(ImmutableMap map) { - - return result; - } - @DELETE - @Produces("application/json") - @Path("/delete") - public ImmutableList delete(ImmutableMap map) { - - return result; - } - - -} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/rest/client/com/aol/micro/server/RestClientTest.java b/micro-spring-boot/src/test/java/app/rest/client/com/aol/micro/server/RestClientTest.java deleted file mode 100644 index 9f1c86922..000000000 --- a/micro-spring-boot/src/test/java/app/rest/client/com/aol/micro/server/RestClientTest.java +++ /dev/null @@ -1,116 +0,0 @@ - -package app.rest.client.com.aol.micro.server; - - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.List; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.web.client.RestClientException; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.rest.client.nio.NIORestClient; -import com.aol.micro.server.rest.client.nio.SpringConfig; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.aol.micro.server.spring.boot.MicroSpringBoot; - -@Microserver @MicroSpringBoot -public class RestClientTest { - - private final AsyncRestClient> listClient = new AsyncRestClient(1000,1000).withResponse(List.class); - private final AsyncRestClient> setClient = new AsyncRestClient(1000,1000).withResponse(ImmutableSet.class);; - private final AsyncRestClient> genericsClient = new AsyncRestClient(1000,1000).withGenericResponse(ImmutableList.class, MyEntity.class); - - private final NIORestClient rest = new SpringConfig().restClient(); - - - MicroserverApp server; - static volatile boolean run = false; - @Before - public void startServer(){ - if(run) - return; - run = true; - server = new MicroserverApp( RestClientTest.class, ()-> "rest-app"); - - - } - - - /* - * Simpler with JaxRsNIOClient - */ - @Test - public void testCRUD() throws InterruptedException, ExecutionException{ - - - assertThat(listClient.get("http://localhost:8080/rest-app/rest/get").get().get(0),is("ok")); - assertThat(setClient.post("http://localhost:8080/rest-app/rest/post",ImmutableMap.of(1,"hello")).get(),is(ImmutableSet.of("hello"))); - assertThat(setClient.put("http://localhost:8080/rest-app/rest/put",ImmutableMap.of(1,"hello")).get(),is(ImmutableSet.of("hello"))); - assertThat(listClient.delete("http://localhost:8080/rest-app/rest/delete").get().get(0),is("ok")); - } - - @Test - public void testCRUDGenerics() throws InterruptedException, ExecutionException{ - - - assertThat(genericsClient.get("http://localhost:8080/rest-app/generics/get").get().get(0),is(new MyEntity())); - assertThat(genericsClient.post("http://localhost:8080/rest-app/generics/post",ImmutableMap.of(1,"hello")).get(),is(ImmutableList.of(new MyEntity()))); - assertThat(genericsClient.put("http://localhost:8080/rest-app/generics/put",ImmutableMap.of(1,"hello")).get(),is(ImmutableList.of(new MyEntity()))); - assertThat(genericsClient.delete("http://localhost:8080/rest-app/generics/delete").get().get(0),is(new MyEntity())); - } - - /** - * More complex with Spring REST Template Based NIORestTemplate - * - */ - - @Test - public void testCRUDSpring() throws InterruptedException, ExecutionException, RestClientException, URISyntaxException{ - - - assertThat(rest.getForEntity(new URI("http://localhost:8080/rest-app/rest/get"),List.class).get().getBody().get(0),is("ok")); - - assertThat(rest.postForEntity("http://localhost:8080/rest-app/rest/post", new HttpEntity(ImmutableMap.of(1,"hello")), ImmutableSet.class).get().getBody(),is(ImmutableSet.of("hello"))); - assertThat( rest.put("http://localhost:8080/rest-app/rest/put",new HttpEntity(ImmutableMap.of(1,"hello")),ImmutableSet.class).get() - ,is(nullValue())); - assertThat(rest.delete("http://localhost:8080/rest-app/rest/delete").get(),is(nullValue())); - } - - @Test - public void testCRUDGenericsSpring() throws InterruptedException, ExecutionException{ - - - assertThat(rest.exchange("http://localhost:8080/rest-app/generics/get",HttpMethod.GET,null,new ParameterizedTypeReference>(){}) - .get().getBody().get(0),is(new MyEntity())); - - assertThat(rest.exchange("http://localhost:8080/rest-app/generics/post",HttpMethod.POST,new HttpEntity(ImmutableMap.of(1,"hello")),new ParameterizedTypeReference>(){}) - .get().getBody(),is(ImmutableList.of(new MyEntity()))); - - assertThat(rest.exchange("http://localhost:8080/rest-app/generics/put",HttpMethod.PUT,new HttpEntity(ImmutableMap.of(1,"hello")),new ParameterizedTypeReference>(){}) - .get().getBody(),is(ImmutableList.of(new MyEntity()))); - - assertThat(rest.exchange("http://localhost:8080/rest-app/generics/delete",HttpMethod.DELETE,null,new ParameterizedTypeReference>(){}) - .get().getBody().get(0),is(new MyEntity())); - - } - - - -} diff --git a/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/GenericRestClientResource.java b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/GenericRestClientResource.java new file mode 100644 index 000000000..3b6b9ee90 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/GenericRestClientResource.java @@ -0,0 +1,56 @@ +package app.rest.client.com.oath.micro.server; + +import java.util.List; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +@Component +@Path("/rest") +public class GenericRestClientResource implements RestResource { + + + @GET + @Produces("application/json") + @Path("/get") + public List get() { + + return ImmutableList.of("ok"); + } + + @POST + @Produces("application/json") + @Path("/post") + public ImmutableSet post(ImmutableMap map) { + + return ImmutableSet.copyOf(map.values()); + } + + @PUT + @Produces("application/json") + @Path("/put") + public ImmutableSet put(ImmutableMap map) { + + return ImmutableSet.copyOf(map.values()); + } + @DELETE + @Produces("application/json") + @Path("/delete") + public List delete(ImmutableMap map) { + + return ImmutableList.of("ok"); + } + + +} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/LoggingExMapper.java b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/LoggingExMapper.java new file mode 100644 index 000000000..89bf54b51 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/LoggingExMapper.java @@ -0,0 +1,19 @@ +package app.rest.client.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + +@Provider +public class LoggingExMapper implements ExceptionMapper { + public LoggingExMapper(){ + System.out.println("registered"); + } + @Override + public Response toResponse(Throwable exception) { + exception.printStackTrace(); + return Response.status(400).build(); + } +} diff --git a/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/LoggingFilter.java b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/LoggingFilter.java new file mode 100644 index 000000000..ecc8dc6a7 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/LoggingFilter.java @@ -0,0 +1,50 @@ +package app.rest.client.com.oath.micro.server; + +import com.oath.micro.server.auto.discovery.FilterConfiguration; +import cyclops.control.Either; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import java.io.IOException; + +import static cyclops.control.Either.right; + +@Component +public class LoggingFilter implements FilterConfiguration { + @Override + public String[] getMapping() { + return new String[]{"/*"}; + } + + @Override + public Either, Filter> getFilter() { + return right(new Filter() { + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + try { + chain.doFilter(request, response); + }catch(Throwable e){ + e.printStackTrace(); + } + System.out.println("hello"); + } + + @Override + public void destroy() { + + } + }); + } +} diff --git a/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/Main.java b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/Main.java new file mode 100644 index 000000000..d699d8644 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/Main.java @@ -0,0 +1,22 @@ +package app.rest.client.com.oath.micro.server; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.Module; +import com.oath.micro.server.spring.boot.MicroSpringBoot; + +@Microserver +@MicroSpringBoot +public class Main { + public static void main(String[] args) throws InterruptedException { + new MicroserverApp( RestClientTest.class, new Module() { + @Override + public String getContext() { + return "rest-app"; + } + }); + while(true){ + Thread.sleep(1000000l); + } + } +} diff --git a/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/MyEntity.java b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/MyEntity.java new file mode 100644 index 000000000..c075fa67f --- /dev/null +++ b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/MyEntity.java @@ -0,0 +1,12 @@ +package app.rest.client.com.oath.micro.server; + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@EqualsAndHashCode +@Getter +public class MyEntity { + + private final String name ="myEntity"; + +} diff --git a/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/RestClientResource.java b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/RestClientResource.java new file mode 100644 index 000000000..dfeef9bf1 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/RestClientResource.java @@ -0,0 +1,55 @@ +package app.rest.client.com.oath.micro.server; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +import java.util.Map; + +@Component +@Path("/generics") +public class RestClientResource implements RestResource { + + private final ImmutableList result = ImmutableList.of(new MyEntity()); + @GET + @Produces("application/json") + @Path("/get") + public ImmutableList get() { + + return result; + } + + @POST + @Produces("application/json") + @Path("/post") + public ImmutableList post(Map map) { + + return result; + } + + @PUT + @Produces("application/json") + @Path("/put") + public ImmutableList put(Map map) { + + return result; + } + @DELETE + @Produces("application/json") + @Path("/delete") + public ImmutableList delete(Map map) { + + return result; + } + + +} diff --git a/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/RestClientTest.java b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/RestClientTest.java new file mode 100644 index 000000000..deebb5bd6 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/rest/client/com/oath/micro/server/RestClientTest.java @@ -0,0 +1,138 @@ + +package app.rest.client.com.oath.micro.server; + + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutionException; + +import com.oath.micro.server.module.Module; +import cyclops.reactive.collections.mutable.SetX; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.web.client.RestClientException; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.rest.client.nio.NIORestClient; +import com.oath.micro.server.rest.client.nio.SpringConfig; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.oath.micro.server.spring.boot.MicroSpringBoot; + +@Microserver @MicroSpringBoot +@Ignore //not picking up Guava Jackson config +public class RestClientTest { + + private final AsyncRestClient> listClient = new AsyncRestClient(1000,1000).withResponse(List.class); + private final AsyncRestClient> setClient = new AsyncRestClient(1000,1000).withResponse(ImmutableSet.class);; + private final AsyncRestClient> genericsClient = new AsyncRestClient(1000,1000).withGenericResponse(ImmutableList.class, MyEntity.class); + + private final NIORestClient rest = new SpringConfig().restClient(); + + + MicroserverApp server; + static volatile boolean run = false; + @Before + public void startServer(){ + System.setProperty("java.util.logging.config.file","/C02W40GKHTDG/Users/jmcclean/github/micro-server/micro-spring-boot/src/test/resources/logging.properties"); + if(run) + return; + run = true; + + server = new MicroserverApp(RestClientTest.class, new Module() { + @Override + public Set getJaxRsResourceObjects() { + return SetX.of(new LoggingExMapper()); + } + + @Override + public String getContext() { + return "rest-app"; + } + }); + + + } + + + /* + * Simpler with JaxRsNIOClient + */ + @Test + public void testCRUD() throws InterruptedException, ExecutionException{ + + assertThat(listClient.get("http://localhost:8080/rest-app/rest/get").get().get(0),is("ok")); + try { + setClient.post("http://localhost:8080/rest-app/rest/post", ImmutableMap.of(1, "hello")).get(); + }catch(Exception e){ + e.printStackTrace(); + } + + assertThat(setClient.post("http://localhost:8080/rest-app/rest/post",ImmutableMap.of(1,"hello")).get(),is(ImmutableSet.of("hello"))); + + + assertThat(setClient.put("http://localhost:8080/rest-app/rest/put",ImmutableMap.of(1,"hello")).get(),is(ImmutableSet.of("hello"))); + assertThat(listClient.delete("http://localhost:8080/rest-app/rest/delete").get().get(0),is("ok")); + } + + + @Test + public void testCRUDGenerics() throws InterruptedException, ExecutionException{ + + + assertThat(genericsClient.get("http://localhost:8080/rest-app/generics/get").get().get(0),is(new MyEntity())); + assertThat(genericsClient.post("http://localhost:8080/rest-app/generics/post",ImmutableMap.of(1,"hello")).get(),is(ImmutableList.of(new MyEntity()))); + assertThat(genericsClient.put("http://localhost:8080/rest-app/generics/put",ImmutableMap.of(1,"hello")).get(),is(ImmutableList.of(new MyEntity()))); + assertThat(genericsClient.delete("http://localhost:8080/rest-app/generics/delete").get().get(0),is(new MyEntity())); + } + + /** + * More complex with Spring REST Template Based NIORestTemplate + * + **/ + @Test + public void testCRUDSpring() throws InterruptedException, ExecutionException, RestClientException, URISyntaxException{ + + + assertThat(rest.getForEntity(new URI("http://localhost:8080/rest-app/rest/get"),List.class).get().getBody().get(0),is("ok")); + + assertThat(rest.postForEntity("http://localhost:8080/rest-app/rest/post", new HttpEntity(ImmutableMap.of(1,"hello")), ImmutableSet.class).get().getBody(),is(ImmutableSet.of("hello"))); + assertThat( rest.put("http://localhost:8080/rest-app/rest/put",new HttpEntity(ImmutableMap.of(1,"hello")),ImmutableSet.class).get() + ,is(nullValue())); + assertThat(rest.delete("http://localhost:8080/rest-app/rest/delete").get(),is(nullValue())); + } + + @Test + public void testCRUDGenericsSpring() throws InterruptedException, ExecutionException{ + + + assertThat(rest.exchange("http://localhost:8080/rest-app/generics/get",HttpMethod.GET,null,new ParameterizedTypeReference>(){}) + .get().getBody().get(0),is(new MyEntity())); + + assertThat(rest.exchange("http://localhost:8080/rest-app/generics/post",HttpMethod.POST,new HttpEntity(ImmutableMap.of(1,"hello")),new ParameterizedTypeReference>(){}) + .get().getBody(),is(ImmutableList.of(new MyEntity()))); + + assertThat(rest.exchange("http://localhost:8080/rest-app/generics/put",HttpMethod.PUT,new HttpEntity(ImmutableMap.of(1,"hello")),new ParameterizedTypeReference>(){}) + .get().getBody(),is(ImmutableList.of(new MyEntity()))); + + assertThat(rest.exchange("http://localhost:8080/rest-app/generics/delete",HttpMethod.DELETE,null,new ParameterizedTypeReference>(){}) + .get().getBody().get(0),is(new MyEntity())); + + } + + + +} diff --git a/micro-spring-boot/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java b/micro-spring-boot/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java deleted file mode 100644 index af811647d..000000000 --- a/micro-spring-boot/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package app.simple.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.spring.boot.MicroSpringBoot; -import com.aol.micro.server.testing.RestAgent; -import com.aol.micro.server.spring.boot.MicroSpringBoot; - -@Microserver @MicroSpringBoot -public class SimpleRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( SimpleRunnerTest.class, ()-> "simple-app"); - - - } - - - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); - - - } - - - -} diff --git a/micro-spring-boot/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java b/micro-spring-boot/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java deleted file mode 100644 index 0093fe138..000000000 --- a/micro-spring-boot/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java +++ /dev/null @@ -1,28 +0,0 @@ -package app.simple.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Qualifier("simpleStatusResource") -@Path("/status") -public class SimpleStatusResource implements RestResource { - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java b/micro-spring-boot/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java new file mode 100644 index 000000000..97f8871f1 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java @@ -0,0 +1,45 @@ +package app.simple.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.spring.boot.MicroSpringBoot; +import com.oath.micro.server.testing.RestAgent; + +@Microserver @MicroSpringBoot +public class SimpleRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( SimpleRunnerTest.class, ()-> "simple-app"); + + + } + + + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); + + + } + + + +} diff --git a/micro-spring-boot/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java b/micro-spring-boot/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java new file mode 100644 index 000000000..97265ed02 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java @@ -0,0 +1,28 @@ +package app.simple.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Qualifier("simpleStatusResource") +@Path("/status") +public class SimpleStatusResource implements RestResource { + + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/spring/com/aol/micro/server/MyBean.java b/micro-spring-boot/src/test/java/app/spring/com/aol/micro/server/MyBean.java deleted file mode 100644 index 1f7a589ff..000000000 --- a/micro-spring-boot/src/test/java/app/spring/com/aol/micro/server/MyBean.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.spring.com.aol.micro.server; - -import javax.inject.Inject; - -import lombok.Getter; - -@Getter -public class MyBean { - - @Inject - private MyDependency injected; -} diff --git a/micro-spring-boot/src/test/java/app/spring/com/aol/micro/server/MyDependency.java b/micro-spring-boot/src/test/java/app/spring/com/aol/micro/server/MyDependency.java deleted file mode 100644 index 48d89e6c5..000000000 --- a/micro-spring-boot/src/test/java/app/spring/com/aol/micro/server/MyDependency.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.spring.com.aol.micro.server; - -import lombok.Getter; - -import org.springframework.stereotype.Component; - -@Component -@Getter -public class MyDependency { - - private String data = "hello world"; -} diff --git a/micro-spring-boot/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java b/micro-spring-boot/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java deleted file mode 100644 index 4f0b93786..000000000 --- a/micro-spring-boot/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package app.spring.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.springframework.context.annotation.Bean; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.spring.boot.MicroSpringBoot; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Microserver @MicroSpringBoot -public class SpringRunnerTest { - - RestAgent rest = new RestAgent(); - - @Bean - public MyBean mybean(){ - return new MyBean(); - } - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( SpringRunnerTest.class, ()-> "spring-app"); - - - } - - - @Test - public void testAutoWiring() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/spring-app/spring/ping"),is("hello world")); - - } - - - - - -} diff --git a/micro-spring-boot/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java b/micro-spring-boot/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java deleted file mode 100644 index 331ac997e..000000000 --- a/micro-spring-boot/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java +++ /dev/null @@ -1,32 +0,0 @@ -package app.spring.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/spring") -public class SpringStatusResource implements RestResource { - - @Autowired - private MyBean mybean; - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return mybean.getInjected().getData(); - } - @GET - @Produces("text/plain") - @Path("/ping2") - public String ping2() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/spring/com/oath/micro/server/MyBean.java b/micro-spring-boot/src/test/java/app/spring/com/oath/micro/server/MyBean.java new file mode 100644 index 000000000..328b7d185 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/spring/com/oath/micro/server/MyBean.java @@ -0,0 +1,12 @@ +package app.spring.com.oath.micro.server; + +import javax.inject.Inject; + +import lombok.Getter; + +@Getter +public class MyBean { + + @Inject + private MyDependency injected; +} diff --git a/micro-spring-boot/src/test/java/app/spring/com/oath/micro/server/MyDependency.java b/micro-spring-boot/src/test/java/app/spring/com/oath/micro/server/MyDependency.java new file mode 100644 index 000000000..1ca23b15b --- /dev/null +++ b/micro-spring-boot/src/test/java/app/spring/com/oath/micro/server/MyDependency.java @@ -0,0 +1,12 @@ +package app.spring.com.oath.micro.server; + +import lombok.Getter; + +import org.springframework.stereotype.Component; + +@Component +@Getter +public class MyDependency { + + private String data = "hello world"; +} diff --git a/micro-spring-boot/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java b/micro-spring-boot/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java new file mode 100644 index 000000000..3f114b966 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java @@ -0,0 +1,49 @@ +package app.spring.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.annotation.Bean; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.spring.boot.MicroSpringBoot; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver @MicroSpringBoot +public class SpringRunnerTest { + + RestAgent rest = new RestAgent(); + + @Bean + public MyBean mybean(){ + return new MyBean(); + } + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( SpringRunnerTest.class, ()-> "spring-app"); + + + } + + + @Test + public void testAutoWiring() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/spring-app/spring/ping"),is("hello world")); + + } + + + + + +} diff --git a/micro-spring-boot/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java b/micro-spring-boot/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java new file mode 100644 index 000000000..ae0c817de --- /dev/null +++ b/micro-spring-boot/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java @@ -0,0 +1,32 @@ +package app.spring.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/spring") +public class SpringStatusResource implements RestResource { + + @Autowired + private MyBean mybean; + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return mybean.getInjected().getData(); + } + @GET + @Produces("text/plain") + @Path("/ping2") + public String ping2() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-spring-boot/src/test/java/app/swagger/com/aol/micro/server/StatsResource.java b/micro-spring-boot/src/test/java/app/swagger/com/aol/micro/server/StatsResource.java deleted file mode 100644 index 3d3516a41..000000000 --- a/micro-spring-boot/src/test/java/app/swagger/com/aol/micro/server/StatsResource.java +++ /dev/null @@ -1,31 +0,0 @@ -package app.swagger.com.aol.micro.server; - -import java.util.List; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -import com.google.common.collect.ImmutableList; -import com.wordnik.swagger.annotations.Api; -import com.wordnik.swagger.annotations.ApiOperation; - - -@Path("/stats") -@Component -@Api(value = "/stats", description = "Resource to show stats for a box using sigar") -public class StatsResource implements RestResource { - - - - @GET - @Path("/ping") - @Produces("application/json") - @ApiOperation(value = "Make a ping call", response = List.class) - public List getMachineStats() { - return ImmutableList.of(1); - } -} diff --git a/micro-spring-boot/src/test/java/app/swagger/com/aol/micro/server/SwaggerRunnerTest.java b/micro-spring-boot/src/test/java/app/swagger/com/aol/micro/server/SwaggerRunnerTest.java deleted file mode 100644 index 80eb62942..000000000 --- a/micro-spring-boot/src/test/java/app/swagger/com/aol/micro/server/SwaggerRunnerTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package app.swagger.com.aol.micro.server; - -import static org.hamcrest.Matchers.containsString; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.testing.RestAgent; -import com.aol.micro.server.module.Module; -import com.aol.micro.server.spring.boot.MicroSpringBoot; - -@Configuration -@ComponentScan(basePackages = { "app.swagger.com.aol.micro.server" }) -@MicroSpringBoot // needs some work for spring-boot -public class SwaggerRunnerTest implements Module{ - - - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( SwaggerRunnerTest.class,this); - - - } - - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.getJson("http://localhost:8080/swagger-app/stats/ping"),containsString("1")); - assertThat(rest.getJson("http://localhost:8080/swagger-app/api-docs"),containsString("apiVersion")); - - } - - - @Override - public String getContext() { - return "swagger-app"; - } - - - -} diff --git a/micro-spring-boot/src/test/java/app/swagger/com/oath/micro/server/StatsResource.java b/micro-spring-boot/src/test/java/app/swagger/com/oath/micro/server/StatsResource.java new file mode 100644 index 000000000..848d10205 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/swagger/com/oath/micro/server/StatsResource.java @@ -0,0 +1,31 @@ +package app.swagger.com.oath.micro.server; + +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +import com.google.common.collect.ImmutableList; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; + + +@Path("/stats") +@Component +@Api(value = "/stats", description = "Resource to show stats for a box using sigar") +public class StatsResource implements RestResource { + + + + @GET + @Path("/ping") + @Produces("application/json") + @ApiOperation(value = "Make a ping call", response = List.class) + public List getMachineStats() { + return ImmutableList.of(1); + } +} diff --git a/micro-spring-boot/src/test/java/app/swagger/com/oath/micro/server/SwaggerRunnerTest.java b/micro-spring-boot/src/test/java/app/swagger/com/oath/micro/server/SwaggerRunnerTest.java new file mode 100644 index 000000000..07f6382b1 --- /dev/null +++ b/micro-spring-boot/src/test/java/app/swagger/com/oath/micro/server/SwaggerRunnerTest.java @@ -0,0 +1,55 @@ +package app.swagger.com.oath.micro.server; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; +import com.oath.micro.server.module.Module; +import com.oath.micro.server.spring.boot.MicroSpringBoot; + +@Configuration +@ComponentScan(basePackages = { "app.swagger.com.oath.micro.server" }) +@MicroSpringBoot // needs some work for spring-boot +public class SwaggerRunnerTest implements Module{ + + + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( SwaggerRunnerTest.class,this); + + + } + + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.getJson("http://localhost:8080/swagger-app/stats/ping"),containsString("1")); + assertThat(rest.getJson("http://localhost:8080/swagger-app/api-docs"),containsString("apiVersion")); + + } + + + @Override + public String getContext() { + return "swagger-app"; + } + + + +} diff --git a/micro-spring-boot/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-spring-boot/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-spring-boot/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-spring-boot/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-spring-boot/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-spring-boot/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-swagger/README.md b/micro-swagger/README.md new file mode 100644 index 000000000..08d903763 --- /dev/null +++ b/micro-swagger/README.md @@ -0,0 +1,21 @@ +# Swagger plugin for Microserver + +[micro-swagger example apps](https://github.com/aol/micro-server/tree/master/micro-swagger/src/test/java/app/swagger/com/aol/micro/server) + +Also can run standalone outside of Microserver + +## To use + +Simply add to the classpath + +Maven + + + com.oath.microservices + micro-swagger + 0.62 + + +Gradle + + compile 'com.oath.microservices:micro-swagger:0.62' diff --git a/micro-swagger/build.gradle b/micro-swagger/build.gradle index bff2308b1..cb3663bd3 100644 --- a/micro-swagger/build.gradle +++ b/micro-swagger/build.gradle @@ -1,58 +1,59 @@ description = 'micro-swagger' + dependencies { - compile group: 'com.wordnik', name: 'swagger-jersey2-jaxrs_2.10', version:'1.3.10' - compile project(':micro-core') - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') - testCompile project(':micro-jackson-configuration') + compile group: 'com.wordnik', name: 'swagger-jersey2-jaxrs_2.10', version: '1.3.10' + compile project(':micro-core') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') + testCompile project(':micro-jackson-configuration') } modifyPom { - project { - name 'Microserver : swagger' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-swagger' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - } - - } + project { + name 'Microserver : swagger' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-swagger' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + } + + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-swagger/readme.md b/micro-swagger/readme.md deleted file mode 100644 index 8b1f405bd..000000000 --- a/micro-swagger/readme.md +++ /dev/null @@ -1,21 +0,0 @@ -# Swagger plugin for Microserver - -[micro-swagger example apps](https://github.com/aol/micro-server/tree/master/micro-swagger/src/test/java/app/swagger/com/aol/micro/server) - -Also can run standalone outside of Microserver - -## To use - -Simply add to the classpath - -Maven - - - com.aol.microservices - micro-swagger - 0.62 - - -Gradle - - compile 'com.aol.microservices:micro-swagger:0.62' \ No newline at end of file diff --git a/micro-swagger/src/main/java/com/aol/micro/server/rest/swagger/SwaggerPlugin.java b/micro-swagger/src/main/java/com/aol/micro/server/rest/swagger/SwaggerPlugin.java deleted file mode 100644 index fa78f4271..000000000 --- a/micro-swagger/src/main/java/com/aol/micro/server/rest/swagger/SwaggerPlugin.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.aol.micro.server.rest.swagger; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; -import java.util.function.Function; - -import javax.servlet.ServletContextListener; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.cyclops.util.function.Lambda; -import com.aol.micro.server.Plugin; -import com.aol.micro.server.servers.model.ServerData; -import com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON; -import com.wordnik.swagger.jersey.listing.JerseyApiDeclarationProvider; -import com.wordnik.swagger.jersey.listing.JerseyResourceListingProvider; - -/** - * - * Collections of Spring configuration classes (Classes annotated with @Configuration) - * that configure various useful pieces of functionality - such as property file loading, - * datasources, scheduling etc - * - * @author johnmcclean - * - */ -public class SwaggerPlugin implements Plugin{ - - @Override - public PSetX springClasses() { - return PSetX.empty(); - } - - @Override - public PSetX> servletContextListeners(){ - return PSetX.of(Lambda.l1(serverData -> new SwaggerInitializer(serverData))); - - } - - @Override - public PSetX> jaxRsResources() { - return PSetX.of(ApiListingResourceJSON.class,JerseyApiDeclarationProvider.class, - JerseyResourceListingProvider.class); - } - - @Override - public PSetX jaxRsPackages() { - return PSetX.of("com.wordnik.swagger.sample.resource", - "com.wordnik.swagger.sample.util" ); - } -} diff --git a/micro-swagger/src/main/java/com/aol/micro/server/rest/swagger/SwaggerInitializer.java b/micro-swagger/src/main/java/com/oath/micro/server/rest/swagger/SwaggerInitializer.java similarity index 84% rename from micro-swagger/src/main/java/com/aol/micro/server/rest/swagger/SwaggerInitializer.java rename to micro-swagger/src/main/java/com/oath/micro/server/rest/swagger/SwaggerInitializer.java index 134ed37e4..62d17f85e 100644 --- a/micro-swagger/src/main/java/com/aol/micro/server/rest/swagger/SwaggerInitializer.java +++ b/micro-swagger/src/main/java/com/oath/micro/server/rest/swagger/SwaggerInitializer.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.rest.swagger; +package com.oath.micro.server.rest.swagger; import java.util.stream.Collectors; @@ -7,15 +7,10 @@ import javax.servlet.ServletContextListener; import javax.ws.rs.core.Application; -import lombok.Setter; - -import org.springframework.beans.factory.annotation.Autowired; - import scala.collection.JavaConversions; import scala.collection.immutable.List; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.servers.model.ServerData; +import com.oath.micro.server.servers.model.ServerData; import com.wordnik.swagger.jaxrs.config.BeanConfig; public class SwaggerInitializer implements ServletContextListener { diff --git a/micro-swagger/src/main/java/com/oath/micro/server/rest/swagger/SwaggerPlugin.java b/micro-swagger/src/main/java/com/oath/micro/server/rest/swagger/SwaggerPlugin.java new file mode 100644 index 000000000..706a33e5e --- /dev/null +++ b/micro-swagger/src/main/java/com/oath/micro/server/rest/swagger/SwaggerPlugin.java @@ -0,0 +1,50 @@ +package com.oath.micro.server.rest.swagger; + +import java.util.Set; +import java.util.function.Function; + +import javax.servlet.ServletContextListener; + + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.servers.model.ServerData; +import com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON; +import com.wordnik.swagger.jersey.listing.JerseyApiDeclarationProvider; +import com.wordnik.swagger.jersey.listing.JerseyResourceListingProvider; +import cyclops.reactive.collections.mutable.SetX; +import cyclops.function.Lambda; + +/** + * + * Collections of Spring configuration classes (Classes annotated with @Configuration) + * that configure various useful pieces of functionality - such as property file loading, + * datasources, scheduling etc + * + * @author johnmcclean + * + */ +public class SwaggerPlugin implements Plugin{ + + @Override + public Set springClasses() { + return SetX.empty(); + } + + @Override + public Set> servletContextListeners(){ + return SetX.of(Lambda.l1(serverData -> new SwaggerInitializer(serverData))); + + } + + @Override + public Set> jaxRsResources() { + return SetX.of(ApiListingResourceJSON.class,JerseyApiDeclarationProvider.class, + JerseyResourceListingProvider.class); + } + + @Override + public Set jaxRsPackages() { + return SetX.of("com.wordnik.swagger.sample.resource", + "com.wordnik.swagger.sample.util" ); + } +} diff --git a/micro-swagger/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-swagger/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index af043f2d8..000000000 --- a/micro-swagger/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.rest.swagger.SwaggerPlugin \ No newline at end of file diff --git a/micro-swagger/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-swagger/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..cc13efc43 --- /dev/null +++ b/micro-swagger/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.rest.swagger.SwaggerPlugin \ No newline at end of file diff --git a/micro-swagger/src/test/java/app/swagger/com/aol/micro/server/StatsResource.java b/micro-swagger/src/test/java/app/swagger/com/aol/micro/server/StatsResource.java deleted file mode 100644 index 3d3516a41..000000000 --- a/micro-swagger/src/test/java/app/swagger/com/aol/micro/server/StatsResource.java +++ /dev/null @@ -1,31 +0,0 @@ -package app.swagger.com.aol.micro.server; - -import java.util.List; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -import com.google.common.collect.ImmutableList; -import com.wordnik.swagger.annotations.Api; -import com.wordnik.swagger.annotations.ApiOperation; - - -@Path("/stats") -@Component -@Api(value = "/stats", description = "Resource to show stats for a box using sigar") -public class StatsResource implements RestResource { - - - - @GET - @Path("/ping") - @Produces("application/json") - @ApiOperation(value = "Make a ping call", response = List.class) - public List getMachineStats() { - return ImmutableList.of(1); - } -} diff --git a/micro-swagger/src/test/java/app/swagger/com/aol/micro/server/SwaggerRunnerTest.java b/micro-swagger/src/test/java/app/swagger/com/aol/micro/server/SwaggerRunnerTest.java deleted file mode 100644 index 2f05228b3..000000000 --- a/micro-swagger/src/test/java/app/swagger/com/aol/micro/server/SwaggerRunnerTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package app.swagger.com.aol.micro.server; - -import static org.hamcrest.Matchers.containsString; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.testing.RestAgent; - -@Configuration -@ComponentScan(basePackages = { "app.swagger.com.aol.micro.server" }) -public class SwaggerRunnerTest { - - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp( SwaggerRunnerTest.class, ()-> "swagger-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.getJson("http://localhost:8080/api-docs/stats"),containsString("Make a ping call")); - - } - - - -} diff --git a/micro-swagger/src/test/java/app/swagger/com/oath/micro/server/StatsResource.java b/micro-swagger/src/test/java/app/swagger/com/oath/micro/server/StatsResource.java new file mode 100644 index 000000000..848d10205 --- /dev/null +++ b/micro-swagger/src/test/java/app/swagger/com/oath/micro/server/StatsResource.java @@ -0,0 +1,31 @@ +package app.swagger.com.oath.micro.server; + +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +import com.google.common.collect.ImmutableList; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; + + +@Path("/stats") +@Component +@Api(value = "/stats", description = "Resource to show stats for a box using sigar") +public class StatsResource implements RestResource { + + + + @GET + @Path("/ping") + @Produces("application/json") + @ApiOperation(value = "Make a ping call", response = List.class) + public List getMachineStats() { + return ImmutableList.of(1); + } +} diff --git a/micro-swagger/src/test/java/app/swagger/com/oath/micro/server/SwaggerRunnerTest.java b/micro-swagger/src/test/java/app/swagger/com/oath/micro/server/SwaggerRunnerTest.java new file mode 100644 index 000000000..5f9c6351c --- /dev/null +++ b/micro-swagger/src/test/java/app/swagger/com/oath/micro/server/SwaggerRunnerTest.java @@ -0,0 +1,49 @@ +package app.swagger.com.oath.micro.server; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; + +@Configuration +@ComponentScan(basePackages = { "app.swagger.com.oath.micro.server" }) +public class SwaggerRunnerTest { + + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp( SwaggerRunnerTest.class, ()-> "swagger-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.getJson("http://localhost:8080/api-docs/stats"),containsString("Make a ping call")); + + } + + + +} diff --git a/micro-swagger/src/test/java/com/aol/micro/server/rest/swagger/ServletStatusResource.java b/micro-swagger/src/test/java/com/aol/micro/server/rest/swagger/ServletStatusResource.java deleted file mode 100644 index cb9d826ef..000000000 --- a/micro-swagger/src/test/java/com/aol/micro/server/rest/swagger/ServletStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aol.micro.server.rest.swagger; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/servlet") -public class ServletStatusResource implements RestResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-swagger/src/test/java/com/aol/micro/server/rest/swagger/SwaggerInitializerTest.java b/micro-swagger/src/test/java/com/aol/micro/server/rest/swagger/SwaggerInitializerTest.java deleted file mode 100644 index 78b927b97..000000000 --- a/micro-swagger/src/test/java/com/aol/micro/server/rest/swagger/SwaggerInitializerTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.aol.micro.server.rest.swagger; - -import org.junit.Test; - -import com.aol.cyclops.data.collections.extensions.persistent.PStackX; -import com.aol.micro.server.servers.model.ServerData; -import com.google.common.collect.ImmutableList; - -public class SwaggerInitializerTest { - - @Test - public void testContextInitialized() { - SwaggerInitializer initializer = new SwaggerInitializer(ServerData.builder().resources(PStackX.of(new ServletStatusResource())).build()); - ServerData serverData = new ServerData(8080, ImmutableList.of(new ServletStatusResource()), null, "url", () -> "context"); - - initializer.contextInitialized(null); - } - -} - diff --git a/micro-swagger/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-swagger/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-swagger/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-swagger/src/test/java/com/oath/micro/server/rest/swagger/ServletStatusResource.java b/micro-swagger/src/test/java/com/oath/micro/server/rest/swagger/ServletStatusResource.java new file mode 100644 index 000000000..434d0af4a --- /dev/null +++ b/micro-swagger/src/test/java/com/oath/micro/server/rest/swagger/ServletStatusResource.java @@ -0,0 +1,22 @@ +package com.oath.micro.server.rest.swagger; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/servlet") +public class ServletStatusResource implements RestResource { + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-swagger/src/test/java/com/oath/micro/server/rest/swagger/SwaggerInitializerTest.java b/micro-swagger/src/test/java/com/oath/micro/server/rest/swagger/SwaggerInitializerTest.java new file mode 100644 index 000000000..ee5456b10 --- /dev/null +++ b/micro-swagger/src/test/java/com/oath/micro/server/rest/swagger/SwaggerInitializerTest.java @@ -0,0 +1,21 @@ +package com.oath.micro.server.rest.swagger; + +import cyclops.reactive.collections.immutable.LinkedListX; +import org.junit.Test; + + +import com.oath.micro.server.servers.model.ServerData; +import com.google.common.collect.ImmutableList; + +public class SwaggerInitializerTest { + + @Test + public void testContextInitialized() { + SwaggerInitializer initializer = new SwaggerInitializer(ServerData.builder().resources(LinkedListX.of(new ServletStatusResource())).build()); + ServerData serverData = new ServerData(8080, ImmutableList.of(new ServletStatusResource()), null, "url", () -> "context"); + + initializer.contextInitialized(null); + } + +} + diff --git a/micro-swagger/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-swagger/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-swagger/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-tomcat-with-jersey/README.md b/micro-tomcat-with-jersey/README.md new file mode 100644 index 000000000..c38f97851 --- /dev/null +++ b/micro-tomcat-with-jersey/README.md @@ -0,0 +1,29 @@ +# Tomcat, Jersey and Microserver together + +[Example Tomcat & Jersey Apps](https://github.com/aol/micro-server/tree/master/micro-tomcat/src/test/java/app) + +Convenience module that packages Tomcat, Jersey, Jackson and Microserver together + +## Note + +Tomcat does not currently support the Microserver micro-monolith style of development where by multiple Microservers can be rolled up into a single 'monolithic' style services at runtime. If you require that type of functionality take a look at micro-grizzly instead. + + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-grizzly-with-jersey/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-grizzly-with-jersey) + +Simply add to the classpath + +Maven +```xml + + com.oath.microservices + micro-tomcat-with-jersey + x.yz + +``` +Gradle +```groovy + compile 'com.oath.microservices:micro-tomcat-with-jersey:x.yz' +``` diff --git a/micro-tomcat-with-jersey/build.gradle b/micro-tomcat-with-jersey/build.gradle index 6cd4a4f6d..5c2012630 100644 --- a/micro-tomcat-with-jersey/build.gradle +++ b/micro-tomcat-with-jersey/build.gradle @@ -1,62 +1,65 @@ description = 'micro-tomcat-with-jersey' -dependencies { - compile project(':micro-core') - compile project(':micro-tomcat') - compile project(':micro-jersey') - compile project(':micro-jackson-configuration') - - +dependencies { + compile project(':micro-core') + compile project(':micro-tomcat') + compile project(':micro-jersey') + compile project(':micro-jackson-configuration') + testCompile "com.oath.cyclops:cyclops-futurestream:$cyclopsVersion" } modifyPom { - project { - name 'Microserver Tomcat With Jersey' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-tomcat-with-jersey' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - - } - - } + + project { + name 'Microserver Tomcat With Jersey' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-tomcat-with-jersey' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + + } + + } +} +test { + forkEvery = 1 } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-tomcat-with-jersey/readme.md b/micro-tomcat-with-jersey/readme.md deleted file mode 100644 index 322b7949f..000000000 --- a/micro-tomcat-with-jersey/readme.md +++ /dev/null @@ -1,29 +0,0 @@ -# Tomcat, Jersey and Microserver together - -[Example Tomcat & Jersey Apps](https://github.com/aol/micro-server/tree/master/micro-tomcat/src/test/java/app) - -Convenience module that packages Tomcat, Jersey, Jackson and Microserver together - -## Note - -Tomcat does not currently support the Microserver micro-monolith style of development where by multiple Microservers can be rolled up into a single 'monolithic' style services at runtime. If you require that type of functionality take a look at micro-grizzly instead. - - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-grizzly-with-jersey/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-grizzly-with-jersey) - -Simply add to the classpath - -Maven -```xml - - com.aol.microservices - micro-tomcat-with-jersey - x.yz - -``` -Gradle -```groovy - compile 'com.aol.microservices:micro-tomcat-with-jersey:x.yz' -``` \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/access/log/micro/server/servers/AccessLogConfigTest.java b/micro-tomcat-with-jersey/src/test/java/app/access/log/micro/server/servers/AccessLogConfigTest.java index 275aa8b17..7fff1987b 100644 --- a/micro-tomcat-with-jersey/src/test/java/app/access/log/micro/server/servers/AccessLogConfigTest.java +++ b/micro-tomcat-with-jersey/src/test/java/app/access/log/micro/server/servers/AccessLogConfigTest.java @@ -11,8 +11,8 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; @Microserver(properties={"access.log.output", "${user.home}"}) public class AccessLogConfigTest { diff --git a/micro-tomcat-with-jersey/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java b/micro-tomcat-with-jersey/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java deleted file mode 100644 index a5b427b75..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java +++ /dev/null @@ -1,58 +0,0 @@ -package app.async.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.io.IOException; -import java.util.Properties; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.spring.properties.PropertyFileConfig; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class AsyncAppRunner { - - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - - server = new MicroserverApp( ()-> "async-app"); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - Thread.sleep(2000); - - assertThat(rest.get("http://localhost:8080/async-app/async/expensive"),is(";test!;test!;test!")); - - } - - @Test - public void loadProperties() throws IOException{ - - Properties props = new PropertyFileConfig(true).propertyFactory() ; - assertThat(props.getProperty("test"),is("hello world")); - } - - - -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/async/com/aol/micro/server/AsyncResource.java b/micro-tomcat-with-jersey/src/test/java/app/async/com/aol/micro/server/AsyncResource.java deleted file mode 100644 index d87c018d6..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/async/com/aol/micro/server/AsyncResource.java +++ /dev/null @@ -1,56 +0,0 @@ -package app.async.com.aol.micro.server; - -import java.util.Arrays; -import java.util.List; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.container.Suspended; - -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.testing.RestAgent; - -@Path("/async") -@Component -public class AsyncResource implements RestResource{ - - private final SimpleReact simpleReact =new SimpleReact(); - private final List urls = Arrays.asList("http://localhost:8080/async-app/async/ping2", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping"); - - private final RestAgent client = new RestAgent(); - - @GET - @Path("/expensive") - @Produces("text/plain") - public void expensive(@Suspended AsyncResponse asyncResponse){ - - LazyFutureStream.lazyFutureStreamFromIterable(urls) - .then(it->client.get(it)) - .onFail(it -> "") - .peek(it -> - System.out.println(it)) - .convertToSimpleReact() - .allOf(data -> { - System.out.println(data); - return asyncResponse.resume(ReactiveSeq.fromIterable(data).join(";")); }); - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/async/com/aol/micro/server/Simple.java b/micro-tomcat-with-jersey/src/test/java/app/async/com/aol/micro/server/Simple.java deleted file mode 100644 index edefa80ef..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/async/com/aol/micro/server/Simple.java +++ /dev/null @@ -1,16 +0,0 @@ -package app.async.com.aol.micro.server; - -import java.io.IOException; -import java.util.Properties; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.spring.properties.PropertyFileConfig; - -public class Simple { - - public static void main(String[] args) throws IOException{ - - new MicroserverApp(()->"test-app").run(); - } -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/async/com/aol/micro/server/SimpleApp.java b/micro-tomcat-with-jersey/src/test/java/app/async/com/aol/micro/server/SimpleApp.java deleted file mode 100644 index 919b7c6b0..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/async/com/aol/micro/server/SimpleApp.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.async.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; - - - -@Rest -@Path("/test") -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()->"test-app").run(); - } - @GET - public String myEndPoint(){ - return "hello world!"; - } - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java b/micro-tomcat-with-jersey/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java new file mode 100644 index 000000000..79933ea7a --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java @@ -0,0 +1,58 @@ +package app.async.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.Properties; +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.spring.properties.PropertyFileConfig; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class AsyncAppRunner { + + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + + server = new MicroserverApp( ()-> "async-app"); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + Thread.sleep(2000); + + assertThat(rest.get("http://localhost:8080/async-app/async/expensive"),is(";test!;test!;test!")); + + } + + @Test + public void loadProperties() throws IOException{ + + Properties props = new PropertyFileConfig(true).propertyFactory() ; + assertThat(props.getProperty("test"),is("hello world")); + } + + + +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/async/com/oath/micro/server/AsyncResource.java b/micro-tomcat-with-jersey/src/test/java/app/async/com/oath/micro/server/AsyncResource.java new file mode 100644 index 000000000..cb2193ce4 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/async/com/oath/micro/server/AsyncResource.java @@ -0,0 +1,57 @@ +package app.async.com.oath.micro.server; + +import java.util.Arrays; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; + +import cyclops.futurestream.SimpleReact; +import cyclops.futurestream.FutureStream; +import cyclops.reactive.ReactiveSeq; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.testing.RestAgent; + +@Path("/async") +@Component +public class AsyncResource implements RestResource{ + + private final SimpleReact simpleReact =new SimpleReact(); + private final List urls = Arrays.asList("http://localhost:8080/async-app/async/ping2", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping"); + + private final RestAgent client = new RestAgent(); + + @GET + @Path("/expensive") + @Produces("text/plain") + public void expensive(@Suspended AsyncResponse asyncResponse){ + + FutureStream.builder().fromIterable(urls) + .then(it->client.get(it)) + .onFail(it -> "") + .peek(it -> + System.out.println(it)) + .convertToSimpleReact() + .allOf(data -> { + System.out.println(data); + return asyncResponse.resume(ReactiveSeq.fromIterable(data).join(";")); }); + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "test!"; + } + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/async/com/oath/micro/server/Simple.java b/micro-tomcat-with-jersey/src/test/java/app/async/com/oath/micro/server/Simple.java new file mode 100644 index 000000000..3eb3e7504 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/async/com/oath/micro/server/Simple.java @@ -0,0 +1,13 @@ +package app.async.com.oath.micro.server; + +import java.io.IOException; + +import com.oath.micro.server.MicroserverApp; + +public class Simple { + + public static void main(String[] args) throws IOException{ + + new MicroserverApp(()->"test-app").run(); + } +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/async/com/oath/micro/server/SimpleApp.java b/micro-tomcat-with-jersey/src/test/java/app/async/com/oath/micro/server/SimpleApp.java new file mode 100644 index 000000000..916d0330e --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/async/com/oath/micro/server/SimpleApp.java @@ -0,0 +1,24 @@ +package app.async.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; + + + +@Rest +@Path("/test") +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()->"test-app").run(); + } + @GET + public String myEndPoint(){ + return "hello world!"; + } + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleApp.java b/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleApp.java deleted file mode 100644 index 37a92de67..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleApp.java +++ /dev/null @@ -1,18 +0,0 @@ -package app.blacklisted.com.aol.micro.server.copy; - -import java.util.Arrays; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; - -public class SimpleApp { - - public static void main(String[] args){ - - new MicroserverApp(()-> "simple-app").run(); - } - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleRunnerTest.java deleted file mode 100644 index 010676089..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleRunnerTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package app.blacklisted.com.aol.micro.server.copy; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import nonautoscan.com.aol.micro.server.ScheduleAndAsyncConfig; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(blacklistedClasses={ScheduleAndAsyncConfig.class}) -public class SimpleRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); - - - } - - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleStatusResource.java b/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleStatusResource.java deleted file mode 100644 index 3ad8426ad..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/aol/micro/server/copy/SimpleStatusResource.java +++ /dev/null @@ -1,53 +0,0 @@ -package app.blacklisted.com.aol.micro.server.copy; - -import java.io.InputStream; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -import nonautoscan.com.aol.micro.server.ScheduleAndAsyncConfig; - -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; -import org.glassfish.jersey.media.multipart.FormDataParam; -import org.junit.Assert; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class SimpleStatusResource { - - @Autowired - ApplicationContext context; - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - try{ - context.getBean(ScheduleAndAsyncConfig.class); - Assert.fail("failed to remove ScheduleAndAsyncConfig bean!"); - }catch(NoSuchBeanDefinitionException e){ - - } - return "ok"; - } - - @POST - @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces(MediaType.TEXT_PLAIN) - @Path("/file") - public String create( - @FormDataParam("file") InputStream fileInputStream, - @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { - - return "done"; - } -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleApp.java b/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleApp.java new file mode 100644 index 000000000..f73582b0c --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleApp.java @@ -0,0 +1,13 @@ +package app.blacklisted.com.oath.micro.server.copy; + +import com.oath.micro.server.MicroserverApp; + +public class SimpleApp { + + public static void main(String[] args){ + + new MicroserverApp(()-> "simple-app").run(); + } + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleRunnerTest.java new file mode 100644 index 000000000..13c14e435 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleRunnerTest.java @@ -0,0 +1,57 @@ +package app.blacklisted.com.oath.micro.server.copy; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import nonautoscan.com.oath.micro.server.ScheduleAndAsyncConfig; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(blacklistedClasses={ScheduleAndAsyncConfig.class}) +public class SimpleRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); + + + } + + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleStatusResource.java b/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleStatusResource.java new file mode 100644 index 000000000..4370e7e9a --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/blacklisted/com/oath/micro/server/copy/SimpleStatusResource.java @@ -0,0 +1,53 @@ +package app.blacklisted.com.oath.micro.server.copy; + +import java.io.InputStream; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import nonautoscan.com.oath.micro.server.ScheduleAndAsyncConfig; + +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; +import org.junit.Assert; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class SimpleStatusResource { + + @Autowired + ApplicationContext context; + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + try{ + context.getBean(ScheduleAndAsyncConfig.class); + Assert.fail("failed to remove ScheduleAndAsyncConfig bean!"); + }catch(NoSuchBeanDefinitionException e){ + + } + return "ok"; + } + + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.TEXT_PLAIN) + @Path("/file") + public String create( + @FormDataParam("file") InputStream fileInputStream, + @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { + + return "done"; + } +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/custom/binder/test/SimpleApp.java b/micro-tomcat-with-jersey/src/test/java/app/custom/binder/test/SimpleApp.java index 7a2c74e08..2e275f0bd 100644 --- a/micro-tomcat-with-jersey/src/test/java/app/custom/binder/test/SimpleApp.java +++ b/micro-tomcat-with-jersey/src/test/java/app/custom/binder/test/SimpleApp.java @@ -5,9 +5,9 @@ import org.glassfish.jersey.server.ResourceConfig; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.module.ConfigurableModule; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.module.ConfigurableModule; diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java deleted file mode 100644 index d4b8eff5c..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java +++ /dev/null @@ -1,23 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.ArrayList; -import java.util.List; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -@Component -@Path("/alt-status") -public class AltAppResource implements AltAppRestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public List ping(ImmutableEntity entity) { - return entity.getList(); - } - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java deleted file mode 100644 index 8cb2643e3..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface AltAppRestResource extends RestResource { - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java deleted file mode 100644 index bc73c2862..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.Arrays; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.EmbeddedModule; - -@Microserver(basePackages = { "app.embedded.com.aol.micro.server" }) -public class EmbeddedAppLocalMain { - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( - EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")).start(); - - - - } - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java deleted file mode 100644 index efe66003c..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java +++ /dev/null @@ -1,104 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.NotFoundException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.EmbeddedModule; -import com.aol.micro.server.testing.RestAgent; - -@Ignore //embedded - micro-monolith style doesn't work with Tomcat due to MBean naming collisions -public class EmbeddedAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer(){ - server = new MicroserverApp(EmbeddedAppLocalMain.class, - EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")); - server.start(); - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); - - - assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), - hasItem("hello")); - - } - - - @Test - public void nonBlockingRestClientTest(){ - assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"),is("-*test!-*test!")); - } - - CompletableFuture toCompletableFuture( - final ListenableFuture listenableFuture - ) { - //create an instance of CompletableFuture - CompletableFuture completable = new CompletableFuture() { - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - // propagate cancel to the listenable future - boolean result = listenableFuture.cancel(mayInterruptIfRunning); - super.cancel(mayInterruptIfRunning); - return result; - } - }; - - // add callback - listenableFuture.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(T result) { - completable.complete(result); - } - - @Override - public void onFailure(Throwable t) { - completable.completeExceptionally(t); - } - }); - return completable; - } - - @Test(expected=NotFoundException.class) - public void confirmAltAppCantUseTestAppResources(){ - - assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); - - } - @Test(expected=NotFoundException.class) - public void confirmTestAppCantUseAltAppResources(){ - - assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), - hasItem("hello")); - - } -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java deleted file mode 100644 index 778c55c90..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java +++ /dev/null @@ -1,29 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableEntity { - - private final String value; - private final List list; - - public ImmutableEntity() { - this(null,null); - } - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java deleted file mode 100644 index e93d43724..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java +++ /dev/null @@ -1,48 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.Arrays; -import java.util.List; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.micro.server.testing.RestAgent; -@Component -@Path("/test-status") -public class TestAppResource implements TestAppRestResource { - - private final SimpleReact simpleReact = new SimpleReact(); - private final RestAgent template = new RestAgent(); - private final List urls = Arrays.asList("http://localhost:8081/alternative-app/alt-status/ping", - "http://localhost:8080/test-app/test-status/ping", - "http://localhost:8082/simple-app/status/ping", - "http://localhost:8080/test-app/test-status/ping"); - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - @GET - @Produces("text/plain") - @Path("/rest-calls") - public String restCallResult(){ - - return LazyFutureStream.lazyFutureStreamFromIterable(urls) - .map(it ->template.get(it)) - .then(it -> "*"+it) - .peek(loadedAndModified -> System.out.println(loadedAndModified)) - .block().stream().reduce("", (acc,next) -> acc+"-"+next); - - } - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java deleted file mode 100644 index 3133fd8cc..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface TestAppRestResource extends RestResource { - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java new file mode 100644 index 000000000..1835ababe --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java @@ -0,0 +1,22 @@ +package app.embedded.com.oath.micro.server; + +import java.util.List; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +@Component +@Path("/alt-status") +public class AltAppResource implements AltAppRestResource { + + @POST + @Produces("application/json") + @Path("/ping") + public List ping(ImmutableEntity entity) { + return entity.getList(); + } + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java new file mode 100644 index 000000000..7045a4f35 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java @@ -0,0 +1,7 @@ +package app.embedded.com.oath.micro.server; + +import com.oath.micro.server.auto.discovery.RestResource; + +public interface AltAppRestResource extends RestResource { + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java new file mode 100644 index 000000000..dbb290069 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java @@ -0,0 +1,24 @@ +package app.embedded.com.oath.micro.server; + +import java.util.Arrays; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.EmbeddedModule; + +@Microserver(basePackages = { "app.embedded.com.oath.micro.server" }) +public class EmbeddedAppLocalMain { + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( + EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), + EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")).start(); + + + + } + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java new file mode 100644 index 000000000..bc2c5e09b --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java @@ -0,0 +1,104 @@ +package app.embedded.com.oath.micro.server; + +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.NotFoundException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.util.concurrent.ListenableFuture; +import org.springframework.util.concurrent.ListenableFutureCallback; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.EmbeddedModule; +import com.oath.micro.server.testing.RestAgent; + +@Ignore //embedded - micro-monolith style doesn't work with Tomcat due to MBean naming collisions +public class EmbeddedAppTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer(){ + server = new MicroserverApp(EmbeddedAppLocalMain.class, + EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), + EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")); + server.start(); + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); + + + assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), + hasItem("hello")); + + } + + + @Test + public void nonBlockingRestClientTest(){ + assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"),is("-*test!-*test!")); + } + + CompletableFuture toCompletableFuture( + final ListenableFuture listenableFuture + ) { + //create an instance of CompletableFuture + CompletableFuture completable = new CompletableFuture() { + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + // propagate cancel to the listenable future + boolean result = listenableFuture.cancel(mayInterruptIfRunning); + super.cancel(mayInterruptIfRunning); + return result; + } + }; + + // add callback + listenableFuture.addCallback(new ListenableFutureCallback() { + @Override + public void onSuccess(T result) { + completable.complete(result); + } + + @Override + public void onFailure(Throwable t) { + completable.completeExceptionally(t); + } + }); + return completable; + } + + @Test(expected=NotFoundException.class) + public void confirmAltAppCantUseTestAppResources(){ + + assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); + + } + @Test(expected=NotFoundException.class) + public void confirmTestAppCantUseAltAppResources(){ + + assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), + hasItem("hello")); + + } +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java new file mode 100644 index 000000000..337b63b89 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java @@ -0,0 +1,29 @@ +package app.embedded.com.oath.micro.server; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "immutable") +@Getter +@AllArgsConstructor +@Builder +public class ImmutableEntity { + + private final String value; + private final List list; + + public ImmutableEntity() { + this(null,null); + } + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java new file mode 100644 index 000000000..55df29df5 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java @@ -0,0 +1,48 @@ +package app.embedded.com.oath.micro.server; + +import java.util.Arrays; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import cyclops.futurestream.SimpleReact; +import cyclops.futurestream.FutureStream; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.testing.RestAgent; +@Component +@Path("/test-status") +public class TestAppResource implements TestAppRestResource { + + private final SimpleReact simpleReact = new SimpleReact(); + private final RestAgent template = new RestAgent(); + private final List urls = Arrays.asList("http://localhost:8081/alternative-app/alt-status/ping", + "http://localhost:8080/test-app/test-status/ping", + "http://localhost:8082/simple-app/status/ping", + "http://localhost:8080/test-app/test-status/ping"); + + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "test!"; + } + + @GET + @Produces("text/plain") + @Path("/rest-calls") + public String restCallResult(){ + + return FutureStream.builder().fromIterable(urls) + .map(it ->template.get(it)) + .then(it -> "*"+it) + .peek(loadedAndModified -> System.out.println(loadedAndModified)) + .block().stream().reduce("", (acc,next) -> acc+"-"+next); + + } + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java new file mode 100644 index 000000000..7d4df5753 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java @@ -0,0 +1,7 @@ +package app.embedded.com.oath.micro.server; + +import com.oath.micro.server.auto.discovery.RestResource; + +public interface TestAppRestResource extends RestResource { + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/AutodiscoveredFilter.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/AutodiscoveredFilter.java deleted file mode 100644 index 0ea5b4990..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/AutodiscoveredFilter.java +++ /dev/null @@ -1,68 +0,0 @@ -package app.filter.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import lombok.Getter; -import lombok.Setter; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.FilterConfiguration; - -@Component -public class AutodiscoveredFilter implements Filter, FilterConfiguration { - - @Autowired - Bean bean; - @Getter - @Setter - private static volatile int called= 0; - - @Getter - private static boolean beanSet = false; - - @Override - public String[] getMapping() { - return new String[] { "/*" }; - } - public Class getFilter(){ - - return org.springframework.web.filter.DelegatingFilterProxy.class; - - } - public String getName(){ - return "autodiscoveredFilter"; - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - - called++; - if(bean!=null) - beanSet =true; - chain.doFilter(request, response); - } - - @Override - public void destroy() { - - - } - - - -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/Bean.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/Bean.java deleted file mode 100644 index f95b44b05..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/Bean.java +++ /dev/null @@ -1,8 +0,0 @@ -package app.filter.com.aol.micro.server; - -import org.springframework.stereotype.Component; - -@Component -public class Bean { - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/ConfiguredFilter.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/ConfiguredFilter.java deleted file mode 100644 index e00bc941b..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/ConfiguredFilter.java +++ /dev/null @@ -1,38 +0,0 @@ -package app.filter.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import lombok.Getter; - -public class ConfiguredFilter implements Filter { - - @Getter - private static volatile int called= 0; - @Override - public void init(FilterConfig filterConfig) throws ServletException { - // TODO Auto-generated method stub - - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - called++; - chain.doFilter(request, response); - - } - - @Override - public void destroy() { - // TODO Auto-generated method stub - - } - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterAppLocalMain.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterAppLocalMain.java deleted file mode 100644 index 25dc01cc3..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterAppLocalMain.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.filter.com.aol.micro.server; - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import app.servlet.com.aol.micro.server.AppRunnerLocalMain; - -import com.aol.micro.server.MicroserverApp; -@Configuration -@ComponentScan(basePackages = { "app.filter.com.aol.micro.server" }) -public class FilterAppLocalMain { - - - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( FilterAppLocalMain.class, () -> "filter-app") - .run(); - } - - } \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterRunnerTest.java deleted file mode 100644 index a2f2acec9..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterRunnerTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package app.filter.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.Map; -import java.util.concurrent.ExecutionException; - -import javax.servlet.Filter; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; -import com.aol.micro.server.utility.HashMapBuilder; - - - -public class FilterRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - Map filters = HashMapBuilder.map("/filter-app/status/ping2",new ConfiguredFilter()).build(); - server = new MicroserverApp(ConfigurableModule.builder() - .context("filter-app") - .filters(filters ) - .requestListeners(Arrays.asList(new org.springframework.web.context.request.RequestContextListener())).build()); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testAutoDiscoveredFilter() throws InterruptedException, ExecutionException{ - AutodiscoveredFilter.setCalled(0); - - assertThat(rest.get("http://localhost:8080/filter-app/status/ping"),is("ok")); - assertThat(AutodiscoveredFilter.getCalled(),is(1)); - assertThat(AutodiscoveredFilter.isBeanSet(),is(true)); - } - @Test - public void testConfiguredFilter() throws InterruptedException, ExecutionException{ - - assertThat(ConfiguredFilter.getCalled(),is(0)); - assertThat(rest.get("http://localhost:8080/filter-app/status/ping2"),is("ok")); - assertThat(ConfiguredFilter.getCalled(),is(1)); - } - - - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterStatusResource.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterStatusResource.java deleted file mode 100644 index 2d046711b..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/FilterStatusResource.java +++ /dev/null @@ -1,37 +0,0 @@ -package app.filter.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; -import org.springframework.web.context.WebApplicationContext; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) -@Path("/status") -public class FilterStatusResource implements RestResource { - - @Autowired - private RequestScopeUserInfo info; - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - info.print(); - return "ok"; - } - @GET - @Produces("text/plain") - @Path("/ping2") - public String ping2() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/RequestScopeUserInfo.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/RequestScopeUserInfo.java deleted file mode 100644 index c41605c39..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/filter/com/aol/micro/server/RequestScopeUserInfo.java +++ /dev/null @@ -1,20 +0,0 @@ -package app.filter.com.aol.micro.server; - -import javax.servlet.http.HttpServletRequest; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.context.annotation.ScopedProxyMode; -import org.springframework.stereotype.Component; -import org.springframework.web.context.WebApplicationContext; - -@Component -@Scope(value=WebApplicationContext.SCOPE_REQUEST,proxyMode=ScopedProxyMode.TARGET_CLASS) -public class RequestScopeUserInfo { - @Autowired - private HttpServletRequest request; - - public void print(){ - System.out.println(request.getAttribute("oc.info")); - } -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/AutodiscoveredFilter.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/AutodiscoveredFilter.java new file mode 100644 index 000000000..1f6dfc284 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/AutodiscoveredFilter.java @@ -0,0 +1,70 @@ +package app.filter.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import cyclops.control.Either; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.auto.discovery.AutoFilterConfiguration; + +import lombok.Getter; +import lombok.Setter; + +@Component +public class AutodiscoveredFilter implements AutoFilterConfiguration { + + @Autowired + Bean bean; + @Getter + @Setter + private static volatile int called= 0; + + @Getter + private static boolean beanSet = false; + + @Override + public String[] getMapping() { + return new String[] { "/*" }; + } + public Either,Filter> getFilter(){ + + return Either.left(org.springframework.web.filter.DelegatingFilterProxy.class); + + } + public String getName(){ + return "autodiscoveredFilter"; + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + + called++; + if(bean!=null) + beanSet =true; + chain.doFilter(request, response); + } + + @Override + public void destroy() { + + + } + + + +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/Bean.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/Bean.java new file mode 100644 index 000000000..e036a796f --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/Bean.java @@ -0,0 +1,8 @@ +package app.filter.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +@Component +public class Bean { + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/ConfiguredFilter.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/ConfiguredFilter.java new file mode 100644 index 000000000..aca52ad38 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/ConfiguredFilter.java @@ -0,0 +1,38 @@ +package app.filter.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import lombok.Getter; + +public class ConfiguredFilter implements Filter { + + @Getter + private static volatile int called= 0; + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // TODO Auto-generated method stub + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + called++; + chain.doFilter(request, response); + + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterAppLocalMain.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterAppLocalMain.java new file mode 100644 index 000000000..b650780a2 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterAppLocalMain.java @@ -0,0 +1,20 @@ +package app.filter.com.oath.micro.server; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.MicroserverApp; +@Configuration +@ComponentScan(basePackages = { "app.filter.com.aol.micro.server" }) +public class FilterAppLocalMain { + + + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( FilterAppLocalMain.class, () -> "filter-app") + .run(); + } + + } \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterRunnerTest.java new file mode 100644 index 000000000..efe90791e --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterRunnerTest.java @@ -0,0 +1,62 @@ +package app.filter.com.oath.micro.server; + + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; +import com.oath.micro.server.utility.HashMapBuilder; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +import javax.servlet.Filter; +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + + +public class FilterRunnerTest { + + RestAgent rest = new RestAgent(); + + static MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + Thread.sleep(500); + Map filters = HashMapBuilder.map("/filter-app/status/ping2",new ConfiguredFilter()).build(); + server = new MicroserverApp(ConfigurableModule.builder() + .context("filter-app") + .filters(filters ) + .requestListeners(Arrays.asList(new org.springframework.web.context.request.RequestContextListener())).build()); + server.start(); + + } + + @AfterClass + public static void stopServer(){ + server.stop(); + } + + @Test + public void testAutoDiscoveredFilter() throws InterruptedException, ExecutionException{ + AutodiscoveredFilter.setCalled(0); + + assertThat(rest.get("http://localhost:8080/filter-app/status/ping"),is("ok")); + assertThat(AutodiscoveredFilter.getCalled(),is(1)); + assertThat(AutodiscoveredFilter.isBeanSet(),is(true)); + } + @Test + public void testConfiguredFilter() throws InterruptedException, ExecutionException{ + + assertThat(ConfiguredFilter.getCalled(),is(0)); + assertThat(rest.get("http://localhost:8080/filter-app/status/ping2"),is("ok")); + assertThat(ConfiguredFilter.getCalled(),is(1)); + } + + + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterStatusResource.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterStatusResource.java new file mode 100644 index 000000000..c7166c216 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/FilterStatusResource.java @@ -0,0 +1,36 @@ +package app.filter.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) +@Path("/status") +public class FilterStatusResource implements RestResource { + + @Autowired + private RequestScopeUserInfo info; + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + info.print(); + return "ok"; + } + @GET + @Produces("text/plain") + @Path("/ping2") + public String ping2() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/RequestScopeUserInfo.java b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/RequestScopeUserInfo.java new file mode 100644 index 000000000..84c19c3f4 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/filter/com/oath/micro/server/RequestScopeUserInfo.java @@ -0,0 +1,20 @@ +package app.filter.com.oath.micro.server; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.stereotype.Component; +import org.springframework.web.context.WebApplicationContext; + +@Component +@Scope(value=WebApplicationContext.SCOPE_REQUEST,proxyMode=ScopedProxyMode.TARGET_CLASS) +public class RequestScopeUserInfo { + @Autowired + private HttpServletRequest request; + + public void print(){ + System.out.println(request.getAttribute("oc.info")); + } +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java b/micro-tomcat-with-jersey/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java deleted file mode 100644 index bff7cbdc8..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java +++ /dev/null @@ -1,35 +0,0 @@ -package app.listeners.com.aol.micro.server; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import lombok.Getter; - -import org.springframework.stereotype.Component; - -@Component -public class AutodiscoveredListener implements ServletContextListener { - - @Getter - private static volatile int called= 0; - - @Override - public void contextInitialized(ServletContextEvent sce) { - called ++; - - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - - - } - - - - - - - - -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/listeners/com/aol/micro/server/ConfiguredListener.java b/micro-tomcat-with-jersey/src/test/java/app/listeners/com/aol/micro/server/ConfiguredListener.java deleted file mode 100644 index d15dcb76e..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/listeners/com/aol/micro/server/ConfiguredListener.java +++ /dev/null @@ -1,25 +0,0 @@ -package app.listeners.com.aol.micro.server; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import lombok.Getter; - -public class ConfiguredListener implements ServletContextListener { - - @Getter - private static volatile int called= 0; - - @Override - public void contextInitialized(ServletContextEvent sce) { - called ++; - - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - - - } - -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java deleted file mode 100644 index 4f8d7ab69..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.listeners.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.ExecutionException; - -import javax.servlet.ServletContextListener; - - - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - - -@Microserver -public class ListenerRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - List listeners = Arrays.asList(new ConfiguredListener()); - server = new MicroserverApp( ListenerRunnerTest.class, ConfigurableModule.builder().context("listener-app").listeners(listeners ).build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testListeners() throws InterruptedException, ExecutionException{ - - assertThat(AutodiscoveredListener.getCalled(),is(1)); - assertThat(ConfiguredListener.getCalled(),is(1)); - } - - - - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/listeners/com/oath/micro/server/AutodiscoveredListener.java b/micro-tomcat-with-jersey/src/test/java/app/listeners/com/oath/micro/server/AutodiscoveredListener.java new file mode 100644 index 000000000..a3dfdff21 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/listeners/com/oath/micro/server/AutodiscoveredListener.java @@ -0,0 +1,35 @@ +package app.listeners.com.oath.micro.server; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import lombok.Getter; + +import org.springframework.stereotype.Component; + +@Component +public class AutodiscoveredListener implements ServletContextListener { + + @Getter + private static volatile int called= 0; + + @Override + public void contextInitialized(ServletContextEvent sce) { + called ++; + + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + + + } + + + + + + + + +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/listeners/com/oath/micro/server/ConfiguredListener.java b/micro-tomcat-with-jersey/src/test/java/app/listeners/com/oath/micro/server/ConfiguredListener.java new file mode 100644 index 000000000..86a7cd34b --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/listeners/com/oath/micro/server/ConfiguredListener.java @@ -0,0 +1,25 @@ +package app.listeners.com.oath.micro.server; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import lombok.Getter; + +public class ConfiguredListener implements ServletContextListener { + + @Getter + private static volatile int called= 0; + + @Override + public void contextInitialized(ServletContextEvent sce) { + called ++; + + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + + + } + +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/listeners/com/oath/micro/server/ListenerRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/listeners/com/oath/micro/server/ListenerRunnerTest.java new file mode 100644 index 000000000..fa0222a76 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/listeners/com/oath/micro/server/ListenerRunnerTest.java @@ -0,0 +1,55 @@ +package app.listeners.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import javax.servlet.ServletContextListener; + + + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + + +@Microserver +public class ListenerRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + List listeners = Arrays.asList(new ConfiguredListener()); + server = new MicroserverApp( ListenerRunnerTest.class, ConfigurableModule.builder().context("listener-app").listeners(listeners ).build()); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void testListeners() throws InterruptedException, ExecutionException{ + + assertThat(AutodiscoveredListener.getCalled(),is(1)); + assertThat(ConfiguredListener.getCalled(),is(1)); + } + + + + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java b/micro-tomcat-with-jersey/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java deleted file mode 100644 index 04367ecbd..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package app.minimal.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.testing.RestAgent; - -@Rest -@Path("/single") -public class MinimalClassTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "minimal-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java b/micro-tomcat-with-jersey/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java new file mode 100644 index 000000000..9d17b99b6 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java @@ -0,0 +1,57 @@ +package app.minimal.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.testing.RestAgent; + +@Rest +@Path("/single") +public class MinimalClassTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + + server = new MicroserverApp(()-> "minimal-app"); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + Thread.sleep(500); + + assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoRunnerTest.java deleted file mode 100644 index 92abed060..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoRunnerTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package app.noanno.com.aol.micro.server.copy; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - - -public class NoAnnoRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - - server = new MicroserverApp(()-> "simple-app"); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); - - - } - - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoStatusResource.java b/micro-tomcat-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoStatusResource.java deleted file mode 100644 index 8a3f5efaa..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoStatusResource.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.noanno.com.aol.micro.server.copy; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class NoAnnoStatusResource { - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/SimpleApp.java b/micro-tomcat-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/SimpleApp.java deleted file mode 100644 index 5fb7e2ca3..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/noanno/com/aol/micro/server/copy/SimpleApp.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.noanno.com.aol.micro.server.copy; - -import com.aol.micro.server.MicroserverApp; - -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()-> "simple-app").run(); - } - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoRunnerTest.java new file mode 100644 index 000000000..b476e2791 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoRunnerTest.java @@ -0,0 +1,48 @@ +package app.noanno.com.oath.micro.server.copy; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; + + +public class NoAnnoRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + + server = new MicroserverApp(()-> "simple-app"); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); + + + } + + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoStatusResource.java b/micro-tomcat-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoStatusResource.java new file mode 100644 index 000000000..11a42968e --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoStatusResource.java @@ -0,0 +1,24 @@ +package app.noanno.com.oath.micro.server.copy; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class NoAnnoStatusResource { + + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/SimpleApp.java b/micro-tomcat-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/SimpleApp.java new file mode 100644 index 000000000..646004a31 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/noanno/com/oath/micro/server/copy/SimpleApp.java @@ -0,0 +1,12 @@ +package app.noanno.com.oath.micro.server.copy; + +import com.oath.micro.server.MicroserverApp; + +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()-> "simple-app").run(); + } + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/properties/instance/com/aol/micro/server/ServicePropertiesTest.java b/micro-tomcat-with-jersey/src/test/java/app/properties/instance/com/aol/micro/server/ServicePropertiesTest.java deleted file mode 100644 index 66ae36c54..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/properties/instance/com/aol/micro/server/ServicePropertiesTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package app.properties.instance.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Value; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Rest -@Path("/single") -@Microserver(instancePropertiesName="myinstance.properties") -public class ServicePropertiesTest { - - RestAgent rest = new RestAgent(); - - @Value("${type.property}") - private String type; - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - - server = new MicroserverApp(()-> "minimal-app"); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); - - - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - assertThat(type,equalTo("instance")); - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/properties/instance/com/oath/micro/server/ServicePropertiesTest.java b/micro-tomcat-with-jersey/src/test/java/app/properties/instance/com/oath/micro/server/ServicePropertiesTest.java new file mode 100644 index 000000000..0b84e4db2 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/properties/instance/com/oath/micro/server/ServicePropertiesTest.java @@ -0,0 +1,66 @@ +package app.properties.instance.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Value; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Rest +@Path("/single") +@Microserver(instancePropertiesName="myinstance.properties") +public class ServicePropertiesTest { + + RestAgent rest = new RestAgent(); + + @Value("${type.property}") + private String type; + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + + server = new MicroserverApp(()-> "minimal-app"); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); + + + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + assertThat(type,equalTo("instance")); + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/properties/service/com/aol/micro/server/ServicePropertiesTest.java b/micro-tomcat-with-jersey/src/test/java/app/properties/service/com/aol/micro/server/ServicePropertiesTest.java deleted file mode 100644 index de9241729..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/properties/service/com/aol/micro/server/ServicePropertiesTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package app.properties.service.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Value; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Rest -@Path("/single") -@Microserver(serviceTypePropertiesName="myservice.properties") -public class ServicePropertiesTest { - - RestAgent rest = new RestAgent(); - - @Value("${type.property}") - private String type; - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - - server = new MicroserverApp(()-> "minimal-app"); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); - - - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - assertThat(type,equalTo("set")); - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/properties/service/com/oath/micro/server/ServicePropertiesTest.java b/micro-tomcat-with-jersey/src/test/java/app/properties/service/com/oath/micro/server/ServicePropertiesTest.java new file mode 100644 index 000000000..876326418 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/properties/service/com/oath/micro/server/ServicePropertiesTest.java @@ -0,0 +1,66 @@ +package app.properties.service.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Value; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Rest +@Path("/single") +@Microserver(serviceTypePropertiesName="myservice.properties") +public class ServicePropertiesTest { + + RestAgent rest = new RestAgent(); + + @Value("${type.property}") + private String type; + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + + server = new MicroserverApp(()-> "minimal-app"); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); + + + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + assertThat(type,equalTo("set")); + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java deleted file mode 100644 index b447491a1..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java +++ /dev/null @@ -1,20 +0,0 @@ -package app.servlet.com.aol.micro.server; - - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import com.aol.micro.server.MicroserverApp; - -@Configuration -@ComponentScan(basePackages = { "app.servlet.com.aol.micro.server" }) -public class AppRunnerLocalMain { - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( AppRunnerLocalMain.class, () -> "test-app") - .run(); - } - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java deleted file mode 100644 index d0123c905..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java +++ /dev/null @@ -1,30 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.ServletConfiguration; - -@Component -public class AutodiscoveredServlet extends HttpServlet implements ServletConfiguration { - - @Override - public String[] getMapping() { - return new String[] { "/servlet" }; - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - resp.setContentType("text/html"); - resp.getWriter().write("hello world"); - } - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java deleted file mode 100644 index 92577a92e..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class ConfiguredServlet extends HttpServlet { - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - resp.setContentType("text/html"); - resp.getWriter().write("configured servlet"); - } - - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java deleted file mode 100644 index e821da8b6..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package app.servlet.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ExecutionException; - -import javax.servlet.Servlet; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -public class ServletRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - Map servlets = new HashMap<>(); - servlets.put("/configured", new ConfiguredServlet()); - server = new MicroserverApp( AppRunnerLocalMain.class, ConfigurableModule.builder().context("test-app").servlets(servlets ).build()); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/test-app/servlet/ping"),is("ok")); - - } - - @Test - public void autoDiscoveredServletTest() throws InterruptedException, ExecutionException{ - - - assertThat(rest.get("http://localhost:8080/servlet"),is("hello world")); - - } - - @Test - public void configuredServletTest() throws InterruptedException, ExecutionException{ - - - assertThat(rest.get("http://localhost:8080/configured"),is("configured servlet")); - - } - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java deleted file mode 100644 index 890a64679..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/servlet") -public class ServletStatusResource implements RestResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/AppRunnerLocalMain.java b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/AppRunnerLocalMain.java new file mode 100644 index 000000000..217fc92d4 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/AppRunnerLocalMain.java @@ -0,0 +1,20 @@ +package app.servlet.com.oath.micro.server; + + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.MicroserverApp; + +@Configuration +@ComponentScan(basePackages = { "app.servlet.com.oath.micro.server" }) +public class AppRunnerLocalMain { + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( AppRunnerLocalMain.class, () -> "test-app") + .run(); + } + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/AutodiscoveredServlet.java b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/AutodiscoveredServlet.java new file mode 100644 index 000000000..66cbfd59c --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/AutodiscoveredServlet.java @@ -0,0 +1,30 @@ +package app.servlet.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.AutoServletConfiguration; + +@Component +public class AutodiscoveredServlet extends HttpServlet implements AutoServletConfiguration { + + @Override + public String[] getMapping() { + return new String[] { "/servlet" }; + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + resp.setContentType("text/html"); + resp.getWriter().write("hello world"); + } + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ConfiguredServlet.java b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ConfiguredServlet.java new file mode 100644 index 000000000..65de82291 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ConfiguredServlet.java @@ -0,0 +1,21 @@ +package app.servlet.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class ConfiguredServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + resp.setContentType("text/html"); + resp.getWriter().write("configured servlet"); + } + + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ServletRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ServletRunnerTest.java new file mode 100644 index 000000000..1fd393deb --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ServletRunnerTest.java @@ -0,0 +1,66 @@ +package app.servlet.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import javax.servlet.Servlet; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +public class ServletRunnerTest { + + RestAgent rest = new RestAgent(); + + static MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + Map servlets = new HashMap<>(); + servlets.put("/configured", new ConfiguredServlet()); + server = new MicroserverApp( AppRunnerLocalMain.class, ConfigurableModule.builder().context("test-app").servlets(servlets ).build()); + Thread.sleep(1000); + server.start(); + + } + + @AfterClass + public static void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/test-app/servlet/ping"),is("ok")); + + } + + @Test + public void autoDiscoveredServletTest() throws InterruptedException, ExecutionException{ + + + assertThat(rest.get("http://localhost:8080/servlet"),is("hello world")); + + } + + @Test + public void configuredServletTest() throws InterruptedException, ExecutionException{ + + + assertThat(rest.get("http://localhost:8080/configured"),is("configured servlet")); + + } + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ServletStatusResource.java b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ServletStatusResource.java new file mode 100644 index 000000000..6d86eeb84 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/servlet/com/oath/micro/server/ServletStatusResource.java @@ -0,0 +1,22 @@ +package app.servlet.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/servlet") +public class ServletStatusResource implements RestResource { + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java b/micro-tomcat-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java deleted file mode 100644 index 700a2c778..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java +++ /dev/null @@ -1,18 +0,0 @@ -package app.simple.com.aol.micro.server; - -import java.util.Arrays; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; - -public class SimpleApp { - - public static void main(String[] args){ - - new MicroserverApp(()-> "simple-app").run(); - } - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java deleted file mode 100644 index 57bc0e1ef..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.simple.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class SimpleRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); - - - } - - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java b/micro-tomcat-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java deleted file mode 100644 index 17e6c3e45..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java +++ /dev/null @@ -1,39 +0,0 @@ -package app.simple.com.aol.micro.server; - -import java.io.InputStream; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; -import org.glassfish.jersey.media.multipart.FormDataParam; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class SimpleStatusResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return "ok"; - } - - @POST - @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces(MediaType.TEXT_PLAIN) - @Path("/file") - public String create( - @FormDataParam("file") InputStream fileInputStream, - @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { - - return "done"; - } -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java b/micro-tomcat-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java new file mode 100644 index 000000000..e82a92291 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java @@ -0,0 +1,13 @@ +package app.simple.com.oath.micro.server; + +import com.oath.micro.server.MicroserverApp; + +public class SimpleApp { + + public static void main(String[] args){ + + new MicroserverApp(()-> "simple-app").run(); + } + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java new file mode 100644 index 000000000..504b5199e --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java @@ -0,0 +1,55 @@ +package app.simple.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class SimpleRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); + + + } + + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java b/micro-tomcat-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java new file mode 100644 index 000000000..2a894a8fc --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java @@ -0,0 +1,39 @@ +package app.simple.com.oath.micro.server; + +import java.io.InputStream; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class SimpleStatusResource { + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + return "ok"; + } + + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.TEXT_PLAIN) + @Path("/file") + public String create( + @FormDataParam("file") InputStream fileInputStream, + @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { + + return "done"; + } +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java b/micro-tomcat-with-jersey/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java deleted file mode 100644 index 4839e9fff..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package app.single.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -@Path("/single") -public class SingleClassTest implements RestResource{ - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - - server = new MicroserverApp( SingleClassTest.class, ()-> "simple-app"); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/single/ping"),is("ok")); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java b/micro-tomcat-with-jersey/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java new file mode 100644 index 000000000..324cf4dce --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java @@ -0,0 +1,59 @@ +package app.single.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +@Path("/single") +public class SingleClassTest implements RestResource{ + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + + server = new MicroserverApp( SingleClassTest.class, ()-> "simple-app"); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/single/ping"),is("ok")); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java b/micro-tomcat-with-jersey/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java deleted file mode 100644 index aef7a170c..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.single.main.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class SingleClassApp { - - public static void main(String[] args){ - new MicroserverApp(()-> "simple-app").run(); - } - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/single/main/com/oath/micro/server/SingleClassApp.java b/micro-tomcat-with-jersey/src/test/java/app/single/main/com/oath/micro/server/SingleClassApp.java new file mode 100644 index 000000000..2d7a71917 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/single/main/com/oath/micro/server/SingleClassApp.java @@ -0,0 +1,24 @@ +package app.single.main.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class SingleClassApp { + + public static void main(String[] args){ + new MicroserverApp(()-> "simple-app").run(); + } + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/single/serverconfig/com/aol/micro/server/SingleClassTest.java b/micro-tomcat-with-jersey/src/test/java/app/single/serverconfig/com/aol/micro/server/SingleClassTest.java deleted file mode 100644 index 5c0cb67b8..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/single/serverconfig/com/aol/micro/server/SingleClassTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package app.single.serverconfig.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - - -@Path("/single") -public class SingleClassTest implements RestResource{ - - RestAgent rest = new RestAgent(); - - boolean called; - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - called = false; - server = new MicroserverApp( ConfigurableModule.builder() - .context("hello") - .serverConfigManager(server->called=true) - .build()); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/hello/single/ping"),is("ok")); - assertTrue(called); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/single/serverconfig/com/oath/micro/server/SingleClassTest.java b/micro-tomcat-with-jersey/src/test/java/app/single/serverconfig/com/oath/micro/server/SingleClassTest.java new file mode 100644 index 000000000..6d0bc5d09 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/single/serverconfig/com/oath/micro/server/SingleClassTest.java @@ -0,0 +1,64 @@ +package app.single.serverconfig.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + + +@Path("/single") +public class SingleClassTest implements RestResource{ + + RestAgent rest = new RestAgent(); + + boolean called; + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + called = false; + server = new MicroserverApp( ConfigurableModule.builder() + .context("hello") + .serverConfigManager(server->called=true) + .build()); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/hello/single/ping"),is("ok")); + assertTrue(called); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/spring/com/aol/micro/server/MyBean.java b/micro-tomcat-with-jersey/src/test/java/app/spring/com/aol/micro/server/MyBean.java deleted file mode 100644 index 1f7a589ff..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/spring/com/aol/micro/server/MyBean.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.spring.com.aol.micro.server; - -import javax.inject.Inject; - -import lombok.Getter; - -@Getter -public class MyBean { - - @Inject - private MyDependency injected; -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/spring/com/aol/micro/server/MyDependency.java b/micro-tomcat-with-jersey/src/test/java/app/spring/com/aol/micro/server/MyDependency.java deleted file mode 100644 index 48d89e6c5..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/spring/com/aol/micro/server/MyDependency.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.spring.com.aol.micro.server; - -import lombok.Getter; - -import org.springframework.stereotype.Component; - -@Component -@Getter -public class MyDependency { - - private String data = "hello world"; -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java deleted file mode 100644 index 6f777ba02..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.spring.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.context.annotation.Bean; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; -/**@Configuration -@ComponentScan(basePackages = { "app.spring.com.aol.micro.server" })**/ -@Microserver -public class SpringRunnerTest { - - RestAgent rest = new RestAgent(); - - @Bean - public MyBean mybean(){ - return new MyBean(); - } - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - - server = new MicroserverApp( SpringRunnerTest.class, ()-> "spring-app"); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testAutoWiring() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/spring-app/spring/ping"),is("hello world")); - - } - - - - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java b/micro-tomcat-with-jersey/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java deleted file mode 100644 index 331ac997e..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java +++ /dev/null @@ -1,32 +0,0 @@ -package app.spring.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/spring") -public class SpringStatusResource implements RestResource { - - @Autowired - private MyBean mybean; - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return mybean.getInjected().getData(); - } - @GET - @Produces("text/plain") - @Path("/ping2") - public String ping2() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/spring/com/oath/micro/server/MyBean.java b/micro-tomcat-with-jersey/src/test/java/app/spring/com/oath/micro/server/MyBean.java new file mode 100644 index 000000000..328b7d185 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/spring/com/oath/micro/server/MyBean.java @@ -0,0 +1,12 @@ +package app.spring.com.oath.micro.server; + +import javax.inject.Inject; + +import lombok.Getter; + +@Getter +public class MyBean { + + @Inject + private MyDependency injected; +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/spring/com/oath/micro/server/MyDependency.java b/micro-tomcat-with-jersey/src/test/java/app/spring/com/oath/micro/server/MyDependency.java new file mode 100644 index 000000000..1ca23b15b --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/spring/com/oath/micro/server/MyDependency.java @@ -0,0 +1,12 @@ +package app.spring.com.oath.micro.server; + +import lombok.Getter; + +import org.springframework.stereotype.Component; + +@Component +@Getter +public class MyDependency { + + private String data = "hello world"; +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java b/micro-tomcat-with-jersey/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java new file mode 100644 index 000000000..8fb684d67 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java @@ -0,0 +1,55 @@ +package app.spring.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.annotation.Bean; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; +/**@Configuration +@ComponentScan(basePackages = { "app.spring.com.oath.micro.server" })**/ +@Microserver +public class SpringRunnerTest { + + RestAgent rest = new RestAgent(); + + @Bean + public MyBean mybean(){ + return new MyBean(); + } + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + + server = new MicroserverApp( SpringRunnerTest.class, ()-> "spring-app"); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void testAutoWiring() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/spring-app/spring/ping"),is("hello world")); + + } + + + + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java b/micro-tomcat-with-jersey/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java new file mode 100644 index 000000000..ae0c817de --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java @@ -0,0 +1,32 @@ +package app.spring.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/spring") +public class SpringStatusResource implements RestResource { + + @Autowired + private MyBean mybean; + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return mybean.getInjected().getData(); + } + @GET + @Produces("text/plain") + @Path("/ping2") + public String ping2() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-tomcat-with-jersey/src/test/java/app/validation/com/aol/micro/server/ImmutableEntity.java b/micro-tomcat-with-jersey/src/test/java/app/validation/com/aol/micro/server/ImmutableEntity.java deleted file mode 100644 index 5af51d60c..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/validation/com/aol/micro/server/ImmutableEntity.java +++ /dev/null @@ -1,28 +0,0 @@ -package app.validation.com.aol.micro.server; - - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableEntity { - - private final String value; - - - public ImmutableEntity() { - this(null); - } - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java b/micro-tomcat-with-jersey/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java deleted file mode 100644 index 880c619e8..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java +++ /dev/null @@ -1,23 +0,0 @@ -package app.validation.com.aol.micro.server; - -import javax.validation.constraints.NotNull; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -@Component -@Path("/status") -public class ValidationAppResource implements RestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public ImmutableEntity ping( @NotNull ImmutableEntity entity) { - return entity; - } - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java b/micro-tomcat-with-jersey/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java deleted file mode 100644 index 2ddec8a47..000000000 --- a/micro-tomcat-with-jersey/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package app.validation.com.aol.micro.server; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.BadRequestException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.SimpleReactStream; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.testing.RestAgent; - -//@Microserver(basePackages = { "app.guava.com.aol.micro.server" }) -public class ValidationAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - ImmutableEntity entity; - - - SimpleReact simpleReact = new SimpleReact(); - SimpleReactStream stream; - - @Before - public void startServer() throws InterruptedException { - server = new MicroserverApp(() -> "guava-app"); - Thread.sleep(1000); - server.start(); - - - entity = ImmutableEntity.builder().value("value").build(); - - - } - - @After - public void stopServer() { - server.stop(); - } - - - @Test(expected=BadRequestException.class) - public void confirmError() throws InterruptedException, - ExecutionException { - - - //stream.block(); - - rest.post( - "http://localhost:8080/guava-app/status/ping", null, - ImmutableEntity.class); - - - } - @Test - public void confirmNoError() throws InterruptedException, - ExecutionException { - - //stream.block(); - rest.post( - "http://localhost:8080/guava-app/status/ping", entity, - ImmutableEntity.class); - - - } - - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/app/validation/com/oath/micro/server/ImmutableEntity.java b/micro-tomcat-with-jersey/src/test/java/app/validation/com/oath/micro/server/ImmutableEntity.java new file mode 100644 index 000000000..19e8f5b26 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/validation/com/oath/micro/server/ImmutableEntity.java @@ -0,0 +1,28 @@ +package app.validation.com.oath.micro.server; + + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "immutable") +@Getter +@AllArgsConstructor +@Builder +public class ImmutableEntity { + + private final String value; + + + public ImmutableEntity() { + this(null); + } + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppErrorTest.java b/micro-tomcat-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppErrorTest.java new file mode 100644 index 000000000..3d29ece0f --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppErrorTest.java @@ -0,0 +1,60 @@ +package app.validation.com.oath.micro.server; + +import com.oath.cyclops.types.futurestream.SimpleReactStream; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; +import cyclops.futurestream.SimpleReact; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.ws.rs.BadRequestException; +import java.util.concurrent.ExecutionException; + +//@Microserver(basePackages = { "app.guava.com.aol.micro.server" }) +public class ValidationAppErrorTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + ImmutableEntity entity; + + + SimpleReact simpleReact = new SimpleReact(); + SimpleReactStream stream; + + @Before + public void startServer() throws InterruptedException { + server = new MicroserverApp(() -> "guava-app"); + Thread.sleep(1000); + server.start(); + + + entity = ImmutableEntity.builder().value("value").build(); + + + } + + @After + public void stopServer() { + server.stop(); + } + + + @Test(expected=BadRequestException.class) + public void confirmError() throws InterruptedException, + ExecutionException { + + + //stream.block(); + + rest.post( + "http://localhost:8080/guava-app/status/ping", null, + ImmutableEntity.class); + + + } + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java b/micro-tomcat-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java new file mode 100644 index 000000000..7a8d0c325 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java @@ -0,0 +1,23 @@ +package app.validation.com.oath.micro.server; + +import javax.validation.constraints.NotNull; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +@Component +@Path("/status") +public class ValidationAppResource implements RestResource { + + @POST + @Produces("application/json") + @Path("/ping") + public ImmutableEntity ping( @NotNull ImmutableEntity entity) { + return entity; + } + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java b/micro-tomcat-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java new file mode 100644 index 000000000..f571dd132 --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java @@ -0,0 +1,59 @@ +package app.validation.com.oath.micro.server; + +import com.oath.cyclops.types.futurestream.SimpleReactStream; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; +import cyclops.futurestream.SimpleReact; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +//@Microserver(basePackages = { "app.guava.com.aol.micro.server" }) +public class ValidationAppTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + ImmutableEntity entity; + + + SimpleReact simpleReact = new SimpleReact(); + SimpleReactStream stream; + + @Before + public void startServer() throws InterruptedException { + server = new MicroserverApp(() -> "guava-app"); + Thread.sleep(1000); + server.start(); + + + entity = ImmutableEntity.builder().value("value").build(); + + + } + + @After + public void stopServer() { + server.stop(); + } + + + + @Test + public void confirmNoError() throws InterruptedException, + ExecutionException { + + //stream.block(); + rest.post( + "http://localhost:8080/guava-app/status/ping", entity, + ImmutableEntity.class); + + + } + + + +} diff --git a/micro-tomcat-with-jersey/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-tomcat-with-jersey/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-tomcat-with-jersey/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-tomcat-with-jersey/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-tomcat-with-jersey/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-tomcat-with-jersey/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-tomcat/README.md b/micro-tomcat/README.md new file mode 100644 index 000000000..97263b311 --- /dev/null +++ b/micro-tomcat/README.md @@ -0,0 +1,29 @@ +# Tomcat web server Plugin + +[Example Tomcat apps](https://github.com/aol/micro-server/tree/master/micro-tomcat/src/test/java/app) + +Plugin that allows the Tomcat Web server to be used with Microserver. (Since v0.79 of Microserver) + +## Note + +Tomcat does not currently support the Microserver micro-monolith style of development where by multiple Microservers can be rolled up into a single 'monolithic' style services at runtime. If you require that type of functionality take a look at micro-grizzly instead. + + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-grizzly/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-tomcat) + +Simply add to the classpath + +Maven +```xml + + com.oath.microservices + micro-tomcat + x.yz + + ``` +Gradle +```groovy + compile 'com.oath.microservices:micro-tomcaty:x.yz' +``` diff --git a/micro-tomcat/build.gradle b/micro-tomcat/build.gradle index b0bbebb51..6f7b363b5 100644 --- a/micro-tomcat/build.gradle +++ b/micro-tomcat/build.gradle @@ -1,64 +1,61 @@ description = 'micro-tomcat' -dependencies { - compile 'org.apache.tomcat.embed:tomcat-embed-core:'+tomcatVersion - compile 'org.apache.tomcat.embed:tomcat-embed-logging-juli:'+tomcatVersion - - - compile project(':micro-core') - testCompile project(':micro-jersey') - testCompile project(':micro-jackson-configuration') - - - +dependencies { + compile project(':micro-core') + compile 'org.apache.tomcat.embed:tomcat-embed-core:' + tomcatVersion + testCompile project(':micro-jersey') + testCompile project(':micro-jackson-configuration') + testCompile "com.oath.cyclops:cyclops-futurestream:$cyclopsVersion" } modifyPom { - project { - name 'Microserver Tomcat' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' - - groupId 'com.aol.microservices' - artifactId 'micro-tomcat' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } - - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - } - - } + project { + name 'Microserver Tomcat' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-tomcat' + version "$version" + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + } + + } +} +test { + forkEvery = 1 } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-tomcat/readme.md b/micro-tomcat/readme.md deleted file mode 100644 index 0f8e68a72..000000000 --- a/micro-tomcat/readme.md +++ /dev/null @@ -1,29 +0,0 @@ -# Tomcat web server Plugin - -[Example Tomcat apps](https://github.com/aol/micro-server/tree/master/micro-tomcat/src/test/java/app) - -Plugin that allows the Tomcat Web server to be used with Microserver. (Since v0.79 of Microserver) - -## Note - -Tomcat does not currently support the Microserver micro-monolith style of development where by multiple Microservers can be rolled up into a single 'monolithic' style services at runtime. If you require that type of functionality take a look at micro-grizzly instead. - - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-grizzly/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-tomcat) - -Simply add to the classpath - -Maven -```xml - - com.aol.microservices - micro-tomcat - x.yz - - ``` -Gradle -```groovy - compile 'com.aol.microservices:micro-tomcaty:x.yz' -``` \ No newline at end of file diff --git a/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/SSLConfigurationBuilder.java b/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/SSLConfigurationBuilder.java deleted file mode 100644 index 4bf487469..000000000 --- a/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/SSLConfigurationBuilder.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.aol.micro.server.servers.tomcat; - - - -import org.apache.coyote.http11.AbstractHttp11JsseProtocol; - - -import com.aol.micro.server.config.SSLProperties; - -public class SSLConfigurationBuilder { - - - public void build(AbstractHttp11JsseProtocol protocol,SSLProperties sslProperties) { - protocol.setKeystoreFile(sslProperties.getKeyStoreFile()); // contains server keypair - protocol.setKeyPass(sslProperties.getKeyStorePass()); - sslProperties.getKeyStoreType().peek(type->protocol.setKeystoreType(type)); - sslProperties.getKeyStoreProvider().peek(provider->protocol.setKeystoreProvider(provider)); - - protocol.setTruststoreFile(sslProperties.getTrustStoreFile()); // contains client certificate - protocol.setTruststorePass(sslProperties.getTrustStorePass()); - sslProperties.getTrustStoreType().peek(type->protocol.setTruststoreType(type)); - sslProperties.getTrustStoreProvider().peek(provider->protocol.setTruststoreProvider(provider)); - sslProperties.getClientAuth().peek(auth->protocol.setClientAuth(auth)); - - protocol.setSSLEnabled(true); - sslProperties.getCiphers().peek(ciphers->protocol.setCiphers(ciphers)); - sslProperties.getProtocol().peek(pr->protocol.setSslProtocol(pr)); - - - } -} diff --git a/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/TomcatApplication.java b/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/TomcatApplication.java deleted file mode 100644 index 680c92bf0..000000000 --- a/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/TomcatApplication.java +++ /dev/null @@ -1,172 +0,0 @@ -package com.aol.micro.server.servers.tomcat; - -import java.io.File; -import java.util.HashSet; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import javax.servlet.ServletContextListener; -import javax.servlet.ServletRequestListener; - -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Wither; - -import org.apache.catalina.LifecycleException; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.core.StandardContext; -import org.apache.catalina.startup.Tomcat; -import org.apache.catalina.valves.AccessLogValve; -import org.apache.catalina.valves.Constants; -import org.apache.coyote.ProtocolHandler; -import org.apache.coyote.http11.AbstractHttp11JsseProtocol; -import org.pcollections.PStack; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.aol.cyclops.util.ExceptionSoftener; -import com.aol.micro.server.ErrorCode; -import com.aol.micro.server.config.SSLProperties; -import com.aol.micro.server.module.WebServerProvider; -import com.aol.micro.server.servers.AccessLogLocationBean; -import com.aol.micro.server.servers.JaxRsServletConfigurer; -import com.aol.micro.server.servers.ServerApplication; -import com.aol.micro.server.servers.model.AllData; -import com.aol.micro.server.servers.model.FilterData; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.servers.model.ServletData; - -@AllArgsConstructor(access = AccessLevel.PRIVATE) -public class TomcatApplication implements ServerApplication { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - @Getter - private final ServerData serverData; - - private final PStack filterData; - private final PStack servletData; - private final PStack servletContextListenerData; - private final PStack servletRequestListenerData; - @Wither - private final SSLProperties SSLProperties; - - public TomcatApplication(AllData serverData) { - this.serverData = serverData.getServerData(); - this.filterData = serverData.getFilterDataList(); - this.servletData = serverData.getServletDataList(); - this.servletContextListenerData = serverData.getServletContextListeners(); - this.servletRequestListenerData = serverData.getServletRequestListeners(); - this.SSLProperties = null; - } - - public void run(CompletableFuture start, JaxRsServletConfigurer jaxRsConfigurer, CompletableFuture end) { - Tomcat tomcat = new Tomcat(); - tomcat.setPort(serverData.getPort()); - tomcat.getHost().setAutoDeploy(false); - tomcat.getEngine().setBackgroundProcessorDelay(-1); - File docBase = new File("."); - StandardContext context =(StandardContext)tomcat.addContext("", docBase.getAbsolutePath()); - context.addServletContainerInitializer(new TomcatListener(jaxRsConfigurer, serverData, filterData, servletData, servletContextListenerData, servletRequestListenerData), - new HashSet<>()); - addAccessLog(tomcat,context); - - serverData.getModule().getServerConfigManager().accept(new WebServerProvider(tomcat)); - - if(SSLProperties!=null){ - addSSL(tomcat.getConnector(),SSLProperties); - } - - startServer( tomcat, start, end); - } - - private void addSSL(Connector connector,SSLProperties sslProperties) { - ProtocolHandler handler = connector.getProtocolHandler(); - if(handler instanceof AbstractHttp11JsseProtocol){ - new SSLConfigurationBuilder().build((AbstractHttp11JsseProtocol)handler,sslProperties); - connector.setScheme("https"); - connector.setSecure(true); - - } - - - } - - private void startServer( Tomcat httpServer, CompletableFuture start, CompletableFuture end) { - - try { - logger.info("Starting application {} on port {}", serverData.getModule().getContext(), serverData.getPort()); - logger.info("Browse to http://localhost:{}/{}/application.wadl", serverData.getPort(), serverData.getModule().getContext()); - logger.info("Configured resource classes :-"); - serverData.extractResources().forEach( - t -> logger.info(t.v1() + " : " + "http://localhost:" + serverData.getPort() + "/" + serverData.getModule().getContext() + t.v2())); - ; - - httpServer.start(); - - start.complete(true); - end.get(); - - }catch (LifecycleException e) { - throw ExceptionSoftener.throwSoftenedException(e); - } catch (ExecutionException e) { - throw ExceptionSoftener.throwSoftenedException(e); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw ExceptionSoftener.throwSoftenedException(e); - } finally { - try { - httpServer.stop(); - httpServer.getConnector().destroy(); - httpServer.getEngine().destroy(); - httpServer.destroy(); - - - - } catch (LifecycleException e) { - } - try{ - Thread.sleep(5_000); - } - catch (InterruptedException e) { - - } - - } - } - - private void addAccessLog(Tomcat httpServer, StandardContext context) { - try { - - String accessLogLocation = serverData.getRootContext().getBean(AccessLogLocationBean.class).getAccessLogLocation(); - - accessLogLocation = accessLogLocation + "/" + replaceSlash(serverData.getModule().getContext()) + "-access.log"; - - AccessLogValve accessLogValve = new AccessLogValve(); - accessLogValve.setDirectory(accessLogLocation); - accessLogValve.setPattern(Constants.AccessLog.COMMON_ALIAS); - accessLogValve.setSuffix(".log"); - accessLogValve.setRotatable(true); - context.getPipeline().addValve(accessLogValve); - - } catch (Exception e) { - - logger.error(ErrorCode.SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG.toString() + ": " + e.getMessage()); - if (e.getCause() != null) - logger.error("CAUSED BY: " + ErrorCode.SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG.toString() + ": " + e.getCause().getMessage()); - - } - - } - - - - private String replaceSlash(String context) { - if (context != null && context.contains("/")) { - return context.substring(0, context.indexOf("/")); - } - return context; - } - -} diff --git a/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/TomcatApplicationFactory.java b/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/TomcatApplicationFactory.java deleted file mode 100644 index d5c40751d..000000000 --- a/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/TomcatApplicationFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.aol.micro.server.servers.tomcat; - -import java.util.List; - -import lombok.AllArgsConstructor; - -import org.pcollections.PStack; -import org.springframework.context.ApplicationContext; - -import com.aol.micro.server.module.Environment; -import com.aol.micro.server.module.Module; -import com.aol.micro.server.module.ModuleDataExtractor; -import com.aol.micro.server.servers.ServerApplication; -import com.aol.micro.server.servers.ServerApplicationFactory; -import com.aol.micro.server.servers.model.AllData; -import com.aol.micro.server.servers.model.FilterData; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.servers.model.ServletData; - -@AllArgsConstructor -public class TomcatApplicationFactory implements ServerApplicationFactory { - - - - - public ServerApplication createApp(final Module module, final ApplicationContext rootContext) { - ModuleDataExtractor extractor = new ModuleDataExtractor(module); - PStack resources = extractor.getRestResources(rootContext); - - Environment environment = rootContext.getBean(Environment.class); - - environment.assureModule(module); - String fullRestResource = "/" + module.getContext() + "/*"; - - ServerData serverData = new ServerData(environment.getModuleBean(module).getPort(), - resources, - rootContext, fullRestResource, module); - List filterDataList = extractor.createFilteredDataList(serverData); - List servletDataList = extractor.createServletDataList(serverData); - - TomcatApplication app = new TomcatApplication( - new AllData(serverData, - filterDataList, - servletDataList, - module.getListeners(serverData), - module.getRequestListeners(serverData))); - return app; - } -} diff --git a/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/TomcatListener.java b/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/TomcatListener.java deleted file mode 100644 index 4c87e4bd2..000000000 --- a/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/TomcatListener.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.aol.micro.server.servers.tomcat; - -import java.util.Set; - -import javax.servlet.ServletContainerInitializer; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletException; -import javax.servlet.ServletRequestListener; - -import org.pcollections.PStack; - -import lombok.AllArgsConstructor; - -import com.aol.micro.server.servers.FilterConfigurer; -import com.aol.micro.server.servers.JaxRsServletConfigurer; -import com.aol.micro.server.servers.ServerThreadLocalVariables; -import com.aol.micro.server.servers.ServletConfigurer; -import com.aol.micro.server.servers.ServletContextListenerConfigurer; -import com.aol.micro.server.servers.model.FilterData; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.servers.model.ServletData; -@AllArgsConstructor -public class TomcatListener implements ServletContainerInitializer { - - - private final JaxRsServletConfigurer jaxRsConfigurer; - private final ServerData serverData; - - private final PStack filterData; - private final PStack servletData; - private final PStack servletContextListenerData; - private final PStack servletRequestListenerData; - - - @Override - public void onStartup(Set> classes, ServletContext webappContext) - throws ServletException { - try { - ServerThreadLocalVariables.getContext().set(serverData.getModule().getContext()); - - jaxRsConfigurer.addServlet(this.serverData,webappContext); - - new ServletConfigurer(serverData, servletData).addServlets(webappContext); - - new FilterConfigurer(serverData, this.filterData).addFilters(webappContext); - new ServletContextListenerConfigurer(serverData, servletContextListenerData, servletRequestListenerData).addListeners(webappContext); - - } - catch (Exception ex) { - - } - } - - - -} \ No newline at end of file diff --git a/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/plugin/TomcatPlugin.java b/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/plugin/TomcatPlugin.java deleted file mode 100644 index 99ed60b5b..000000000 --- a/micro-tomcat/src/main/java/com/aol/micro/server/servers/tomcat/plugin/TomcatPlugin.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.aol.micro.server.servers.tomcat.plugin; - -import java.util.Optional; - -import com.aol.micro.server.Plugin; -import com.aol.micro.server.servers.ServerApplicationFactory; -import com.aol.micro.server.servers.tomcat.TomcatApplicationFactory; - - -public class TomcatPlugin implements Plugin{ - - @Override - public Optional serverApplicationFactory(){ - return Optional.of(new TomcatApplicationFactory()); - } - - -} diff --git a/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/SSLConfigurationBuilder.java b/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/SSLConfigurationBuilder.java new file mode 100644 index 000000000..1ffa237f7 --- /dev/null +++ b/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/SSLConfigurationBuilder.java @@ -0,0 +1,32 @@ +package com.oath.micro.server.servers.tomcat; + + + +import org.apache.coyote.http11.AbstractHttp11JsseProtocol; + + +import com.oath.micro.server.config.SSLProperties; + +public class SSLConfigurationBuilder { + + + public void build(AbstractHttp11JsseProtocol protocol,SSLProperties sslProperties) { + protocol.setKeystoreFile(sslProperties.getKeyStoreFile()); // contains server keypair + protocol.setKeyPass(sslProperties.getKeyStorePass()); + sslProperties.getKeyStoreType().ifPresent(type->protocol.setKeystoreType(type)); + sslProperties.getKeyStoreProvider().ifPresent(provider->protocol.setKeystoreProvider(provider)); + + sslProperties.getTrustStoreFile().ifPresent(file->protocol.setTruststoreFile(file)); // contains client certificate + sslProperties.getTrustStorePass().ifPresent(pass->protocol.setTruststorePass(pass)); + + sslProperties.getTrustStoreType().ifPresent(type->protocol.setTruststoreType(type)); + sslProperties.getTrustStoreProvider().ifPresent(provider->protocol.setTruststoreProvider(provider)); + sslProperties.getClientAuth().ifPresent(auth->protocol.setClientAuth(auth)); + + protocol.setSSLEnabled(true); + sslProperties.getCiphers().ifPresent(ciphers->protocol.setCiphers(ciphers)); + sslProperties.getProtocol().ifPresent(pr->protocol.setSslProtocol(pr)); + + + } +} diff --git a/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/TomcatApplication.java b/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/TomcatApplication.java new file mode 100644 index 000000000..ad1e6f24a --- /dev/null +++ b/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/TomcatApplication.java @@ -0,0 +1,175 @@ +package com.oath.micro.server.servers.tomcat; + +import java.io.File; +import java.util.HashSet; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import javax.servlet.ServletContextListener; +import javax.servlet.ServletRequestListener; + +import com.oath.cyclops.types.persistent.PersistentList; +import com.oath.cyclops.util.ExceptionSoftener; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import org.apache.catalina.LifecycleException; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.valves.AccessLogValve; +import org.apache.catalina.valves.Constants; +import org.apache.coyote.ProtocolHandler; +import org.apache.coyote.http11.AbstractHttp11JsseProtocol; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +import com.oath.micro.server.InternalErrorCode; +import com.oath.micro.server.config.SSLProperties; +import com.oath.micro.server.module.WebServerProvider; +import com.oath.micro.server.servers.AccessLogLocationBean; +import com.oath.micro.server.servers.JaxRsServletConfigurer; +import com.oath.micro.server.servers.ServerApplication; +import com.oath.micro.server.servers.model.AllData; +import com.oath.micro.server.servers.model.FilterData; +import com.oath.micro.server.servers.model.ServerData; +import com.oath.micro.server.servers.model.ServletData; +import org.springframework.beans.factory.BeanNotOfRequiredTypeException; + +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class TomcatApplication implements ServerApplication { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Getter + private final ServerData serverData; + + private final PersistentList filterData; + private final PersistentList servletData; + private final PersistentList servletContextListenerData; + private final PersistentList servletRequestListenerData; + + public TomcatApplication(AllData serverData) { + this.serverData = serverData.getServerData(); + this.filterData = serverData.getFilterDataList(); + this.servletData = serverData.getServletDataList(); + this.servletContextListenerData = serverData.getServletContextListeners(); + this.servletRequestListenerData = serverData.getServletRequestListeners(); + } + + public void run(CompletableFuture start, JaxRsServletConfigurer jaxRsConfigurer, CompletableFuture end) { + Tomcat tomcat = new Tomcat(); + tomcat.setPort(serverData.getPort()); + tomcat.getHost().setAutoDeploy(false); + tomcat.getEngine().setBackgroundProcessorDelay(-1); + File docBase = new File("."); + StandardContext context =(StandardContext)tomcat.addContext("", docBase.getAbsolutePath()); + context.addServletContainerInitializer(new TomcatListener(jaxRsConfigurer, serverData, filterData, servletData, servletContextListenerData, servletRequestListenerData), + new HashSet<>()); + addAccessLog(tomcat,context); + + serverData.getModule().getServerConfigManager().accept(new WebServerProvider(tomcat)); + + addSSL(tomcat.getConnector()); + + startServer(tomcat, start, end); + } + + private void addSSL(Connector connector) { + try { + + SSLProperties sslProperties = serverData.getRootContext().getBean(SSLProperties.class); + ProtocolHandler handler = connector.getProtocolHandler(); + if (sslProperties != null && handler instanceof AbstractHttp11JsseProtocol) { + new SSLConfigurationBuilder().build((AbstractHttp11JsseProtocol) handler, sslProperties); + connector.setScheme("https"); + connector.setSecure(true); + } + + } catch (BeanNotOfRequiredTypeException e) { + + } + + + } + + private void startServer( Tomcat httpServer, CompletableFuture start, CompletableFuture end) { + + try { + logger.info("Starting application {} on port {}", serverData.getModule().getContext(), serverData.getPort()); + logger.info("Browse to http://localhost:{}{}/application.wadl", serverData.getPort(), serverData.getNormalizedContextPath()); + logger.info("Configured resource classes :-"); + serverData.extractResources().forEach( + t -> logger.info(t._1() + " : " + "http://localhost:" + serverData.getPort() + serverData.getNormalizedContextPath() + t._2())); + ; + + httpServer.start(); + + start.complete(true); + end.get(); + + }catch (LifecycleException e) { + throw ExceptionSoftener.throwSoftenedException(e); + } catch (ExecutionException e) { + throw ExceptionSoftener.throwSoftenedException(e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw ExceptionSoftener.throwSoftenedException(e); + } finally { + try { + httpServer.stop(); + httpServer.getConnector().destroy(); + httpServer.getEngine().destroy(); + httpServer.destroy(); + + + + } catch (LifecycleException e) { + } + try{ + Thread.sleep(5_000); + } + catch (InterruptedException e) { + + } + + } + } + + private void addAccessLog(Tomcat httpServer, StandardContext context) { + try { + + String accessLogLocation = serverData.getRootContext().getBean(AccessLogLocationBean.class).getAccessLogLocation(); + + accessLogLocation = accessLogLocation + "/" + replaceSlash(serverData.getModule().getContext()) + "-access.log"; + + AccessLogValve accessLogValve = new AccessLogValve(); + accessLogValve.setDirectory(accessLogLocation); + accessLogValve.setPattern(Constants.AccessLog.COMMON_ALIAS); + accessLogValve.setSuffix(".log"); + accessLogValve.setRotatable(true); + context.getPipeline().addValve(accessLogValve); + + } catch (Exception e) { + + logger.error(InternalErrorCode.SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG.toString() + ": " + e.getMessage()); + if (e.getCause() != null) + logger.error("CAUSED BY: " + InternalErrorCode.SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG.toString() + ": " + e.getCause().getMessage()); + + } + + } + + + + private String replaceSlash(String context) { + if (context != null && context.contains("/")) { + return context.substring(0, context.indexOf("/")); + } + return context; + } + +} diff --git a/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/TomcatApplicationFactory.java b/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/TomcatApplicationFactory.java new file mode 100644 index 000000000..4ccc07be6 --- /dev/null +++ b/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/TomcatApplicationFactory.java @@ -0,0 +1,50 @@ +package com.oath.micro.server.servers.tomcat; + +import java.util.List; + +import com.oath.cyclops.types.persistent.PersistentList; +import com.oath.micro.server.module.MicroserverEnvironment; +import lombok.AllArgsConstructor; + + +import org.springframework.context.ApplicationContext; + +import com.oath.micro.server.module.Module; +import com.oath.micro.server.module.ModuleDataExtractor; +import com.oath.micro.server.servers.ServerApplication; +import com.oath.micro.server.servers.ServerApplicationFactory; +import com.oath.micro.server.servers.model.AllData; +import com.oath.micro.server.servers.model.FilterData; +import com.oath.micro.server.servers.model.ServerData; +import com.oath.micro.server.servers.model.ServletData; + +@AllArgsConstructor +public class TomcatApplicationFactory implements ServerApplicationFactory { + + + + + public ServerApplication createApp(final Module module, final ApplicationContext rootContext) { + ModuleDataExtractor extractor = new ModuleDataExtractor(module); + PersistentList resources = extractor.getRestResources(rootContext); + + MicroserverEnvironment microserverEnvironment = rootContext.getBean(MicroserverEnvironment.class); + + microserverEnvironment.assureModule(module); + String fullRestResource = "/" + module.getContext() + "/*"; + + ServerData serverData = new ServerData(microserverEnvironment.getModuleBean(module).getPort(), + resources, + rootContext, fullRestResource, module); + List filterDataList = extractor.createFilteredDataList(serverData); + List servletDataList = extractor.createServletDataList(serverData); + + TomcatApplication app = new TomcatApplication( + new AllData(serverData, + filterDataList, + servletDataList, + module.getListeners(serverData), + module.getRequestListeners(serverData))); + return app; + } +} diff --git a/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/TomcatListener.java b/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/TomcatListener.java new file mode 100644 index 000000000..0c3d27050 --- /dev/null +++ b/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/TomcatListener.java @@ -0,0 +1,57 @@ +package com.oath.micro.server.servers.tomcat; + +import java.util.Set; + +import javax.servlet.ServletContainerInitializer; +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletException; +import javax.servlet.ServletRequestListener; + + +import com.oath.cyclops.types.persistent.PersistentList; +import lombok.AllArgsConstructor; + +import com.oath.micro.server.servers.FilterConfigurer; +import com.oath.micro.server.servers.JaxRsServletConfigurer; +import com.oath.micro.server.servers.ServerThreadLocalVariables; +import com.oath.micro.server.servers.ServletConfigurer; +import com.oath.micro.server.servers.ServletContextListenerConfigurer; +import com.oath.micro.server.servers.model.FilterData; +import com.oath.micro.server.servers.model.ServerData; +import com.oath.micro.server.servers.model.ServletData; +@AllArgsConstructor +public class TomcatListener implements ServletContainerInitializer { + + + private final JaxRsServletConfigurer jaxRsConfigurer; + private final ServerData serverData; + + private final PersistentList filterData; + private final PersistentList servletData; + private final PersistentList servletContextListenerData; + private final PersistentList servletRequestListenerData; + + + @Override + public void onStartup(Set> classes, ServletContext webappContext) + throws ServletException { + try { + ServerThreadLocalVariables.getContext().set(serverData.getModule().getContext()); + + jaxRsConfigurer.addServlet(this.serverData,webappContext); + + new ServletConfigurer(serverData, servletData).addServlets(webappContext); + + new FilterConfigurer(serverData, this.filterData).addFilters(webappContext); + new ServletContextListenerConfigurer(serverData, servletContextListenerData, servletRequestListenerData).addListeners(webappContext); + + } + catch (Exception ex) { + + } + } + + + +} \ No newline at end of file diff --git a/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/plugin/TomcatPlugin.java b/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/plugin/TomcatPlugin.java new file mode 100644 index 000000000..48dba1da0 --- /dev/null +++ b/micro-tomcat/src/main/java/com/oath/micro/server/servers/tomcat/plugin/TomcatPlugin.java @@ -0,0 +1,18 @@ +package com.oath.micro.server.servers.tomcat.plugin; + +import java.util.Optional; + +import com.oath.micro.server.Plugin; +import com.oath.micro.server.servers.ServerApplicationFactory; +import com.oath.micro.server.servers.tomcat.TomcatApplicationFactory; + + +public class TomcatPlugin implements Plugin{ + + @Override + public Optional serverApplicationFactory(){ + return Optional.of(new TomcatApplicationFactory()); + } + + +} diff --git a/micro-tomcat/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-tomcat/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 397770690..000000000 --- a/micro-tomcat/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.servers.tomcat.plugin.TomcatPlugin \ No newline at end of file diff --git a/micro-tomcat/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-tomcat/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..b608d6d79 --- /dev/null +++ b/micro-tomcat/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.servers.tomcat.plugin.TomcatPlugin \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/access/log/micro/server/servers/AccessLogConfigTest.java b/micro-tomcat/src/test/java/app/access/log/micro/server/servers/AccessLogConfigTest.java index 3c97147d2..57d456fac 100644 --- a/micro-tomcat/src/test/java/app/access/log/micro/server/servers/AccessLogConfigTest.java +++ b/micro-tomcat/src/test/java/app/access/log/micro/server/servers/AccessLogConfigTest.java @@ -11,8 +11,8 @@ import org.junit.Before; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; @Microserver(properties={"access.log.output", "${user.home}"}) public class AccessLogConfigTest { diff --git a/micro-tomcat/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java b/micro-tomcat/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java deleted file mode 100644 index a5b427b75..000000000 --- a/micro-tomcat/src/test/java/app/async/com/aol/micro/server/AsyncAppRunner.java +++ /dev/null @@ -1,58 +0,0 @@ -package app.async.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.io.IOException; -import java.util.Properties; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.spring.properties.PropertyFileConfig; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class AsyncAppRunner { - - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - - server = new MicroserverApp( ()-> "async-app"); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - Thread.sleep(2000); - - assertThat(rest.get("http://localhost:8080/async-app/async/expensive"),is(";test!;test!;test!")); - - } - - @Test - public void loadProperties() throws IOException{ - - Properties props = new PropertyFileConfig(true).propertyFactory() ; - assertThat(props.getProperty("test"),is("hello world")); - } - - - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/async/com/aol/micro/server/AsyncResource.java b/micro-tomcat/src/test/java/app/async/com/aol/micro/server/AsyncResource.java deleted file mode 100644 index d87c018d6..000000000 --- a/micro-tomcat/src/test/java/app/async/com/aol/micro/server/AsyncResource.java +++ /dev/null @@ -1,56 +0,0 @@ -package app.async.com.aol.micro.server; - -import java.util.Arrays; -import java.util.List; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.container.Suspended; - -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.ReactiveSeq; -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.testing.RestAgent; - -@Path("/async") -@Component -public class AsyncResource implements RestResource{ - - private final SimpleReact simpleReact =new SimpleReact(); - private final List urls = Arrays.asList("http://localhost:8080/async-app/async/ping2", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping", - "http://localhost:8080/async-app/async/ping"); - - private final RestAgent client = new RestAgent(); - - @GET - @Path("/expensive") - @Produces("text/plain") - public void expensive(@Suspended AsyncResponse asyncResponse){ - - LazyFutureStream.lazyFutureStreamFromIterable(urls) - .then(it->client.get(it)) - .onFail(it -> "") - .peek(it -> - System.out.println(it)) - .convertToSimpleReact() - .allOf(data -> { - System.out.println(data); - return asyncResponse.resume(ReactiveSeq.fromIterable(data).join(";")); }); - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - -} diff --git a/micro-tomcat/src/test/java/app/async/com/aol/micro/server/Simple.java b/micro-tomcat/src/test/java/app/async/com/aol/micro/server/Simple.java deleted file mode 100644 index edefa80ef..000000000 --- a/micro-tomcat/src/test/java/app/async/com/aol/micro/server/Simple.java +++ /dev/null @@ -1,16 +0,0 @@ -package app.async.com.aol.micro.server; - -import java.io.IOException; -import java.util.Properties; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Config; -import com.aol.micro.server.spring.properties.PropertyFileConfig; - -public class Simple { - - public static void main(String[] args) throws IOException{ - - new MicroserverApp(()->"test-app").run(); - } -} diff --git a/micro-tomcat/src/test/java/app/async/com/aol/micro/server/SimpleApp.java b/micro-tomcat/src/test/java/app/async/com/aol/micro/server/SimpleApp.java deleted file mode 100644 index 919b7c6b0..000000000 --- a/micro-tomcat/src/test/java/app/async/com/aol/micro/server/SimpleApp.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.async.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; - - - -@Rest -@Path("/test") -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()->"test-app").run(); - } - @GET - public String myEndPoint(){ - return "hello world!"; - } - - -} diff --git a/micro-tomcat/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java b/micro-tomcat/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java new file mode 100644 index 000000000..79933ea7a --- /dev/null +++ b/micro-tomcat/src/test/java/app/async/com/oath/micro/server/AsyncAppRunner.java @@ -0,0 +1,58 @@ +package app.async.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.Properties; +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.spring.properties.PropertyFileConfig; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class AsyncAppRunner { + + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + + server = new MicroserverApp( ()-> "async-app"); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + Thread.sleep(2000); + + assertThat(rest.get("http://localhost:8080/async-app/async/expensive"),is(";test!;test!;test!")); + + } + + @Test + public void loadProperties() throws IOException{ + + Properties props = new PropertyFileConfig(true).propertyFactory() ; + assertThat(props.getProperty("test"),is("hello world")); + } + + + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/async/com/oath/micro/server/AsyncResource.java b/micro-tomcat/src/test/java/app/async/com/oath/micro/server/AsyncResource.java new file mode 100644 index 000000000..cb2193ce4 --- /dev/null +++ b/micro-tomcat/src/test/java/app/async/com/oath/micro/server/AsyncResource.java @@ -0,0 +1,57 @@ +package app.async.com.oath.micro.server; + +import java.util.Arrays; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; + +import cyclops.futurestream.SimpleReact; +import cyclops.futurestream.FutureStream; +import cyclops.reactive.ReactiveSeq; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.testing.RestAgent; + +@Path("/async") +@Component +public class AsyncResource implements RestResource{ + + private final SimpleReact simpleReact =new SimpleReact(); + private final List urls = Arrays.asList("http://localhost:8080/async-app/async/ping2", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping", + "http://localhost:8080/async-app/async/ping"); + + private final RestAgent client = new RestAgent(); + + @GET + @Path("/expensive") + @Produces("text/plain") + public void expensive(@Suspended AsyncResponse asyncResponse){ + + FutureStream.builder().fromIterable(urls) + .then(it->client.get(it)) + .onFail(it -> "") + .peek(it -> + System.out.println(it)) + .convertToSimpleReact() + .allOf(data -> { + System.out.println(data); + return asyncResponse.resume(ReactiveSeq.fromIterable(data).join(";")); }); + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "test!"; + } + + +} diff --git a/micro-tomcat/src/test/java/app/async/com/oath/micro/server/Simple.java b/micro-tomcat/src/test/java/app/async/com/oath/micro/server/Simple.java new file mode 100644 index 000000000..3eb3e7504 --- /dev/null +++ b/micro-tomcat/src/test/java/app/async/com/oath/micro/server/Simple.java @@ -0,0 +1,13 @@ +package app.async.com.oath.micro.server; + +import java.io.IOException; + +import com.oath.micro.server.MicroserverApp; + +public class Simple { + + public static void main(String[] args) throws IOException{ + + new MicroserverApp(()->"test-app").run(); + } +} diff --git a/micro-tomcat/src/test/java/app/async/com/oath/micro/server/SimpleApp.java b/micro-tomcat/src/test/java/app/async/com/oath/micro/server/SimpleApp.java new file mode 100644 index 000000000..916d0330e --- /dev/null +++ b/micro-tomcat/src/test/java/app/async/com/oath/micro/server/SimpleApp.java @@ -0,0 +1,24 @@ +package app.async.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; + + + +@Rest +@Path("/test") +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()->"test-app").run(); + } + @GET + public String myEndPoint(){ + return "hello world!"; + } + + +} diff --git a/micro-tomcat/src/test/java/app/custom/binder/test/SimpleApp.java b/micro-tomcat/src/test/java/app/custom/binder/test/SimpleApp.java index 35fda203b..2906df5fd 100644 --- a/micro-tomcat/src/test/java/app/custom/binder/test/SimpleApp.java +++ b/micro-tomcat/src/test/java/app/custom/binder/test/SimpleApp.java @@ -7,9 +7,9 @@ import org.glassfish.jersey.server.ResourceConfig; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.module.ConfigurableModule; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.module.ConfigurableModule; diff --git a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java b/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java deleted file mode 100644 index d4b8eff5c..000000000 --- a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/AltAppResource.java +++ /dev/null @@ -1,23 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.ArrayList; -import java.util.List; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -@Component -@Path("/alt-status") -public class AltAppResource implements AltAppRestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public List ping(ImmutableEntity entity) { - return entity.getList(); - } - -} diff --git a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java b/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java deleted file mode 100644 index 8cb2643e3..000000000 --- a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/AltAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface AltAppRestResource extends RestResource { - -} diff --git a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java b/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java deleted file mode 100644 index bc73c2862..000000000 --- a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppLocalMain.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.Arrays; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.EmbeddedModule; - -@Microserver(basePackages = { "app.embedded.com.aol.micro.server" }) -public class EmbeddedAppLocalMain { - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( - EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")).start(); - - - - } - - -} diff --git a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java b/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java deleted file mode 100644 index 12c1148d1..000000000 --- a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/EmbeddedAppTest.java +++ /dev/null @@ -1,103 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.NotFoundException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.EmbeddedModule; -import com.aol.micro.server.testing.RestAgent; -@Ignore //micro-monolith doesn't work with Tomcat at the moment, because tomcat MBean registrations clash -public class EmbeddedAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer(){ - server = new MicroserverApp(EmbeddedAppLocalMain.class, - EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), - EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")); - server.start(); - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); - - - assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), - hasItem("hello")); - - } - - - @Test - public void nonBlockingRestClientTest(){ - assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"),is("-*test!-*test!")); - } - - CompletableFuture toCompletableFuture( - final ListenableFuture listenableFuture - ) { - //create an instance of CompletableFuture - CompletableFuture completable = new CompletableFuture() { - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - // propagate cancel to the listenable future - boolean result = listenableFuture.cancel(mayInterruptIfRunning); - super.cancel(mayInterruptIfRunning); - return result; - } - }; - - // add callback - listenableFuture.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(T result) { - completable.complete(result); - } - - @Override - public void onFailure(Throwable t) { - completable.completeExceptionally(t); - } - }); - return completable; - } - - @Test(expected=NotFoundException.class) - public void confirmAltAppCantUseTestAppResources(){ - - assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); - - } - @Test(expected=NotFoundException.class) - public void confirmTestAppCantUseAltAppResources(){ - - assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), - hasItem("hello")); - - } -} diff --git a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java b/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java deleted file mode 100644 index 778c55c90..000000000 --- a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/ImmutableEntity.java +++ /dev/null @@ -1,29 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableEntity { - - private final String value; - private final List list; - - public ImmutableEntity() { - this(null,null); - } - -} diff --git a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java b/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java deleted file mode 100644 index e93d43724..000000000 --- a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/TestAppResource.java +++ /dev/null @@ -1,48 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import java.util.Arrays; -import java.util.List; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.LazyFutureStream; -import com.aol.micro.server.testing.RestAgent; -@Component -@Path("/test-status") -public class TestAppResource implements TestAppRestResource { - - private final SimpleReact simpleReact = new SimpleReact(); - private final RestAgent template = new RestAgent(); - private final List urls = Arrays.asList("http://localhost:8081/alternative-app/alt-status/ping", - "http://localhost:8080/test-app/test-status/ping", - "http://localhost:8082/simple-app/status/ping", - "http://localhost:8080/test-app/test-status/ping"); - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "test!"; - } - - @GET - @Produces("text/plain") - @Path("/rest-calls") - public String restCallResult(){ - - return LazyFutureStream.lazyFutureStreamFromIterable(urls) - .map(it ->template.get(it)) - .then(it -> "*"+it) - .peek(loadedAndModified -> System.out.println(loadedAndModified)) - .block().stream().reduce("", (acc,next) -> acc+"-"+next); - - } - -} diff --git a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java b/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java deleted file mode 100644 index 3133fd8cc..000000000 --- a/micro-tomcat/src/test/java/app/embedded/com/aol/micro/server/TestAppRestResource.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.embedded.com.aol.micro.server; - -import com.aol.micro.server.auto.discovery.RestResource; - -public interface TestAppRestResource extends RestResource { - -} diff --git a/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java new file mode 100644 index 000000000..1835ababe --- /dev/null +++ b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/AltAppResource.java @@ -0,0 +1,22 @@ +package app.embedded.com.oath.micro.server; + +import java.util.List; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +@Component +@Path("/alt-status") +public class AltAppResource implements AltAppRestResource { + + @POST + @Produces("application/json") + @Path("/ping") + public List ping(ImmutableEntity entity) { + return entity.getList(); + } + +} diff --git a/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java new file mode 100644 index 000000000..7045a4f35 --- /dev/null +++ b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/AltAppRestResource.java @@ -0,0 +1,7 @@ +package app.embedded.com.oath.micro.server; + +import com.oath.micro.server.auto.discovery.RestResource; + +public interface AltAppRestResource extends RestResource { + +} diff --git a/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java new file mode 100644 index 000000000..dbb290069 --- /dev/null +++ b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppLocalMain.java @@ -0,0 +1,24 @@ +package app.embedded.com.oath.micro.server; + +import java.util.Arrays; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.EmbeddedModule; + +@Microserver(basePackages = { "app.embedded.com.oath.micro.server" }) +public class EmbeddedAppLocalMain { + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( + EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), + EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")).start(); + + + + } + + +} diff --git a/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java new file mode 100644 index 000000000..eb0daed57 --- /dev/null +++ b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/EmbeddedAppTest.java @@ -0,0 +1,103 @@ +package app.embedded.com.oath.micro.server; + +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.NotFoundException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.util.concurrent.ListenableFuture; +import org.springframework.util.concurrent.ListenableFutureCallback; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.EmbeddedModule; +import com.oath.micro.server.testing.RestAgent; +@Ignore //micro-monolith doesn't work with Tomcat at the moment, because tomcat MBean registrations clash +public class EmbeddedAppTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer(){ + server = new MicroserverApp(EmbeddedAppLocalMain.class, + EmbeddedModule.tagInterfaceModule(Arrays.asList(TestAppRestResource.class),"test-app"), + EmbeddedModule.tagInterfaceModule(Arrays.asList(AltAppRestResource.class),"alternative-app")); + server.start(); + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void confirmExpectedUrlsPresentTest() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/test-app/test-status/ping"),is("test!")); + + + assertThat((List)rest.post("http://localhost:8081/alternative-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), + hasItem("hello")); + + } + + + @Test + public void nonBlockingRestClientTest(){ + assertThat(rest.get("http://localhost:8080/test-app/test-status/rest-calls"),is("-*test!-*test!")); + } + + CompletableFuture toCompletableFuture( + final ListenableFuture listenableFuture + ) { + //create an instance of CompletableFuture + CompletableFuture completable = new CompletableFuture() { + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + // propagate cancel to the listenable future + boolean result = listenableFuture.cancel(mayInterruptIfRunning); + super.cancel(mayInterruptIfRunning); + return result; + } + }; + + // add callback + listenableFuture.addCallback(new ListenableFutureCallback() { + @Override + public void onSuccess(T result) { + completable.complete(result); + } + + @Override + public void onFailure(Throwable t) { + completable.completeExceptionally(t); + } + }); + return completable; + } + + @Test(expected=NotFoundException.class) + public void confirmAltAppCantUseTestAppResources(){ + + assertThat(rest.get("http://localhost:8080/alternative-app/test-status/ping"),is("test!")); + + } + @Test(expected=NotFoundException.class) + public void confirmTestAppCantUseAltAppResources(){ + + assertThat((List)rest.post("http://localhost:8081/test-app/alt-status/ping",new ImmutableEntity("value",Arrays.asList("hello","world")),List.class), + hasItem("hello")); + + } +} diff --git a/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java new file mode 100644 index 000000000..337b63b89 --- /dev/null +++ b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/ImmutableEntity.java @@ -0,0 +1,29 @@ +package app.embedded.com.oath.micro.server; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "immutable") +@Getter +@AllArgsConstructor +@Builder +public class ImmutableEntity { + + private final String value; + private final List list; + + public ImmutableEntity() { + this(null,null); + } + +} diff --git a/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java new file mode 100644 index 000000000..539e24cd1 --- /dev/null +++ b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/TestAppResource.java @@ -0,0 +1,49 @@ +package app.embedded.com.oath.micro.server; + +import java.util.Arrays; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import cyclops.futurestream.FutureStream; +import cyclops.futurestream.SimpleReact; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.testing.RestAgent; +@Component +@Path("/test-status") +public class TestAppResource implements TestAppRestResource { + + private final SimpleReact simpleReact = new SimpleReact(); + private final RestAgent template = new RestAgent(); + private final List urls = Arrays.asList("http://localhost:8081/alternative-app/alt-status/ping", + "http://localhost:8080/test-app/test-status/ping", + "http://localhost:8082/simple-app/status/ping", + "http://localhost:8080/test-app/test-status/ping"); + + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "test!"; + } + + @GET + @Produces("text/plain") + @Path("/rest-calls") + public String restCallResult(){ + + return FutureStream.builder().fromIterable(urls) + .map(it ->template.get(it)) + .then(it -> "*"+it) + .peek(loadedAndModified -> System.out.println(loadedAndModified)) + .block().stream().reduce("", (acc,next) -> acc+"-"+next); + + } + +} diff --git a/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java new file mode 100644 index 000000000..7d4df5753 --- /dev/null +++ b/micro-tomcat/src/test/java/app/embedded/com/oath/micro/server/TestAppRestResource.java @@ -0,0 +1,7 @@ +package app.embedded.com.oath.micro.server; + +import com.oath.micro.server.auto.discovery.RestResource; + +public interface TestAppRestResource extends RestResource { + +} diff --git a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/AutodiscoveredFilter.java b/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/AutodiscoveredFilter.java deleted file mode 100644 index 0ea5b4990..000000000 --- a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/AutodiscoveredFilter.java +++ /dev/null @@ -1,68 +0,0 @@ -package app.filter.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import lombok.Getter; -import lombok.Setter; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.FilterConfiguration; - -@Component -public class AutodiscoveredFilter implements Filter, FilterConfiguration { - - @Autowired - Bean bean; - @Getter - @Setter - private static volatile int called= 0; - - @Getter - private static boolean beanSet = false; - - @Override - public String[] getMapping() { - return new String[] { "/*" }; - } - public Class getFilter(){ - - return org.springframework.web.filter.DelegatingFilterProxy.class; - - } - public String getName(){ - return "autodiscoveredFilter"; - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - - called++; - if(bean!=null) - beanSet =true; - chain.doFilter(request, response); - } - - @Override - public void destroy() { - - - } - - - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/Bean.java b/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/Bean.java deleted file mode 100644 index f95b44b05..000000000 --- a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/Bean.java +++ /dev/null @@ -1,8 +0,0 @@ -package app.filter.com.aol.micro.server; - -import org.springframework.stereotype.Component; - -@Component -public class Bean { - -} diff --git a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/ConfiguredFilter.java b/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/ConfiguredFilter.java deleted file mode 100644 index e00bc941b..000000000 --- a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/ConfiguredFilter.java +++ /dev/null @@ -1,38 +0,0 @@ -package app.filter.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import lombok.Getter; - -public class ConfiguredFilter implements Filter { - - @Getter - private static volatile int called= 0; - @Override - public void init(FilterConfig filterConfig) throws ServletException { - // TODO Auto-generated method stub - - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - called++; - chain.doFilter(request, response); - - } - - @Override - public void destroy() { - // TODO Auto-generated method stub - - } - -} diff --git a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/FilterAppLocalMain.java b/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/FilterAppLocalMain.java deleted file mode 100644 index 25dc01cc3..000000000 --- a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/FilterAppLocalMain.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.filter.com.aol.micro.server; - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import app.servlet.com.aol.micro.server.AppRunnerLocalMain; - -import com.aol.micro.server.MicroserverApp; -@Configuration -@ComponentScan(basePackages = { "app.filter.com.aol.micro.server" }) -public class FilterAppLocalMain { - - - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( FilterAppLocalMain.class, () -> "filter-app") - .run(); - } - - } \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/FilterRunnerTest.java b/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/FilterRunnerTest.java deleted file mode 100644 index 9b16a9a24..000000000 --- a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/FilterRunnerTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package app.filter.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.Map; -import java.util.concurrent.ExecutionException; - -import javax.servlet.Filter; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; -import com.aol.micro.server.utility.HashMapBuilder; - - - -public class FilterRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - Thread.sleep(500); - Map filters = HashMapBuilder.map("/filter-app/status/ping2",new ConfiguredFilter()).build(); - server = new MicroserverApp(ConfigurableModule.builder() - .context("filter-app") - .filters(filters ) - .requestListeners(Arrays.asList(new org.springframework.web.context.request.RequestContextListener())).build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testAutoDiscoveredFilter() throws InterruptedException, ExecutionException{ - AutodiscoveredFilter.setCalled(0); - - assertThat(rest.get("http://localhost:8080/filter-app/status/ping"),is("ok")); - assertThat(AutodiscoveredFilter.getCalled(),is(1)); - assertThat(AutodiscoveredFilter.isBeanSet(),is(true)); - } - @Test - public void testConfiguredFilter() throws InterruptedException, ExecutionException{ - - assertThat(ConfiguredFilter.getCalled(),is(0)); - assertThat(rest.get("http://localhost:8080/filter-app/status/ping2"),is("ok")); - assertThat(ConfiguredFilter.getCalled(),is(1)); - } - - - - -} diff --git a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/FilterStatusResource.java b/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/FilterStatusResource.java deleted file mode 100644 index 2d046711b..000000000 --- a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/FilterStatusResource.java +++ /dev/null @@ -1,37 +0,0 @@ -package app.filter.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; -import org.springframework.web.context.WebApplicationContext; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) -@Path("/status") -public class FilterStatusResource implements RestResource { - - @Autowired - private RequestScopeUserInfo info; - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - info.print(); - return "ok"; - } - @GET - @Produces("text/plain") - @Path("/ping2") - public String ping2() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/RequestScopeUserInfo.java b/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/RequestScopeUserInfo.java deleted file mode 100644 index c41605c39..000000000 --- a/micro-tomcat/src/test/java/app/filter/com/aol/micro/server/RequestScopeUserInfo.java +++ /dev/null @@ -1,20 +0,0 @@ -package app.filter.com.aol.micro.server; - -import javax.servlet.http.HttpServletRequest; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.context.annotation.ScopedProxyMode; -import org.springframework.stereotype.Component; -import org.springframework.web.context.WebApplicationContext; - -@Component -@Scope(value=WebApplicationContext.SCOPE_REQUEST,proxyMode=ScopedProxyMode.TARGET_CLASS) -public class RequestScopeUserInfo { - @Autowired - private HttpServletRequest request; - - public void print(){ - System.out.println(request.getAttribute("oc.info")); - } -} diff --git a/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/AutodiscoveredFilter.java b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/AutodiscoveredFilter.java new file mode 100644 index 000000000..1f6dfc284 --- /dev/null +++ b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/AutodiscoveredFilter.java @@ -0,0 +1,70 @@ +package app.filter.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import cyclops.control.Either; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + + +import com.oath.micro.server.auto.discovery.AutoFilterConfiguration; + +import lombok.Getter; +import lombok.Setter; + +@Component +public class AutodiscoveredFilter implements AutoFilterConfiguration { + + @Autowired + Bean bean; + @Getter + @Setter + private static volatile int called= 0; + + @Getter + private static boolean beanSet = false; + + @Override + public String[] getMapping() { + return new String[] { "/*" }; + } + public Either,Filter> getFilter(){ + + return Either.left(org.springframework.web.filter.DelegatingFilterProxy.class); + + } + public String getName(){ + return "autodiscoveredFilter"; + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + + called++; + if(bean!=null) + beanSet =true; + chain.doFilter(request, response); + } + + @Override + public void destroy() { + + + } + + + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/Bean.java b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/Bean.java new file mode 100644 index 000000000..e036a796f --- /dev/null +++ b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/Bean.java @@ -0,0 +1,8 @@ +package app.filter.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +@Component +public class Bean { + +} diff --git a/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/ConfiguredFilter.java b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/ConfiguredFilter.java new file mode 100644 index 000000000..aca52ad38 --- /dev/null +++ b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/ConfiguredFilter.java @@ -0,0 +1,38 @@ +package app.filter.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import lombok.Getter; + +public class ConfiguredFilter implements Filter { + + @Getter + private static volatile int called= 0; + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // TODO Auto-generated method stub + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + called++; + chain.doFilter(request, response); + + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + +} diff --git a/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/FilterAppLocalMain.java b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/FilterAppLocalMain.java new file mode 100644 index 000000000..b650780a2 --- /dev/null +++ b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/FilterAppLocalMain.java @@ -0,0 +1,20 @@ +package app.filter.com.oath.micro.server; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.MicroserverApp; +@Configuration +@ComponentScan(basePackages = { "app.filter.com.aol.micro.server" }) +public class FilterAppLocalMain { + + + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( FilterAppLocalMain.class, () -> "filter-app") + .run(); + } + + } \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/FilterRunnerTest.java b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/FilterRunnerTest.java new file mode 100644 index 000000000..13b563fd2 --- /dev/null +++ b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/FilterRunnerTest.java @@ -0,0 +1,67 @@ +package app.filter.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import javax.servlet.Filter; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; +import com.oath.micro.server.utility.HashMapBuilder; + + + +public class FilterRunnerTest { + + RestAgent rest = new RestAgent(); + + static MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + Thread.sleep(500); + Map filters = HashMapBuilder.map("/filter-app/status/ping2",new ConfiguredFilter()).build(); + server = new MicroserverApp(ConfigurableModule.builder() + .context("filter-app") + .filters(filters ) + .requestListeners(Arrays.asList(new org.springframework.web.context.request.RequestContextListener())).build()); + server.start(); + + } + + @AfterClass + public static void stopServer(){ + server.stop(); + } + + @Test + public void testAutoDiscoveredFilter() throws InterruptedException, ExecutionException{ + AutodiscoveredFilter.setCalled(0); + + assertThat(rest.get("http://localhost:8080/filter-app/status/ping"),is("ok")); + assertThat(AutodiscoveredFilter.getCalled(),is(1)); + assertThat(AutodiscoveredFilter.isBeanSet(),is(true)); + } + @Test + public void testConfiguredFilter() throws InterruptedException, ExecutionException{ + + assertThat(ConfiguredFilter.getCalled(),is(0)); + assertThat(rest.get("http://localhost:8080/filter-app/status/ping2"),is("ok")); + assertThat(ConfiguredFilter.getCalled(),is(1)); + } + + + + +} diff --git a/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/FilterStatusResource.java b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/FilterStatusResource.java new file mode 100644 index 000000000..c7166c216 --- /dev/null +++ b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/FilterStatusResource.java @@ -0,0 +1,36 @@ +package app.filter.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) +@Path("/status") +public class FilterStatusResource implements RestResource { + + @Autowired + private RequestScopeUserInfo info; + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + info.print(); + return "ok"; + } + @GET + @Produces("text/plain") + @Path("/ping2") + public String ping2() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/RequestScopeUserInfo.java b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/RequestScopeUserInfo.java new file mode 100644 index 000000000..84c19c3f4 --- /dev/null +++ b/micro-tomcat/src/test/java/app/filter/com/oath/micro/server/RequestScopeUserInfo.java @@ -0,0 +1,20 @@ +package app.filter.com.oath.micro.server; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.stereotype.Component; +import org.springframework.web.context.WebApplicationContext; + +@Component +@Scope(value=WebApplicationContext.SCOPE_REQUEST,proxyMode=ScopedProxyMode.TARGET_CLASS) +public class RequestScopeUserInfo { + @Autowired + private HttpServletRequest request; + + public void print(){ + System.out.println(request.getAttribute("oc.info")); + } +} diff --git a/micro-tomcat/src/test/java/app/jackson/custom/com/aol/micro/server/CustomRunnerTest.java b/micro-tomcat/src/test/java/app/jackson/custom/com/aol/micro/server/CustomRunnerTest.java deleted file mode 100644 index e7e14f98f..000000000 --- a/micro-tomcat/src/test/java/app/jackson/custom/com/aol/micro/server/CustomRunnerTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package app.jackson.custom.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class CustomRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - assertThat(rest.postString("http://localhost:8080/simple-app/status/ping","{\"primitive\":null}").getStatus(),is(500)); - - - } - - - -} diff --git a/micro-tomcat/src/test/java/app/jackson/custom/com/aol/micro/server/CustomStatusResource.java b/micro-tomcat/src/test/java/app/jackson/custom/com/aol/micro/server/CustomStatusResource.java deleted file mode 100644 index d765ba53f..000000000 --- a/micro-tomcat/src/test/java/app/jackson/custom/com/aol/micro/server/CustomStatusResource.java +++ /dev/null @@ -1,20 +0,0 @@ -package app.jackson.custom.com.aol.micro.server; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class CustomStatusResource { - - @POST - @Path("/ping") - public String ping(MyEntity entity) { - return "ok"; - - } - - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/jackson/custom/com/aol/micro/server/MapperExtension.java b/micro-tomcat/src/test/java/app/jackson/custom/com/aol/micro/server/MapperExtension.java deleted file mode 100644 index 3bd1c4e45..000000000 --- a/micro-tomcat/src/test/java/app/jackson/custom/com/aol/micro/server/MapperExtension.java +++ /dev/null @@ -1,18 +0,0 @@ -package app.jackson.custom.com.aol.micro.server; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.jackson.JacksonMapperConfigurator; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; - -@Component -public class MapperExtension implements JacksonMapperConfigurator { - - @Override - public void accept(ObjectMapper t) { - t.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true); - - } - -} diff --git a/micro-tomcat/src/test/java/app/jackson/custom/com/aol/micro/server/MyEntity.java b/micro-tomcat/src/test/java/app/jackson/custom/com/aol/micro/server/MyEntity.java deleted file mode 100644 index e62499bff..000000000 --- a/micro-tomcat/src/test/java/app/jackson/custom/com/aol/micro/server/MyEntity.java +++ /dev/null @@ -1,26 +0,0 @@ -package app.jackson.custom.com.aol.micro.server; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.Value; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "myentity") -public class MyEntity { - - @XmlElement(name="primitive") - int i; - - public MyEntity(int i) { - super(); - this.i = i; - } - public MyEntity(){ - this.i=-1; - } -} diff --git a/micro-tomcat/src/test/java/app/jackson/custom/com/oath/micro/server/CustomRunnerTest.java b/micro-tomcat/src/test/java/app/jackson/custom/com/oath/micro/server/CustomRunnerTest.java new file mode 100644 index 000000000..3c2bba459 --- /dev/null +++ b/micro-tomcat/src/test/java/app/jackson/custom/com/oath/micro/server/CustomRunnerTest.java @@ -0,0 +1,54 @@ +package app.jackson.custom.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class CustomRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + assertThat(rest.postString("http://localhost:8080/simple-app/status/ping","{\"primitive\":null}").getStatus(),is(400)); + + + } + + + +} diff --git a/micro-tomcat/src/test/java/app/jackson/custom/com/oath/micro/server/CustomStatusResource.java b/micro-tomcat/src/test/java/app/jackson/custom/com/oath/micro/server/CustomStatusResource.java new file mode 100644 index 000000000..6e8a488ba --- /dev/null +++ b/micro-tomcat/src/test/java/app/jackson/custom/com/oath/micro/server/CustomStatusResource.java @@ -0,0 +1,20 @@ +package app.jackson.custom.com.oath.micro.server; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class CustomStatusResource { + + @POST + @Path("/ping") + public String ping(MyEntity entity) { + return "ok"; + + } + + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/jackson/custom/com/oath/micro/server/MapperExtension.java b/micro-tomcat/src/test/java/app/jackson/custom/com/oath/micro/server/MapperExtension.java new file mode 100644 index 000000000..60a50428a --- /dev/null +++ b/micro-tomcat/src/test/java/app/jackson/custom/com/oath/micro/server/MapperExtension.java @@ -0,0 +1,18 @@ +package app.jackson.custom.com.oath.micro.server; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.jackson.JacksonMapperConfigurator; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +@Component +public class MapperExtension implements JacksonMapperConfigurator { + + @Override + public void accept(ObjectMapper t) { + t.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true); + + } + +} diff --git a/micro-tomcat/src/test/java/app/jackson/custom/com/oath/micro/server/MyEntity.java b/micro-tomcat/src/test/java/app/jackson/custom/com/oath/micro/server/MyEntity.java new file mode 100644 index 000000000..79f8f0b9a --- /dev/null +++ b/micro-tomcat/src/test/java/app/jackson/custom/com/oath/micro/server/MyEntity.java @@ -0,0 +1,24 @@ +package app.jackson.custom.com.oath.micro.server; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "myentity") +public class MyEntity { + + @XmlElement(name="primitive") + int i; + + public MyEntity(int i) { + super(); + this.i = i; + } + public MyEntity(){ + this.i=-1; + } +} diff --git a/micro-tomcat/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/IncludesRunnerTest.java b/micro-tomcat/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/IncludesRunnerTest.java deleted file mode 100644 index 6edc161bb..000000000 --- a/micro-tomcat/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/IncludesRunnerTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package app.jackson.includes.all.com.aol.micro.server.copy; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(properties={"jackson.serialization","ALWAYS"}) -public class IncludesRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - Thread.sleep(5000); - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.getJson("http://localhost:8080/simple-app/status/ping"),is("{\"primitive\":null}")); - - - } - - - -} diff --git a/micro-tomcat/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/IncludesStatusResource.java b/micro-tomcat/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/IncludesStatusResource.java deleted file mode 100644 index 566d503b9..000000000 --- a/micro-tomcat/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/IncludesStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.jackson.includes.all.com.aol.micro.server.copy; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class IncludesStatusResource { - - @GET - @Path("/ping") - @Produces("application/json") - public MyEntity ping() { - return new MyEntity(); - - } - - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/MyEntity.java b/micro-tomcat/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/MyEntity.java deleted file mode 100644 index e2c6b02ba..000000000 --- a/micro-tomcat/src/test/java/app/jackson/includes/all/com/aol/micro/server/copy/MyEntity.java +++ /dev/null @@ -1,26 +0,0 @@ -package app.jackson.includes.all.com.aol.micro.server.copy; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.Value; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "myentity") -public class MyEntity { - - @XmlElement(name="primitive") - Integer i = null; - - public MyEntity(int i) { - super(); - this.i = i; - } - public MyEntity(){ - this.i=null; - } -} diff --git a/micro-tomcat/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/IncludesRunnerTest.java b/micro-tomcat/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/IncludesRunnerTest.java new file mode 100644 index 000000000..05581a3fa --- /dev/null +++ b/micro-tomcat/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/IncludesRunnerTest.java @@ -0,0 +1,56 @@ +package app.jackson.includes.all.com.oath.micro.server.copy; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties={"jackson.serialization","ALWAYS"}) +public class IncludesRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + Thread.sleep(5000); + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.getJson("http://localhost:8080/simple-app/status/ping"),is("{\"primitive\":null}")); + + + } + + + +} diff --git a/micro-tomcat/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/IncludesStatusResource.java b/micro-tomcat/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/IncludesStatusResource.java new file mode 100644 index 000000000..bc0d8f3bb --- /dev/null +++ b/micro-tomcat/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/IncludesStatusResource.java @@ -0,0 +1,22 @@ +package app.jackson.includes.all.com.oath.micro.server.copy; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class IncludesStatusResource { + + @GET + @Path("/ping") + @Produces("application/json") + public MyEntity ping() { + return new MyEntity(); + + } + + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/MyEntity.java b/micro-tomcat/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/MyEntity.java new file mode 100644 index 000000000..2b28c5d5b --- /dev/null +++ b/micro-tomcat/src/test/java/app/jackson/includes/all/com/oath/micro/server/copy/MyEntity.java @@ -0,0 +1,24 @@ +package app.jackson.includes.all.com.oath.micro.server.copy; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "myentity") +public class MyEntity { + + @XmlElement(name="primitive") + Integer i = null; + + public MyEntity(int i) { + super(); + this.i = i; + } + public MyEntity(){ + this.i=null; + } +} diff --git a/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/IncludesRunnerTest.java b/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/IncludesRunnerTest.java deleted file mode 100644 index a311d0a80..000000000 --- a/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/IncludesRunnerTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package app.jackson.includes.nonnull.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.core.Response; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class IncludesRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - Thread.sleep(5000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.getJson("http://localhost:8080/simple-app/status/ping"),is("{}")); - - - } - - - -} diff --git a/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/IncludesStatusResource.java b/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/IncludesStatusResource.java deleted file mode 100644 index f3a9b74b4..000000000 --- a/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/IncludesStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.jackson.includes.nonnull.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class IncludesStatusResource { - - @GET - @Path("/ping") - @Produces("application/json") - public MyEntity ping() { - return new MyEntity(); - - } - - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/MyEntity.java b/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/MyEntity.java deleted file mode 100644 index 3caa39982..000000000 --- a/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/aol/micro/server/MyEntity.java +++ /dev/null @@ -1,26 +0,0 @@ -package app.jackson.includes.nonnull.com.aol.micro.server; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.Value; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "myentity") -public class MyEntity { - - @XmlElement(name="primitive") - Integer i = null; - - public MyEntity(int i) { - super(); - this.i = i; - } - public MyEntity(){ - this.i=null; - } -} diff --git a/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/IncludesRunnerTest.java b/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/IncludesRunnerTest.java new file mode 100644 index 000000000..89130e833 --- /dev/null +++ b/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/IncludesRunnerTest.java @@ -0,0 +1,55 @@ +package app.jackson.includes.nonnull.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class IncludesRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + Thread.sleep(5000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.getJson("http://localhost:8080/simple-app/status/ping"),is("{}")); + + + } + + + +} diff --git a/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/IncludesStatusResource.java b/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/IncludesStatusResource.java new file mode 100644 index 000000000..477b68744 --- /dev/null +++ b/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/IncludesStatusResource.java @@ -0,0 +1,22 @@ +package app.jackson.includes.nonnull.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class IncludesStatusResource { + + @GET + @Path("/ping") + @Produces("application/json") + public MyEntity ping() { + return new MyEntity(); + + } + + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/MyEntity.java b/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/MyEntity.java new file mode 100644 index 000000000..6671f20d4 --- /dev/null +++ b/micro-tomcat/src/test/java/app/jackson/includes/nonnull/com/oath/micro/server/MyEntity.java @@ -0,0 +1,24 @@ +package app.jackson.includes.nonnull.com.oath.micro.server; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "myentity") +public class MyEntity { + + @XmlElement(name="primitive") + Integer i = null; + + public MyEntity(int i) { + super(); + this.i = i; + } + public MyEntity(){ + this.i=null; + } +} diff --git a/micro-tomcat/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java b/micro-tomcat/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java deleted file mode 100644 index bff7cbdc8..000000000 --- a/micro-tomcat/src/test/java/app/listeners/com/aol/micro/server/AutodiscoveredListener.java +++ /dev/null @@ -1,35 +0,0 @@ -package app.listeners.com.aol.micro.server; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import lombok.Getter; - -import org.springframework.stereotype.Component; - -@Component -public class AutodiscoveredListener implements ServletContextListener { - - @Getter - private static volatile int called= 0; - - @Override - public void contextInitialized(ServletContextEvent sce) { - called ++; - - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - - - } - - - - - - - - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/listeners/com/aol/micro/server/ConfiguredListener.java b/micro-tomcat/src/test/java/app/listeners/com/aol/micro/server/ConfiguredListener.java deleted file mode 100644 index d15dcb76e..000000000 --- a/micro-tomcat/src/test/java/app/listeners/com/aol/micro/server/ConfiguredListener.java +++ /dev/null @@ -1,25 +0,0 @@ -package app.listeners.com.aol.micro.server; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import lombok.Getter; - -public class ConfiguredListener implements ServletContextListener { - - @Getter - private static volatile int called= 0; - - @Override - public void contextInitialized(ServletContextEvent sce) { - called ++; - - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - - - } - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java b/micro-tomcat/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java deleted file mode 100644 index 4f8d7ab69..000000000 --- a/micro-tomcat/src/test/java/app/listeners/com/aol/micro/server/ListenerRunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.listeners.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.ExecutionException; - -import javax.servlet.ServletContextListener; - - - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - - -@Microserver -public class ListenerRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - List listeners = Arrays.asList(new ConfiguredListener()); - server = new MicroserverApp( ListenerRunnerTest.class, ConfigurableModule.builder().context("listener-app").listeners(listeners ).build()); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testListeners() throws InterruptedException, ExecutionException{ - - assertThat(AutodiscoveredListener.getCalled(),is(1)); - assertThat(ConfiguredListener.getCalled(),is(1)); - } - - - - - -} diff --git a/micro-tomcat/src/test/java/app/listeners/com/oath/micro/server/AutodiscoveredListener.java b/micro-tomcat/src/test/java/app/listeners/com/oath/micro/server/AutodiscoveredListener.java new file mode 100644 index 000000000..a3dfdff21 --- /dev/null +++ b/micro-tomcat/src/test/java/app/listeners/com/oath/micro/server/AutodiscoveredListener.java @@ -0,0 +1,35 @@ +package app.listeners.com.oath.micro.server; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import lombok.Getter; + +import org.springframework.stereotype.Component; + +@Component +public class AutodiscoveredListener implements ServletContextListener { + + @Getter + private static volatile int called= 0; + + @Override + public void contextInitialized(ServletContextEvent sce) { + called ++; + + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + + + } + + + + + + + + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/listeners/com/oath/micro/server/ConfiguredListener.java b/micro-tomcat/src/test/java/app/listeners/com/oath/micro/server/ConfiguredListener.java new file mode 100644 index 000000000..86a7cd34b --- /dev/null +++ b/micro-tomcat/src/test/java/app/listeners/com/oath/micro/server/ConfiguredListener.java @@ -0,0 +1,25 @@ +package app.listeners.com.oath.micro.server; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import lombok.Getter; + +public class ConfiguredListener implements ServletContextListener { + + @Getter + private static volatile int called= 0; + + @Override + public void contextInitialized(ServletContextEvent sce) { + called ++; + + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + + + } + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/listeners/com/oath/micro/server/ListenerRunnerTest.java b/micro-tomcat/src/test/java/app/listeners/com/oath/micro/server/ListenerRunnerTest.java new file mode 100644 index 000000000..fa0222a76 --- /dev/null +++ b/micro-tomcat/src/test/java/app/listeners/com/oath/micro/server/ListenerRunnerTest.java @@ -0,0 +1,55 @@ +package app.listeners.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import javax.servlet.ServletContextListener; + + + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + + +@Microserver +public class ListenerRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer(){ + List listeners = Arrays.asList(new ConfiguredListener()); + server = new MicroserverApp( ListenerRunnerTest.class, ConfigurableModule.builder().context("listener-app").listeners(listeners ).build()); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void testListeners() throws InterruptedException, ExecutionException{ + + assertThat(AutodiscoveredListener.getCalled(),is(1)); + assertThat(ConfiguredListener.getCalled(),is(1)); + } + + + + + +} diff --git a/micro-tomcat/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java b/micro-tomcat/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java deleted file mode 100644 index 04367ecbd..000000000 --- a/micro-tomcat/src/test/java/app/minimal/com/aol/micro/server/MinimalClassTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package app.minimal.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.testing.RestAgent; - -@Rest -@Path("/single") -public class MinimalClassTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer(){ - - server = new MicroserverApp(()-> "minimal-app"); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"),is("ok")); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java b/micro-tomcat/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java new file mode 100644 index 000000000..6640ecea0 --- /dev/null +++ b/micro-tomcat/src/test/java/app/minimal/com/oath/micro/server/MinimalClassTest.java @@ -0,0 +1,57 @@ +package app.minimal.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.testing.RestAgent; + +@Rest +@Path("/single") +public class MinimalClassTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer() { + + server = new MicroserverApp( + () -> "minimal-app"); + server.start(); + + } + + @After + public void stopServer() { + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException { + + Thread.sleep(500l); + assertThat(rest.get("http://localhost:8080/minimal-app/single/ping"), is("ok")); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoRunnerTest.java b/micro-tomcat/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoRunnerTest.java deleted file mode 100644 index 92abed060..000000000 --- a/micro-tomcat/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoRunnerTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package app.noanno.com.aol.micro.server.copy; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - - -public class NoAnnoRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - - server = new MicroserverApp(()-> "simple-app"); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); - - - } - - - -} diff --git a/micro-tomcat/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoStatusResource.java b/micro-tomcat/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoStatusResource.java deleted file mode 100644 index 8a3f5efaa..000000000 --- a/micro-tomcat/src/test/java/app/noanno/com/aol/micro/server/copy/NoAnnoStatusResource.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.noanno.com.aol.micro.server.copy; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class NoAnnoStatusResource { - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/noanno/com/aol/micro/server/copy/SimpleApp.java b/micro-tomcat/src/test/java/app/noanno/com/aol/micro/server/copy/SimpleApp.java deleted file mode 100644 index 5fb7e2ca3..000000000 --- a/micro-tomcat/src/test/java/app/noanno/com/aol/micro/server/copy/SimpleApp.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.noanno.com.aol.micro.server.copy; - -import com.aol.micro.server.MicroserverApp; - -public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()-> "simple-app").run(); - } - - -} diff --git a/micro-tomcat/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoRunnerTest.java b/micro-tomcat/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoRunnerTest.java new file mode 100644 index 000000000..b476e2791 --- /dev/null +++ b/micro-tomcat/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoRunnerTest.java @@ -0,0 +1,48 @@ +package app.noanno.com.oath.micro.server.copy; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; + + +public class NoAnnoRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + + server = new MicroserverApp(()-> "simple-app"); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); + + + } + + + +} diff --git a/micro-tomcat/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoStatusResource.java b/micro-tomcat/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoStatusResource.java new file mode 100644 index 000000000..11a42968e --- /dev/null +++ b/micro-tomcat/src/test/java/app/noanno/com/oath/micro/server/copy/NoAnnoStatusResource.java @@ -0,0 +1,24 @@ +package app.noanno.com.oath.micro.server.copy; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class NoAnnoStatusResource { + + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/noanno/com/oath/micro/server/copy/SimpleApp.java b/micro-tomcat/src/test/java/app/noanno/com/oath/micro/server/copy/SimpleApp.java new file mode 100644 index 000000000..646004a31 --- /dev/null +++ b/micro-tomcat/src/test/java/app/noanno/com/oath/micro/server/copy/SimpleApp.java @@ -0,0 +1,12 @@ +package app.noanno.com.oath.micro.server.copy; + +import com.oath.micro.server.MicroserverApp; + +public class SimpleApp { + + public static void main(String[] args){ + new MicroserverApp(()-> "simple-app").run(); + } + + +} diff --git a/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java b/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java deleted file mode 100644 index b447491a1..000000000 --- a/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/AppRunnerLocalMain.java +++ /dev/null @@ -1,20 +0,0 @@ -package app.servlet.com.aol.micro.server; - - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import com.aol.micro.server.MicroserverApp; - -@Configuration -@ComponentScan(basePackages = { "app.servlet.com.aol.micro.server" }) -public class AppRunnerLocalMain { - - - public static void main(String[] args) throws InterruptedException { - - new MicroserverApp( AppRunnerLocalMain.class, () -> "test-app") - .run(); - } - -} diff --git a/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java b/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java deleted file mode 100644 index d0123c905..000000000 --- a/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/AutodiscoveredServlet.java +++ /dev/null @@ -1,30 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.ServletConfiguration; - -@Component -public class AutodiscoveredServlet extends HttpServlet implements ServletConfiguration { - - @Override - public String[] getMapping() { - return new String[] { "/servlet" }; - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - resp.setContentType("text/html"); - resp.getWriter().write("hello world"); - } - -} diff --git a/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java b/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java deleted file mode 100644 index 92577a92e..000000000 --- a/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/ConfiguredServlet.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import java.io.IOException; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class ConfiguredServlet extends HttpServlet { - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - resp.setContentType("text/html"); - resp.getWriter().write("configured servlet"); - } - - - -} diff --git a/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java b/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java deleted file mode 100644 index 40ea43478..000000000 --- a/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/ServletRunnerTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package app.servlet.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ExecutionException; - -import javax.servlet.Servlet; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -public class ServletRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - Map servlets = new HashMap<>(); - servlets.put("/configured", new ConfiguredServlet()); - server = new MicroserverApp( AppRunnerLocalMain.class, ConfigurableModule.builder().context("test-app").servlets(servlets ).build()); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/test-app/servlet/ping"),is("ok")); - assertThat(rest.get("http://localhost:8080/servlet"),is("hello world")); - assertThat(rest.get("http://localhost:8080/configured"),is("configured servlet")); - - } - - - - -} diff --git a/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java b/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java deleted file mode 100644 index 890a64679..000000000 --- a/micro-tomcat/src/test/java/app/servlet/com/aol/micro/server/ServletStatusResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.servlet.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/servlet") -public class ServletStatusResource implements RestResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/AppRunnerLocalMain.java b/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/AppRunnerLocalMain.java new file mode 100644 index 000000000..065973f62 --- /dev/null +++ b/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/AppRunnerLocalMain.java @@ -0,0 +1,20 @@ +package app.servlet.com.oath.micro.server; + + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.oath.micro.server.MicroserverApp; + +@Configuration +@ComponentScan(basePackages = { "app.servlet.com.aol.micro.server" }) +public class AppRunnerLocalMain { + + + public static void main(String[] args) throws InterruptedException { + + new MicroserverApp( AppRunnerLocalMain.class, () -> "test-app") + .run(); + } + +} diff --git a/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/AutodiscoveredServlet.java b/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/AutodiscoveredServlet.java new file mode 100644 index 000000000..66cbfd59c --- /dev/null +++ b/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/AutodiscoveredServlet.java @@ -0,0 +1,30 @@ +package app.servlet.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.AutoServletConfiguration; + +@Component +public class AutodiscoveredServlet extends HttpServlet implements AutoServletConfiguration { + + @Override + public String[] getMapping() { + return new String[] { "/servlet" }; + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + resp.setContentType("text/html"); + resp.getWriter().write("hello world"); + } + +} diff --git a/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/ConfiguredServlet.java b/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/ConfiguredServlet.java new file mode 100644 index 000000000..65de82291 --- /dev/null +++ b/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/ConfiguredServlet.java @@ -0,0 +1,21 @@ +package app.servlet.com.oath.micro.server; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class ConfiguredServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + resp.setContentType("text/html"); + resp.getWriter().write("configured servlet"); + } + + + +} diff --git a/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/ServletRunnerTest.java b/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/ServletRunnerTest.java new file mode 100644 index 000000000..0829b9f05 --- /dev/null +++ b/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/ServletRunnerTest.java @@ -0,0 +1,53 @@ +package app.servlet.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import javax.servlet.Servlet; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +public class ServletRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + Map servlets = new HashMap<>(); + servlets.put("/configured", new ConfiguredServlet()); + server = new MicroserverApp( AppRunnerLocalMain.class, ConfigurableModule.builder().context("test-app").servlets(servlets ).build()); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/test-app/servlet/ping"),is("ok")); + assertThat(rest.get("http://localhost:8080/servlet"),is("hello world")); + assertThat(rest.get("http://localhost:8080/configured"),is("configured servlet")); + + } + + + + +} diff --git a/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/ServletStatusResource.java b/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/ServletStatusResource.java new file mode 100644 index 000000000..6d86eeb84 --- /dev/null +++ b/micro-tomcat/src/test/java/app/servlet/com/oath/micro/server/ServletStatusResource.java @@ -0,0 +1,22 @@ +package app.servlet.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/servlet") +public class ServletStatusResource implements RestResource { + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java b/micro-tomcat/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java deleted file mode 100644 index 700a2c778..000000000 --- a/micro-tomcat/src/test/java/app/simple/com/aol/micro/server/SimpleApp.java +++ /dev/null @@ -1,18 +0,0 @@ -package app.simple.com.aol.micro.server; - -import java.util.Arrays; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.module.ConfigurableModule; - -public class SimpleApp { - - public static void main(String[] args){ - - new MicroserverApp(()-> "simple-app").run(); - } - - -} diff --git a/micro-tomcat/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java b/micro-tomcat/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java deleted file mode 100644 index 57bc0e1ef..000000000 --- a/micro-tomcat/src/test/java/app/simple/com/aol/micro/server/SimpleRunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.simple.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -public class SimpleRunnerTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - server = new MicroserverApp(ConfigurableModule - .builder() - .context("simple-app") - .defaultResources(Arrays.asList(MultiPartFeature.class)) - .build()); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); - - - } - - - -} diff --git a/micro-tomcat/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java b/micro-tomcat/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java deleted file mode 100644 index 07b6a5610..000000000 --- a/micro-tomcat/src/test/java/app/simple/com/aol/micro/server/SimpleStatusResource.java +++ /dev/null @@ -1,40 +0,0 @@ -package app.simple.com.aol.micro.server; - -import java.io.InputStream; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; -import org.glassfish.jersey.media.multipart.FormDataParam; - -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class SimpleStatusResource { - - - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - - return "ok"; - } - - @POST - @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces(MediaType.TEXT_PLAIN) - @Path("/file") - public String create(@FormDataParam("file") InputStream fileInputStream, - @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { - - return "done"; - } -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java b/micro-tomcat/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java new file mode 100644 index 000000000..e82a92291 --- /dev/null +++ b/micro-tomcat/src/test/java/app/simple/com/oath/micro/server/SimpleApp.java @@ -0,0 +1,13 @@ +package app.simple.com.oath.micro.server; + +import com.oath.micro.server.MicroserverApp; + +public class SimpleApp { + + public static void main(String[] args){ + + new MicroserverApp(()-> "simple-app").run(); + } + + +} diff --git a/micro-tomcat/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java b/micro-tomcat/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java new file mode 100644 index 000000000..504b5199e --- /dev/null +++ b/micro-tomcat/src/test/java/app/simple/com/oath/micro/server/SimpleRunnerTest.java @@ -0,0 +1,55 @@ +package app.simple.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +public class SimpleRunnerTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + server = new MicroserverApp(ConfigurableModule + .builder() + .context("simple-app") + .defaultResources(Arrays.asList(MultiPartFeature.class)) + .build()); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/status/ping"),is("ok")); + + + } + + + +} diff --git a/micro-tomcat/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java b/micro-tomcat/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java new file mode 100644 index 000000000..7be280bdf --- /dev/null +++ b/micro-tomcat/src/test/java/app/simple/com/oath/micro/server/SimpleStatusResource.java @@ -0,0 +1,40 @@ +package app.simple.com.oath.micro.server; + +import java.io.InputStream; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; + +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class SimpleStatusResource { + + + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + + return "ok"; + } + + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.TEXT_PLAIN) + @Path("/file") + public String create(@FormDataParam("file") InputStream fileInputStream, + @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { + + return "done"; + } +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java b/micro-tomcat/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java deleted file mode 100644 index 4839e9fff..000000000 --- a/micro-tomcat/src/test/java/app/single/com/aol/micro/server/SingleClassTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package app.single.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; - -@Microserver -@Path("/single") -public class SingleClassTest implements RestResource{ - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - - server = new MicroserverApp( SingleClassTest.class, ()-> "simple-app"); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/simple-app/single/ping"),is("ok")); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java b/micro-tomcat/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java new file mode 100644 index 000000000..324cf4dce --- /dev/null +++ b/micro-tomcat/src/test/java/app/single/com/oath/micro/server/SingleClassTest.java @@ -0,0 +1,59 @@ +package app.single.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; + +@Microserver +@Path("/single") +public class SingleClassTest implements RestResource{ + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + + server = new MicroserverApp( SingleClassTest.class, ()-> "simple-app"); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/simple-app/single/ping"),is("ok")); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java b/micro-tomcat/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java deleted file mode 100644 index aef7a170c..000000000 --- a/micro-tomcat/src/test/java/app/single/main/com/aol/micro/server/SingleClassApp.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.single.main.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.Rest; - -@Rest -@Path("/status") -public class SingleClassApp { - - public static void main(String[] args){ - new MicroserverApp(()-> "simple-app").run(); - } - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - -} diff --git a/micro-tomcat/src/test/java/app/single/main/com/oath/micro/server/SingleClassApp.java b/micro-tomcat/src/test/java/app/single/main/com/oath/micro/server/SingleClassApp.java new file mode 100644 index 000000000..2d7a71917 --- /dev/null +++ b/micro-tomcat/src/test/java/app/single/main/com/oath/micro/server/SingleClassApp.java @@ -0,0 +1,24 @@ +package app.single.main.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class SingleClassApp { + + public static void main(String[] args){ + new MicroserverApp(()-> "simple-app").run(); + } + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} diff --git a/micro-tomcat/src/test/java/app/single/serverconfig/com/aol/micro/server/SingleClassTest.java b/micro-tomcat/src/test/java/app/single/serverconfig/com/aol/micro/server/SingleClassTest.java deleted file mode 100644 index 5c0cb67b8..000000000 --- a/micro-tomcat/src/test/java/app/single/serverconfig/com/aol/micro/server/SingleClassTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package app.single.serverconfig.com.aol.micro.server; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.auto.discovery.RestResource; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.ConfigurableModule; -import com.aol.micro.server.testing.RestAgent; - - -@Path("/single") -public class SingleClassTest implements RestResource{ - - RestAgent rest = new RestAgent(); - - boolean called; - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - called = false; - server = new MicroserverApp( ConfigurableModule.builder() - .context("hello") - .serverConfigManager(server->called=true) - .build()); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/hello/single/ping"),is("ok")); - assertTrue(called); - - } - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/single/serverconfig/com/oath/micro/server/SingleClassTest.java b/micro-tomcat/src/test/java/app/single/serverconfig/com/oath/micro/server/SingleClassTest.java new file mode 100644 index 000000000..6d0bc5d09 --- /dev/null +++ b/micro-tomcat/src/test/java/app/single/serverconfig/com/oath/micro/server/SingleClassTest.java @@ -0,0 +1,64 @@ +package app.single.serverconfig.com.oath.micro.server; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.RestResource; +import com.oath.micro.server.module.ConfigurableModule; +import com.oath.micro.server.testing.RestAgent; + + +@Path("/single") +public class SingleClassTest implements RestResource{ + + RestAgent rest = new RestAgent(); + + boolean called; + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + called = false; + server = new MicroserverApp( ConfigurableModule.builder() + .context("hello") + .serverConfigManager(server->called=true) + .build()); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/hello/single/ping"),is("ok")); + assertTrue(called); + + } + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/spring/com/aol/micro/server/MyBean.java b/micro-tomcat/src/test/java/app/spring/com/aol/micro/server/MyBean.java deleted file mode 100644 index 1f7a589ff..000000000 --- a/micro-tomcat/src/test/java/app/spring/com/aol/micro/server/MyBean.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.spring.com.aol.micro.server; - -import javax.inject.Inject; - -import lombok.Getter; - -@Getter -public class MyBean { - - @Inject - private MyDependency injected; -} diff --git a/micro-tomcat/src/test/java/app/spring/com/aol/micro/server/MyDependency.java b/micro-tomcat/src/test/java/app/spring/com/aol/micro/server/MyDependency.java deleted file mode 100644 index 48d89e6c5..000000000 --- a/micro-tomcat/src/test/java/app/spring/com/aol/micro/server/MyDependency.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.spring.com.aol.micro.server; - -import lombok.Getter; - -import org.springframework.stereotype.Component; - -@Component -@Getter -public class MyDependency { - - private String data = "hello world"; -} diff --git a/micro-tomcat/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java b/micro-tomcat/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java deleted file mode 100644 index 6f777ba02..000000000 --- a/micro-tomcat/src/test/java/app/spring/com/aol/micro/server/SpringRunnerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.spring.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.context.annotation.Bean; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.testing.RestAgent; -/**@Configuration -@ComponentScan(basePackages = { "app.spring.com.aol.micro.server" })**/ -@Microserver -public class SpringRunnerTest { - - RestAgent rest = new RestAgent(); - - @Bean - public MyBean mybean(){ - return new MyBean(); - } - - MicroserverApp server; - @Before - public void startServer() throws InterruptedException{ - - server = new MicroserverApp( SpringRunnerTest.class, ()-> "spring-app"); - Thread.sleep(1000); - server.start(); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void testAutoWiring() throws InterruptedException, ExecutionException{ - - assertThat(rest.get("http://localhost:8080/spring-app/spring/ping"),is("hello world")); - - } - - - - - -} diff --git a/micro-tomcat/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java b/micro-tomcat/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java deleted file mode 100644 index 331ac997e..000000000 --- a/micro-tomcat/src/test/java/app/spring/com/aol/micro/server/SpringStatusResource.java +++ /dev/null @@ -1,32 +0,0 @@ -package app.spring.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; - -@Component -@Path("/spring") -public class SpringStatusResource implements RestResource { - - @Autowired - private MyBean mybean; - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return mybean.getInjected().getData(); - } - @GET - @Produces("text/plain") - @Path("/ping2") - public String ping2() { - return "ok"; - } - -} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/spring/com/oath/micro/server/MyBean.java b/micro-tomcat/src/test/java/app/spring/com/oath/micro/server/MyBean.java new file mode 100644 index 000000000..328b7d185 --- /dev/null +++ b/micro-tomcat/src/test/java/app/spring/com/oath/micro/server/MyBean.java @@ -0,0 +1,12 @@ +package app.spring.com.oath.micro.server; + +import javax.inject.Inject; + +import lombok.Getter; + +@Getter +public class MyBean { + + @Inject + private MyDependency injected; +} diff --git a/micro-tomcat/src/test/java/app/spring/com/oath/micro/server/MyDependency.java b/micro-tomcat/src/test/java/app/spring/com/oath/micro/server/MyDependency.java new file mode 100644 index 000000000..1ca23b15b --- /dev/null +++ b/micro-tomcat/src/test/java/app/spring/com/oath/micro/server/MyDependency.java @@ -0,0 +1,12 @@ +package app.spring.com.oath.micro.server; + +import lombok.Getter; + +import org.springframework.stereotype.Component; + +@Component +@Getter +public class MyDependency { + + private String data = "hello world"; +} diff --git a/micro-tomcat/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java b/micro-tomcat/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java new file mode 100644 index 000000000..8fb684d67 --- /dev/null +++ b/micro-tomcat/src/test/java/app/spring/com/oath/micro/server/SpringRunnerTest.java @@ -0,0 +1,55 @@ +package app.spring.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.annotation.Bean; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.testing.RestAgent; +/**@Configuration +@ComponentScan(basePackages = { "app.spring.com.oath.micro.server" })**/ +@Microserver +public class SpringRunnerTest { + + RestAgent rest = new RestAgent(); + + @Bean + public MyBean mybean(){ + return new MyBean(); + } + + MicroserverApp server; + @Before + public void startServer() throws InterruptedException{ + + server = new MicroserverApp( SpringRunnerTest.class, ()-> "spring-app"); + Thread.sleep(1000); + server.start(); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void testAutoWiring() throws InterruptedException, ExecutionException{ + + assertThat(rest.get("http://localhost:8080/spring-app/spring/ping"),is("hello world")); + + } + + + + + +} diff --git a/micro-tomcat/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java b/micro-tomcat/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java new file mode 100644 index 000000000..ae0c817de --- /dev/null +++ b/micro-tomcat/src/test/java/app/spring/com/oath/micro/server/SpringStatusResource.java @@ -0,0 +1,32 @@ +package app.spring.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; + +@Component +@Path("/spring") +public class SpringStatusResource implements RestResource { + + @Autowired + private MyBean mybean; + + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return mybean.getInjected().getData(); + } + @GET + @Produces("text/plain") + @Path("/ping2") + public String ping2() { + return "ok"; + } + +} \ No newline at end of file diff --git a/micro-tomcat/src/test/java/app/validation/com/aol/micro/server/ImmutableEntity.java b/micro-tomcat/src/test/java/app/validation/com/aol/micro/server/ImmutableEntity.java deleted file mode 100644 index 5af51d60c..000000000 --- a/micro-tomcat/src/test/java/app/validation/com/aol/micro/server/ImmutableEntity.java +++ /dev/null @@ -1,28 +0,0 @@ -package app.validation.com.aol.micro.server; - - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.experimental.Builder; - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "immutable") -@Getter -@AllArgsConstructor -@Builder -public class ImmutableEntity { - - private final String value; - - - public ImmutableEntity() { - this(null); - } - -} diff --git a/micro-tomcat/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java b/micro-tomcat/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java deleted file mode 100644 index 880c619e8..000000000 --- a/micro-tomcat/src/test/java/app/validation/com/aol/micro/server/ValidationAppResource.java +++ /dev/null @@ -1,23 +0,0 @@ -package app.validation.com.aol.micro.server; - -import javax.validation.constraints.NotNull; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.stereotype.Component; - -import com.aol.micro.server.auto.discovery.RestResource; -@Component -@Path("/status") -public class ValidationAppResource implements RestResource { - - @POST - @Produces("application/json") - @Path("/ping") - public ImmutableEntity ping( @NotNull ImmutableEntity entity) { - return entity; - } - - -} diff --git a/micro-tomcat/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java b/micro-tomcat/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java deleted file mode 100644 index 2ddec8a47..000000000 --- a/micro-tomcat/src/test/java/app/validation/com/aol/micro/server/ValidationAppTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package app.validation.com.aol.micro.server; - -import java.util.concurrent.ExecutionException; - -import javax.ws.rs.BadRequestException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aol.cyclops.control.SimpleReact; -import com.aol.cyclops.types.futurestream.SimpleReactStream; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.testing.RestAgent; - -//@Microserver(basePackages = { "app.guava.com.aol.micro.server" }) -public class ValidationAppTest { - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - ImmutableEntity entity; - - - SimpleReact simpleReact = new SimpleReact(); - SimpleReactStream stream; - - @Before - public void startServer() throws InterruptedException { - server = new MicroserverApp(() -> "guava-app"); - Thread.sleep(1000); - server.start(); - - - entity = ImmutableEntity.builder().value("value").build(); - - - } - - @After - public void stopServer() { - server.stop(); - } - - - @Test(expected=BadRequestException.class) - public void confirmError() throws InterruptedException, - ExecutionException { - - - //stream.block(); - - rest.post( - "http://localhost:8080/guava-app/status/ping", null, - ImmutableEntity.class); - - - } - @Test - public void confirmNoError() throws InterruptedException, - ExecutionException { - - //stream.block(); - rest.post( - "http://localhost:8080/guava-app/status/ping", entity, - ImmutableEntity.class); - - - } - - - -} diff --git a/micro-tomcat/src/test/java/app/validation/com/oath/micro/server/ImmutableEntity.java b/micro-tomcat/src/test/java/app/validation/com/oath/micro/server/ImmutableEntity.java new file mode 100644 index 000000000..19e8f5b26 --- /dev/null +++ b/micro-tomcat/src/test/java/app/validation/com/oath/micro/server/ImmutableEntity.java @@ -0,0 +1,28 @@ +package app.validation.com.oath.micro.server; + + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Builder; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "immutable") +@Getter +@AllArgsConstructor +@Builder +public class ImmutableEntity { + + private final String value; + + + public ImmutableEntity() { + this(null); + } + +} diff --git a/micro-tomcat/src/test/java/app/validation/com/oath/micro/server/ValidationAppErrorTest.java b/micro-tomcat/src/test/java/app/validation/com/oath/micro/server/ValidationAppErrorTest.java new file mode 100644 index 000000000..3d29ece0f --- /dev/null +++ b/micro-tomcat/src/test/java/app/validation/com/oath/micro/server/ValidationAppErrorTest.java @@ -0,0 +1,60 @@ +package app.validation.com.oath.micro.server; + +import com.oath.cyclops.types.futurestream.SimpleReactStream; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; +import cyclops.futurestream.SimpleReact; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.ws.rs.BadRequestException; +import java.util.concurrent.ExecutionException; + +//@Microserver(basePackages = { "app.guava.com.aol.micro.server" }) +public class ValidationAppErrorTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + ImmutableEntity entity; + + + SimpleReact simpleReact = new SimpleReact(); + SimpleReactStream stream; + + @Before + public void startServer() throws InterruptedException { + server = new MicroserverApp(() -> "guava-app"); + Thread.sleep(1000); + server.start(); + + + entity = ImmutableEntity.builder().value("value").build(); + + + } + + @After + public void stopServer() { + server.stop(); + } + + + @Test(expected=BadRequestException.class) + public void confirmError() throws InterruptedException, + ExecutionException { + + + //stream.block(); + + rest.post( + "http://localhost:8080/guava-app/status/ping", null, + ImmutableEntity.class); + + + } + + +} diff --git a/micro-tomcat/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java b/micro-tomcat/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java new file mode 100644 index 000000000..7a8d0c325 --- /dev/null +++ b/micro-tomcat/src/test/java/app/validation/com/oath/micro/server/ValidationAppResource.java @@ -0,0 +1,23 @@ +package app.validation.com.oath.micro.server; + +import javax.validation.constraints.NotNull; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.stereotype.Component; + +import com.oath.micro.server.auto.discovery.RestResource; +@Component +@Path("/status") +public class ValidationAppResource implements RestResource { + + @POST + @Produces("application/json") + @Path("/ping") + public ImmutableEntity ping( @NotNull ImmutableEntity entity) { + return entity; + } + + +} diff --git a/micro-tomcat/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java b/micro-tomcat/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java new file mode 100644 index 000000000..fa4163c82 --- /dev/null +++ b/micro-tomcat/src/test/java/app/validation/com/oath/micro/server/ValidationAppTest.java @@ -0,0 +1,65 @@ +package app.validation.com.oath.micro.server; + +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.BadRequestException; + + + +import com.oath.cyclops.types.futurestream.SimpleReactStream; +import cyclops.futurestream.SimpleReact; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.testing.RestAgent; + +//@Microserver(basePackages = { "app.guava.com.aol.micro.server" }) +public class ValidationAppTest { + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + ImmutableEntity entity; + + + SimpleReact simpleReact = new SimpleReact(); + SimpleReactStream stream; + + @Before + public void startServer() throws InterruptedException { + server = new MicroserverApp(() -> "guava-app"); + Thread.sleep(1000); + server.start(); + + + entity = ImmutableEntity.builder().value("value").build(); + + + } + + @After + public void stopServer() { + server.stop(); + } + + + + @Test + public void confirmNoError() throws InterruptedException, + ExecutionException { + + //stream.block(); + rest.post( + "http://localhost:8080/guava-app/status/ping", entity, + ImmutableEntity.class); + + + } + + + +} diff --git a/micro-tomcat/src/test/java/com/aol/micro/server/servers/ServerRunnerTest.java b/micro-tomcat/src/test/java/com/aol/micro/server/servers/ServerRunnerTest.java deleted file mode 100644 index e1f0d7c12..000000000 --- a/micro-tomcat/src/test/java/com/aol/micro/server/servers/ServerRunnerTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.aol.micro.server.servers; - -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; -import java.util.concurrent.CompletableFuture; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; -import org.springframework.context.ApplicationContext; - -import com.aol.micro.server.servers.model.AllData; -import com.aol.micro.server.servers.model.ServerData; -import com.aol.micro.server.servers.tomcat.TomcatApplication; - - - -public class ServerRunnerTest { - - private ServerRunner serverRunner; - private TomcatApplication serverApplication1; - private TomcatApplication serverApplication2; - private ServerData[] registered; - volatile int server1Count =0; - volatile int server2Count =0; - @Before - public void setUp() { - - server1Count =0; - server2Count =0; - - ServerData data1 = new ServerData(8080,Arrays.asList(), Mockito.mock(ApplicationContext.class), "url1", () -> "app-context"); - ServerData data2 = new ServerData(8081, Arrays.asList(), Mockito.mock(ApplicationContext.class), "url2", () -> "test-context"); - - serverApplication1 = new TomcatApplication(AllData.builder().serverData(data1).build()){ - @Override - public void run(CompletableFuture start,JaxRsServletConfigurer jaxRsConfigurer, CompletableFuture end) { - server1Count++; - start.complete(true); - - } - }; - serverApplication2 = new TomcatApplication(AllData.builder().serverData(data2).build()){ - @Override - public void run(CompletableFuture start,JaxRsServletConfigurer jaxRsConfigurer,CompletableFuture end) { - server2Count++; - start.complete(true); - - } - }; - - serverRunner = new ServerRunner( (array) -> {registered = array; } , - Arrays.asList(serverApplication1, serverApplication2), new CompletableFuture()); - - - } - - @Test - public void testRun() { - serverRunner.run(); - assertThat(server1Count,is(1)); - assertThat(server2Count,is(1)); - } -} diff --git a/micro-tomcat/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-tomcat/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index 24b169f2e..000000000 --- a/micro-tomcat/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - public Response postString(String url, String payload) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(payload,MediaType.APPLICATION_JSON)); - } - -} diff --git a/micro-tomcat/src/test/java/com/oath/micro/server/servers/ServerRunnerTest.java b/micro-tomcat/src/test/java/com/oath/micro/server/servers/ServerRunnerTest.java new file mode 100644 index 000000000..70f8ec704 --- /dev/null +++ b/micro-tomcat/src/test/java/com/oath/micro/server/servers/ServerRunnerTest.java @@ -0,0 +1,66 @@ +package com.oath.micro.server.servers; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.concurrent.CompletableFuture; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.context.ApplicationContext; + +import com.oath.micro.server.servers.model.AllData; +import com.oath.micro.server.servers.model.ServerData; +import com.oath.micro.server.servers.tomcat.TomcatApplication; + + + +public class ServerRunnerTest { + + private ServerRunner serverRunner; + private TomcatApplication serverApplication1; + private TomcatApplication serverApplication2; + private ServerData[] registered; + volatile int server1Count =0; + volatile int server2Count =0; + @Before + public void setUp() { + + server1Count =0; + server2Count =0; + + ServerData data1 = new ServerData(8080,Arrays.asList(), Mockito.mock(ApplicationContext.class), "url1", () -> "app-context"); + ServerData data2 = new ServerData(8081, Arrays.asList(), Mockito.mock(ApplicationContext.class), "url2", () -> "test-context"); + + serverApplication1 = new TomcatApplication(AllData.builder().serverData(data1).build()){ + @Override + public void run(CompletableFuture start,JaxRsServletConfigurer jaxRsConfigurer, CompletableFuture end) { + server1Count++; + start.complete(true); + + } + }; + serverApplication2 = new TomcatApplication(AllData.builder().serverData(data2).build()){ + @Override + public void run(CompletableFuture start,JaxRsServletConfigurer jaxRsConfigurer,CompletableFuture end) { + server2Count++; + start.complete(true); + + } + }; + + serverRunner = new ServerRunner( (array) -> {registered = array; } , + Arrays.asList(serverApplication1, serverApplication2), new CompletableFuture()); + + + } + + @Test + public void testRun() { + serverRunner.run(); + assertThat(server1Count,is(1)); + assertThat(server2Count,is(1)); + } +} diff --git a/micro-tomcat/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-tomcat/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..7b83464d9 --- /dev/null +++ b/micro-tomcat/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,64 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + public Response postString(String url, String payload) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(payload,MediaType.APPLICATION_JSON)); + } + +} diff --git a/micro-transactions/README.md b/micro-transactions/README.md new file mode 100644 index 000000000..0d206ceb6 --- /dev/null +++ b/micro-transactions/README.md @@ -0,0 +1,57 @@ +# Transactions Plugin + +[micro-transactions example apps](https://github.com/aol/micro-server/tree/master/micro-transactions/src/test/java/app) + +Handle transactions in a more fluid stream-like (&Java8 Style) fashion + + ```java +Integer result = TransactionFlow.of(transactionTemplate, this::load) + .map(this::save) + .execute(10) + .get(); +``` + +Inject in a preconfigured TransacitonFlow bean + ```java + + private final TransactionFlow flow; + @Autowired + public MyService(TransactionFlow flow){ + this.flow = flow; + } + +``` + +The map and flatMap your heart out. All mapped / flatMapped functions will be executed in the scope of a transaction. + + ```java + +flow.map(this::nextAvailable) + .map(this::updateStatus) + .execute(id); +``` + +TransactionFlow is modelled on the Reader monad (eek!) - which allows for lazy evaluation and dependency injection (hurray!) + +[Dependency injection using the Reader monad in Java 8](https://medium.com/@johnmcclean/dependency-injection-using-the-reader-monad-in-java8-9056d9501c75#.3wxsz9n2z) + +## To use + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-transactions/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.oath.microservices/micro-transactions) + +Simply add to the classpath + +Maven + +```xml + + com.oath.microservices + micro-transactions + x.yz + +``` + +Gradle +```gradle + compile 'com.oath.microservices:micro-transactions:x.yz' +``` diff --git a/micro-transactions/build.gradle b/micro-transactions/build.gradle index 3054b0369..f0e440cfc 100644 --- a/micro-transactions/build.gradle +++ b/micro-transactions/build.gradle @@ -1,73 +1,73 @@ description = 'micro-transactions' dependencies { - compile ('org.hibernate:hibernate-validator:'+hibernateValidator) { - exclude group: 'org.jboss.logging' - } - compile project(':micro-hibernate') - - testCompile project(':micro-client') - testCompile project(':micro-grizzly') - testCompile project(':micro-jersey') - testCompile project(':micro-hikaricp') - testCompile group: 'org.hsqldb', name:'hsqldb', version:'2.0.0' + compile('org.hibernate:hibernate-validator:' + hibernateValidator) { + exclude group: 'org.jboss.logging' + } + compile project(':micro-hibernate') + + testCompile project(':micro-client') + testCompile project(':micro-grizzly') + testCompile project(':micro-jersey') + testCompile project(':micro-hikaricp') + testCompile group: 'org.hsqldb', name: 'hsqldb', version: '2.0.0' } modifyPom { - project { - name 'Microserver transactions' - description 'Opinionated rest microservices' - url 'https://github.com/aol/micro-server' - inceptionYear '2015' + project { + name 'Microserver transactions' + description 'Opinionated rest microservices' + url 'https://github.com/aol/micro-server' + inceptionYear '2015' + + groupId 'com.oath.microservices' + artifactId 'micro-transactions' + version "$version" + + + scm { + url 'scm:git@github.com:aol/micro-server.git' + connection 'scm:git@github.com:aol/micro-server.git' + developerConnection 'scm:git@github.com:aol/micro-server.git' + } - groupId 'com.aol.microservices' - artifactId 'micro-transactions' - version "$version" - - - scm { - url 'scm:git@github.com:aol/micro-server.git' - connection 'scm:git@github.com:aol/micro-server.git' - developerConnection 'scm:git@github.com:aol/micro-server.git' - } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } + developers { + developer { + id 'johnmcclean-aol' + name 'John McClean' + email 'john.mcclean@teamaol.com' + } + developer { + id 'kewangie' + name 'Ke Wang' + email 'ke.wang@teamaol.com' + } + developer { + id 'earlzero' + name 'Nikita Sapozhnikov' + email 'nikita.sapozhnikov@teamaol.com' + } + } - developers { - developer { - id 'johnmcclean-aol' - name 'John McClean' - email 'john.mcclean@teamaol.com' - } - developer { - id 'kewangie' - name 'Ke Wang' - email 'ke.wang@teamaol.com' - } - developer { - id 'earlzero' - name 'Nikita Sapozhnikov' - email 'nikita.sapozhnikov@teamaol.com' - } - } - - } + } } extraArchive { - sources = true - tests = true - javadoc = true + sources = true + tests = true + javadoc = true } nexus { - sign = true - repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots' } diff --git a/micro-transactions/readme.md b/micro-transactions/readme.md deleted file mode 100644 index b65b64e2e..000000000 --- a/micro-transactions/readme.md +++ /dev/null @@ -1,57 +0,0 @@ -# Transactions Plugin - -[micro-transactions example apps](https://github.com/aol/micro-server/tree/master/micro-transactions/src/test/java/app) - -Handle transactions in a more fluid stream-like (&Java8 Style) fashion - - ```java -Integer result = TransactionFlow.of(transactionTemplate, this::load) - .map(this::save) - .execute(10) - .get(); -``` - -Inject in a preconfigured TransacitonFlow bean - ```java - - private final TransactionFlow flow; - @Autowired - public MyService(TransactionFlow flow){ - this.flow = flow; - } - -``` - -The map and flatMap your heart out. All mapped / flatMapped functions will be executed in the scope of a transaction. - - ```java - -flow.map(this::nextAvailable) - .map(this::updateStatus) - .execute(id); -``` - -TransactionFlow is modelled on the Reader monad (eek!) - which allows for lazy evaluation and dependency injection (hurray!) - -[Dependency injection using the Reader monad in Java 8](https://medium.com/@johnmcclean/dependency-injection-using-the-reader-monad-in-java8-9056d9501c75#.3wxsz9n2z) - -## To use - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-transactions/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-transactions) - -Simply add to the classpath - -Maven - -```xml - - com.aol.microservices - micro-transactions - x.yz - -``` - -Gradle -```gradle - compile 'com.aol.microservices:micro-transactions:x.yz' -``` diff --git a/micro-transactions/src/main/java/com/aol/micro/server/transactions/TransactionsPlugin.java b/micro-transactions/src/main/java/com/aol/micro/server/transactions/TransactionsPlugin.java deleted file mode 100644 index 78c5b8dac..000000000 --- a/micro-transactions/src/main/java/com/aol/micro/server/transactions/TransactionsPlugin.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.aol.micro.server.transactions; - -import com.aol.cyclops.data.collections.extensions.persistent.PSetX; -import com.aol.micro.server.Plugin; - -/** - * - * @author johnmcclean - * - */ -public class TransactionsPlugin implements Plugin{ - - @Override - public PSetX springClasses() { - return PSetX.of(TransactionConfiguration.class); - } - - - -} diff --git a/micro-transactions/src/main/java/com/aol/micro/server/transactions/TransactionConfiguration.java b/micro-transactions/src/main/java/com/oath/micro/server/transactions/TransactionConfiguration.java similarity index 94% rename from micro-transactions/src/main/java/com/aol/micro/server/transactions/TransactionConfiguration.java rename to micro-transactions/src/main/java/com/oath/micro/server/transactions/TransactionConfiguration.java index 677e763d1..fb99e908c 100644 --- a/micro-transactions/src/main/java/com/aol/micro/server/transactions/TransactionConfiguration.java +++ b/micro-transactions/src/main/java/com/oath/micro/server/transactions/TransactionConfiguration.java @@ -1,4 +1,4 @@ -package com.aol.micro.server.transactions; +package com.oath.micro.server.transactions; import java.util.function.Function; diff --git a/micro-transactions/src/main/java/com/aol/micro/server/transactions/TransactionFlow.java b/micro-transactions/src/main/java/com/oath/micro/server/transactions/TransactionFlow.java similarity index 98% rename from micro-transactions/src/main/java/com/aol/micro/server/transactions/TransactionFlow.java rename to micro-transactions/src/main/java/com/oath/micro/server/transactions/TransactionFlow.java index 4991f8737..101330669 100644 --- a/micro-transactions/src/main/java/com/aol/micro/server/transactions/TransactionFlow.java +++ b/micro-transactions/src/main/java/com/oath/micro/server/transactions/TransactionFlow.java @@ -1,14 +1,15 @@ -package com.aol.micro.server.transactions; +package com.oath.micro.server.transactions; import java.util.function.Consumer; import java.util.function.Function; +import cyclops.control.Try; import lombok.AllArgsConstructor; import lombok.experimental.Wither; import org.springframework.transaction.support.TransactionTemplate; -import com.aol.cyclops.control.Try; + /** * Stream-like monadic transaction processing diff --git a/micro-transactions/src/main/java/com/oath/micro/server/transactions/TransactionsPlugin.java b/micro-transactions/src/main/java/com/oath/micro/server/transactions/TransactionsPlugin.java new file mode 100644 index 000000000..f5a8fe138 --- /dev/null +++ b/micro-transactions/src/main/java/com/oath/micro/server/transactions/TransactionsPlugin.java @@ -0,0 +1,22 @@ +package com.oath.micro.server.transactions; + +import com.oath.micro.server.Plugin; +import cyclops.reactive.collections.mutable.SetX; + +import java.util.Set; + +/** + * + * @author johnmcclean + * + */ +public class TransactionsPlugin implements Plugin{ + + @Override + public Set springClasses() { + return SetX.of(TransactionConfiguration.class); + } + + + +} diff --git a/micro-transactions/src/main/resources/META-INF/services/com.aol.micro.server.Plugin b/micro-transactions/src/main/resources/META-INF/services/com.aol.micro.server.Plugin deleted file mode 100644 index 6394d103e..000000000 --- a/micro-transactions/src/main/resources/META-INF/services/com.aol.micro.server.Plugin +++ /dev/null @@ -1 +0,0 @@ -com.aol.micro.server.transactions.TransactionsPlugin \ No newline at end of file diff --git a/micro-transactions/src/main/resources/META-INF/services/com.oath.micro.server.Plugin b/micro-transactions/src/main/resources/META-INF/services/com.oath.micro.server.Plugin new file mode 100644 index 000000000..14d71235a --- /dev/null +++ b/micro-transactions/src/main/resources/META-INF/services/com.oath.micro.server.Plugin @@ -0,0 +1 @@ +com.oath.micro.server.transactions.TransactionsPlugin \ No newline at end of file diff --git a/micro-transactions/src/test/java/app/jdbc/transaction/com/aol/micro/server/JdbcEntity.java b/micro-transactions/src/test/java/app/jdbc/transaction/com/aol/micro/server/JdbcEntity.java deleted file mode 100644 index 6c7663e1f..000000000 --- a/micro-transactions/src/test/java/app/jdbc/transaction/com/aol/micro/server/JdbcEntity.java +++ /dev/null @@ -1,27 +0,0 @@ -package app.jdbc.transaction.com.aol.micro.server; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.experimental.Builder; - - - - -@Setter -@Getter -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class JdbcEntity implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - - private Long id; - private String name; - private String value; - private int version; - - -} diff --git a/micro-transactions/src/test/java/app/jdbc/transaction/com/aol/micro/server/JdbcRunnerTest.java b/micro-transactions/src/test/java/app/jdbc/transaction/com/aol/micro/server/JdbcRunnerTest.java deleted file mode 100644 index 364e0efd3..000000000 --- a/micro-transactions/src/test/java/app/jdbc/transaction/com/aol/micro/server/JdbcRunnerTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package app.jdbc.transaction.com.aol.micro.server; - - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import app.jdbc.transaction.com.aol.micro.server.JdbcEntity; - -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; -import com.aol.micro.server.testing.RestAgent; - -@Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", - "db.connection.url","jdbc:hsqldb:mem:aname", - "db.connection.username", "sa", - }) -public class JdbcRunnerTest { - - private final AsyncRestClient listClient = new AsyncRestClient(1000,1000).withResponse(JdbcEntity.class); - - RestAgent rest = new RestAgent(); - - MicroserverApp server; - - @Before - public void startServer(){ - - - server = new MicroserverApp(()->"jdbc-app"); - server.start(); - rest.get("http://localhost:8080/jdbc-app/persistence/gen"); - - } - - @After - public void stopServer(){ - server.stop(); - } - - @Test - public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ - - - - assertThat(rest.get("http://localhost:8080/jdbc-app/persistence/create"),is("ok")); - assertThat(listClient.get("http://localhost:8080/jdbc-app/persistence/get").get(),is(JdbcEntity.class)); - - - } - - - -} diff --git a/micro-transactions/src/test/java/app/jdbc/transaction/com/aol/micro/server/PersistentResource.java b/micro-transactions/src/test/java/app/jdbc/transaction/com/aol/micro/server/PersistentResource.java deleted file mode 100644 index 1f6b9807d..000000000 --- a/micro-transactions/src/test/java/app/jdbc/transaction/com/aol/micro/server/PersistentResource.java +++ /dev/null @@ -1,56 +0,0 @@ -package app.jdbc.transaction.com.aol.micro.server; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.BeanPropertyRowMapper; - -import app.jdbc.transaction.com.aol.micro.server.JdbcEntity; - -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.spring.datasource.jdbc.SQL; -import com.aol.micro.server.transactions.TransactionFlow; - -@Rest -@Path("/persistence") -public class PersistentResource { - - private final SQL dao; - private final TransactionFlow flow; - - @Autowired - public PersistentResource(TransactionFlow flow,SQL dao) { - - this.dao = dao; - this.flow=flow; - } - @GET - @Produces("text/plain") - @Path("/gen") - public String gen() { - dao.getJdbc().execute("create table t_jdbc(id bigint,name varchar(255),value varchar(255),version int);"); - - return "ok"; - } - @GET - @Produces("text/plain") - @Path("/create") - public String createEntity() { - - flow.map(name->dao.getJdbc().update("insert into t_jdbc VALUES (1,'"+name+"+','world',1)")) - .execute("hello"); - - - return "ok"; - } - - @GET - @Produces("application/json") - @Path("/get") - public JdbcEntity get() { - return dao.getJdbc(). queryForObject("select * from t_jdbc", new BeanPropertyRowMapper(JdbcEntity.class)); - } - -} \ No newline at end of file diff --git a/micro-transactions/src/test/java/app/jdbc/transaction/com/oath/micro/server/JdbcEntity.java b/micro-transactions/src/test/java/app/jdbc/transaction/com/oath/micro/server/JdbcEntity.java new file mode 100644 index 000000000..6760e7a2b --- /dev/null +++ b/micro-transactions/src/test/java/app/jdbc/transaction/com/oath/micro/server/JdbcEntity.java @@ -0,0 +1,27 @@ +package app.jdbc.transaction.com.oath.micro.server; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.Builder; + + + + +@Setter +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class JdbcEntity implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + private String name; + private String value; + private int version; + + +} diff --git a/micro-transactions/src/test/java/app/jdbc/transaction/com/oath/micro/server/JdbcRunnerTest.java b/micro-transactions/src/test/java/app/jdbc/transaction/com/oath/micro/server/JdbcRunnerTest.java new file mode 100644 index 000000000..9be773144 --- /dev/null +++ b/micro-transactions/src/test/java/app/jdbc/transaction/com/oath/micro/server/JdbcRunnerTest.java @@ -0,0 +1,58 @@ +package app.jdbc.transaction.com.oath.micro.server; + + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.testing.RestAgent; + +@Microserver(properties={"db.connection.driver","org.hsqldb.jdbcDriver", + "db.connection.url","jdbc:hsqldb:mem:aname", + "db.connection.username", "sa", + }) +public class JdbcRunnerTest { + + private final AsyncRestClient listClient = new AsyncRestClient(1000,1000).withResponse(JdbcEntity.class); + + RestAgent rest = new RestAgent(); + + MicroserverApp server; + + @Before + public void startServer(){ + + + server = new MicroserverApp(()->"jdbc-app"); + server.start(); + rest.get("http://localhost:8080/jdbc-app/persistence/gen"); + + } + + @After + public void stopServer(){ + server.stop(); + } + + @Test + public void runAppAndBasicTest() throws InterruptedException, ExecutionException{ + + + + assertThat(rest.get("http://localhost:8080/jdbc-app/persistence/create"),is("ok")); + assertThat(listClient.get("http://localhost:8080/jdbc-app/persistence/get").get(),is(JdbcEntity.class)); + + + } + + + +} diff --git a/micro-transactions/src/test/java/app/jdbc/transaction/com/oath/micro/server/PersistentResource.java b/micro-transactions/src/test/java/app/jdbc/transaction/com/oath/micro/server/PersistentResource.java new file mode 100644 index 000000000..41ac2cbad --- /dev/null +++ b/micro-transactions/src/test/java/app/jdbc/transaction/com/oath/micro/server/PersistentResource.java @@ -0,0 +1,54 @@ +package app.jdbc.transaction.com.oath.micro.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.BeanPropertyRowMapper; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.spring.datasource.jdbc.SQL; +import com.oath.micro.server.transactions.TransactionFlow; + +@Rest +@Path("/persistence") +public class PersistentResource { + + private final SQL dao; + private final TransactionFlow flow; + + @Autowired + public PersistentResource(TransactionFlow flow,SQL dao) { + + this.dao = dao; + this.flow=flow; + } + @GET + @Produces("text/plain") + @Path("/gen") + public String gen() { + dao.getJdbc().execute("create table t_jdbc(id bigint,name varchar(255),value varchar(255),version int);"); + + return "ok"; + } + @GET + @Produces("text/plain") + @Path("/create") + public String createEntity() { + + flow.map(name->dao.getJdbc().update("insert into t_jdbc VALUES (1,'"+name+"+','world',1)")) + .execute("hello"); + + + return "ok"; + } + + @GET + @Produces("application/json") + @Path("/get") + public JdbcEntity get() { + return dao.getJdbc(). queryForObject("select * from t_jdbc", new BeanPropertyRowMapper(JdbcEntity.class)); + } + +} \ No newline at end of file diff --git a/micro-transactions/src/test/java/com/aol/micro/server/testing/RestAgent.java b/micro-transactions/src/test/java/com/aol/micro/server/testing/RestAgent.java deleted file mode 100644 index ce204f810..000000000 --- a/micro-transactions/src/test/java/com/aol/micro/server/testing/RestAgent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.aol.micro.server.testing; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation.Builder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; - -import com.aol.micro.server.rest.jackson.JacksonUtil; - -public class RestAgent { - - - public String getJson(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.get(String.class); - - } - - public String get(String url) { - - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.TEXT_PLAIN); - - return request.get(String.class); - - } - - public T post(String url, Object payload,Class type) { - Client client = ClientBuilder.newClient(); - - WebTarget resource = client.target(url); - - Builder request = resource.request(); - request.accept(MediaType.APPLICATION_JSON); - - return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); - } - - -} diff --git a/micro-transactions/src/test/java/com/aol/micro/server/transactions/TransactionFlowTest.java b/micro-transactions/src/test/java/com/aol/micro/server/transactions/TransactionFlowTest.java deleted file mode 100644 index 457dba33e..000000000 --- a/micro-transactions/src/test/java/com/aol/micro/server/transactions/TransactionFlowTest.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.aol.micro.server.transactions; - -import org.junit.Test; -import org.springframework.transaction.TransactionException; -import org.springframework.transaction.support.TransactionTemplate; -import org.springframework.transaction.support.TransactionCallback; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -public class TransactionFlowTest { - TransactionTemplate transactionTemplate = new TransactionTemplate(){ - public T execute(TransactionCallback action) throws TransactionException { - return action.doInTransaction(null); - } - }; - TransactionTemplate transactionTemplate2 = new TransactionTemplate(){ - public T execute(TransactionCallback action) throws TransactionException { - return action.doInTransaction(null); - } - }; - @Test - public void test() { - - - - Integer result = TransactionFlow.of(transactionTemplate) - .map(this::load) - .map(this::save) - .execute(10) - .get(); - - assertThat(result,equalTo(-1)); - } - - @Test - public void flatMapTest(){ - String result = TransactionFlow.of(transactionTemplate, this::load) - .flatMap(this::newTransaction) - .execute(10) - .get(); - - } - - @Test - public void errorHandlingGeneral() { - - - - Throwable result = TransactionFlow.of(transactionTemplate) - .map(this::load) - .map(this::error) - .execute(10) - .toFailedOptional() - .get(); - - - assertThat(result,instanceOf(RuntimeException.class)); - } - @Test(expected=RuntimeException.class) - public void errorHandlingSpecific() { - - - - Throwable result = TransactionFlow.of(transactionTemplate) - .map(this::load) - .map(this::error2) - .execute(10,IllegalArgumentException.class) - .toFailedOptional() - .get(); - - - fail("exception expected!"); - } - @Test - public void errorHandlingSpecificCaught() { - - - - NullPointerException result = TransactionFlow.of(transactionTemplate) - .map(this::load) - .map(this::error2) - .execute(10,NullPointerException.class) - .toFailedOptional() - .get(); - - - assertThat(result,instanceOf(NullPointerException.class)); - } - public TransactionFlow newTransaction(String input){ - return TransactionFlow.of(transactionTemplate2, in -> input+":"+in); - } - - public String load(Integer input){ - return "data"; - } - public Integer save(String input){ - return -1; - } - public Integer error(String input){ - throw new RuntimeException(); - } - public Integer error2(String input){ - throw new NullPointerException(); - } - -} diff --git a/micro-transactions/src/test/java/com/oath/micro/server/testing/RestAgent.java b/micro-transactions/src/test/java/com/oath/micro/server/testing/RestAgent.java new file mode 100644 index 000000000..b2b86303e --- /dev/null +++ b/micro-transactions/src/test/java/com/oath/micro/server/testing/RestAgent.java @@ -0,0 +1,53 @@ +package com.oath.micro.server.testing; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.oath.micro.server.rest.jackson.JacksonUtil; + +public class RestAgent { + + + public String getJson(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.get(String.class); + + } + + public String get(String url) { + + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.TEXT_PLAIN); + + return request.get(String.class); + + } + + public T post(String url, Object payload,Class type) { + Client client = ClientBuilder.newClient(); + + WebTarget resource = client.target(url); + + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + + return request.post(Entity.entity(JacksonUtil.serializeToJson(payload),MediaType.APPLICATION_JSON), type); + } + + +} diff --git a/micro-transactions/src/test/java/com/oath/micro/server/transactions/TransactionFlowTest.java b/micro-transactions/src/test/java/com/oath/micro/server/transactions/TransactionFlowTest.java new file mode 100644 index 000000000..7afb5d141 --- /dev/null +++ b/micro-transactions/src/test/java/com/oath/micro/server/transactions/TransactionFlowTest.java @@ -0,0 +1,112 @@ +package com.oath.micro.server.transactions; + +import org.junit.Test; +import org.springframework.transaction.TransactionException; +import org.springframework.transaction.support.TransactionTemplate; +import org.springframework.transaction.support.TransactionCallback; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +public class TransactionFlowTest { + TransactionTemplate transactionTemplate = new TransactionTemplate() { + public T execute(TransactionCallback action) throws TransactionException { + return action.doInTransaction(null); + } + }; + TransactionTemplate transactionTemplate2 = new TransactionTemplate() { + public T execute(TransactionCallback action) throws TransactionException { + return action.doInTransaction(null); + } + }; + + @Test + public void test() { + + + Integer result = TransactionFlow.of(transactionTemplate) + .map(this::load) + .map(this::save) + .execute(10) + .orElse(-1); + + assertThat(result, equalTo(-1)); + } + + @Test + public void flatMapTest() { + String result = TransactionFlow.of(transactionTemplate, this::load) + .flatMap(this::newTransaction) + .execute(10) + .orElse(""); + + assertThat(result, equalTo("data:10")); + + } + + @Test + public void errorHandlingGeneral() { + + + Throwable result = TransactionFlow.of(transactionTemplate) + .map(this::load) + .map(this::error) + .execute(10) + .toFailedOption() + .orElse(null); + + + assertThat(result, instanceOf(RuntimeException.class)); + } + + @Test(expected = RuntimeException.class) + public void errorHandlingSpecific() { + + + Throwable result = TransactionFlow.of(transactionTemplate) + .map(this::load) + .map(this::error2) + .execute(10, IllegalArgumentException.class) + .toFailedOption() + .orElse(null); + + + fail("exception expected!"); + } + + @Test + public void errorHandlingSpecificCaught() { + + + NullPointerException result = TransactionFlow.of(transactionTemplate) + .map(this::load) + .map(this::error2) + .execute(10, NullPointerException.class) + .toFailedOption() + .orElse(null); + + + assertThat(result, instanceOf(NullPointerException.class)); + } + + public TransactionFlow newTransaction(String input) { + return TransactionFlow.of(transactionTemplate2, in -> input + ":" + in); + } + + public String load(Integer input) { + return "data"; + } + + public Integer save(String input) { + return -1; + } + + public Integer error(String input) { + throw new RuntimeException(); + } + + public Integer error2(String input) { + throw new NullPointerException(); + } + +} diff --git a/micro-tutorial/build.gradle b/micro-tutorial/build.gradle index 931f96660..79560da26 100644 --- a/micro-tutorial/build.gradle +++ b/micro-tutorial/build.gradle @@ -1,13 +1,14 @@ description = 'micro-tutorial' + dependencies { - compile project(':micro-hibernate') - compile project(':micro-swagger') - compile project(':micro-metrics') - compile project(':micro-guava') - compile project(':micro-events') - compile project(':micro-client') - compile project(':micro-ip-tracker') - compile project(':micro-grizzly') - compile project(':micro-jersey') - + compile project(':micro-hibernate') + compile project(':micro-swagger') + compile project(':micro-metrics') + compile project(':micro-guava') + compile project(':micro-events') + compile project(':micro-client') + compile project(':micro-ip-tracker') + compile project(':micro-grizzly') + compile project(':micro-jersey') + compile "com.oath.cyclops:cyclops-futurestream:$cyclopsVersion" } diff --git a/micro-tutorial/src/main/java/app1/simple/Job.java b/micro-tutorial/src/main/java/app1/simple/Job.java index 9f4c0b05f..5fc7efbc3 100644 --- a/micro-tutorial/src/main/java/app1/simple/Job.java +++ b/micro-tutorial/src/main/java/app1/simple/Job.java @@ -1,12 +1,11 @@ package app1.simple; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import com.aol.micro.server.events.ScheduledJob; -import com.aol.micro.server.events.SystemData; -import com.aol.micro.server.utility.HashMapBuilder; +import com.oath.micro.server.events.ScheduledJob; +import com.oath.micro.server.events.SystemData; +import com.oath.micro.server.utility.HashMapBuilder; @Component public class Job implements ScheduledJob{ diff --git a/micro-tutorial/src/main/java/app1/simple/MicroserverTutorial.java b/micro-tutorial/src/main/java/app1/simple/MicroserverTutorial.java index 6561a552b..31aa3ed7d 100644 --- a/micro-tutorial/src/main/java/app1/simple/MicroserverTutorial.java +++ b/micro-tutorial/src/main/java/app1/simple/MicroserverTutorial.java @@ -1,7 +1,7 @@ package app1.simple; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.config.Microserver; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.config.Microserver; @Microserver(entityScan = "app1.simple", propertiesName="tutorial.properties") public class MicroserverTutorial { diff --git a/micro-tutorial/src/main/java/app1/simple/MyRestEndPoint.java b/micro-tutorial/src/main/java/app1/simple/MyRestEndPoint.java index 47f77ddd6..29b74b3e5 100644 --- a/micro-tutorial/src/main/java/app1/simple/MyRestEndPoint.java +++ b/micro-tutorial/src/main/java/app1/simple/MyRestEndPoint.java @@ -10,16 +10,17 @@ import javax.ws.rs.container.AsyncResponse; import javax.ws.rs.container.Suspended; +import cyclops.futurestream.LazyReact; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.jdbc.core.BeanPropertyRowMapper; -import com.aol.cyclops.control.LazyReact; -import com.aol.micro.server.auto.discovery.Rest; -import com.aol.micro.server.events.RequestEvents; -import com.aol.micro.server.ip.tracker.QueryIPRetriever; -import com.aol.micro.server.rest.jackson.JacksonUtil; -import com.aol.micro.server.spring.datasource.jdbc.SQL; + +import com.oath.micro.server.auto.discovery.Rest; +import com.oath.micro.server.events.RequestEvents; +import com.oath.micro.server.ip.tracker.QueryIPRetriever; +import com.oath.micro.server.rest.jackson.JacksonUtil; +import com.oath.micro.server.spring.datasource.jdbc.SQL; import com.google.common.collect.ImmutableList; import com.google.common.eventbus.EventBus; import com.wordnik.swagger.annotations.Api; @@ -47,7 +48,7 @@ public MyRestEndPoint(@Qualifier("microserverEventBus")final EventBus bus,final @Path("/hello") @ApiOperation(value = "Hello world", response = String.class) public String hello(){ - long correlationId = correlationProvider.incrementAndGet(); + String correlationId = String.valueOf(correlationProvider.incrementAndGet()); bus.post(RequestEvents.start(QueryIPRetriever.getIpAddress(),correlationId)); try{ return "world"; diff --git a/micro-tutorial/src/test/java/app1/simple/SimpleAppTest.java b/micro-tutorial/src/test/java/app1/simple/SimpleAppTest.java index d46030b07..5db67e1ba 100644 --- a/micro-tutorial/src/test/java/app1/simple/SimpleAppTest.java +++ b/micro-tutorial/src/test/java/app1/simple/SimpleAppTest.java @@ -8,8 +8,8 @@ import org.junit.Ignore; import org.junit.Test; -import com.aol.micro.server.MicroserverApp; -import com.aol.micro.server.rest.client.nio.AsyncRestClient; +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.rest.client.nio.AsyncRestClient; public class SimpleAppTest { diff --git a/micro-tutorial/src/test/java/app1/simple/SingleClassApp.java b/micro-tutorial/src/test/java/app1/simple/SingleClassApp.java new file mode 100644 index 000000000..4825dba97 --- /dev/null +++ b/micro-tutorial/src/test/java/app1/simple/SingleClassApp.java @@ -0,0 +1,24 @@ +package app1.simple; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import com.oath.micro.server.MicroserverApp; +import com.oath.micro.server.auto.discovery.Rest; + +@Rest +@Path("/status") +public class SingleClassApp { + + public static void main(String[] args){ + new MicroserverApp(()-> "simple-app").run(); + } + @GET + @Produces("text/plain") + @Path("/ping") + public String ping() { + return "ok"; + } + +} \ No newline at end of file diff --git a/readme.md b/readme.md deleted file mode 100644 index 618d9a40a..000000000 --- a/readme.md +++ /dev/null @@ -1,333 +0,0 @@ - -#Microserver - -[![Join the chat at https://gitter.im/aol/micro-server](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/aol/micro-server?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -A convenient modular engine for Microservices. Microserver plugins offer seamless integration with Spring (core), Jersey, Guava, Tomcat, Grizzly, reactive programming, Hibernate (& Spring Data), Spring Boot, Codahale Metrics, Swagger and more to come! - -* [Microserver screencast : getting started with plugins](https://www.youtube.com/watch?v=sYn2cVTkfcM) - -![screen shot 2016-05-06 at 12 30 26 pm](https://cloud.githubusercontent.com/assets/9964792/15588807/8da91440-2387-11e6-979b-f24d456541f5.png) - - - -## Quick start - -Install Microserver with Grizzly, Jackson and Jersey (Gradle config below) -```groovy - compile group: 'com.aol.microservices', name:'micro-grizzly-with-jersey', version:'x.yz' -``` -Install Microserver with Tomcat, Jackson and Jersey (Gradle config below) - ```groovy - compile group: 'com.aol.microservices', name:'micro-tomcat-with-jersey', version:'x.yz' - ``` -Create and run a simple app - ```java - @Rest - @Path("/test") - public class SimpleApp { - - public static void main(String[] args){ - new MicroserverApp(()->"test-app").run(); - } - @GET - public String myEndPoint(){ - return "hello world!"; - } - } -``` - -Browse to *http://localhost:8080/test-app/test* - -See the response *hello world!* - -Add plugins by adding them to your build file - rerun the app to get new end points, Spring beans and more! - -# Why Microserver? - -Microserver is a plugin engine for building Spring and Spring Boot based microservices. Microserver supports pure microservice and micro-monolith development styles. The micro-monolith style involves packaging multiple services into a single deployment - offering developers the productivity of microservice development without the operational risk. This can help teams adopt a Microservices architecture on projects that are currently monoliths. - -Microserver plugins are orthogonal to Microservices. They solve a common problem in Microservice development where by services are broken up and deployed separately but code remains entangled in a monolithic common library. By making use of a plugin system that follows the same modular archictectural principals as microservice development, teams can keep cross-service concerns and infrastructure in properly size, coherent and cohesive plugin modules. - -# Tutorial and overview - -[Tutorial](https://github.com/aol/micro-server/wiki/Getting-started-:-Tutorial) - -[Tutoiral code](https://github.com/aol/micro-server/tree/master/micro-tutorial) - -## Note on Fat Jars -Microserver (& Cyclops) have a plugin architecture and make use of the Java Service Laoder mechanism. Make sure your Fat Jar implementation is configured to aggreagate services. With the Gradle Shadow Jar you do this with - ```groovy - shadowJar { - mergeServiceFiles() - } - ``` - - -###Quick start youtube video -[![Getting started video](https://cloud.githubusercontent.com/assets/9964792/6361863/9991c50c-bc7e-11e4-8d28-746b0b87b1da.png)](https://www.youtube.com/watch?v=McXy9oGRpfA&feature=youtu.be) - - -Note the main launch class has been changed from MicroServerStartup to MicroserverApp - -## Blurb - -Microserver is a zero configuration, standards based, battle hardened library to run Java Rest Microservices via a standard Java main class. It has been used in production in AOL since July 2014. - - -## Get Microserver - - -![Build health](https://travis-ci.org/aol/micro-server.svg) - -* micro-grizzly-with-jersey -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-grizzly-with-jersey/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-grizzly-with-jersey) -* micro-tomcat-with-jersey -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-tomcat-with-jersey/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-tomcat-with-jersey) -* micro-core -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-core) -* micro-boot : Microserver driving Spring Boot -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-boot/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-boot) -* micro-spring-boot : Spring Boot driving Microserver -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-spring-boot/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.aol.microservices/micro-spring-boot) - - -##Info - -[wiki](https://github.com/aol/micro-server/wiki) - -[Google Group](https://groups.google.com/forum/#!forum/micro-server) - -[Example Apps : Microserver Core with Grizzly and Jersey](https://github.com/aol/micro-server/tree/master/micro-grizzly/src/test/java/app) - -[Example Apps : Microserver Boot](https://github.com/aol/micro-server/tree/master/micro-boot/src/test/java/app) - -[Java Doc : Microserver Core](http://www.javadoc.io/doc/com.aol.microservices/micro-core/0.62) - -[Java Doc : Microserver Boot](http://www.javadoc.io/doc/com.aol.microservices/micro-core/0.62) - - - -### Maven dependency - -Microserver Grizzly with Jersey - ```xml - - com.aol.microservices - micro-grizzly-with-jersey - x.yz - -``` -Microserver Spring Boot - ```xml - - com.aol.microservices - micro-spring-boot - x.yz - - ``` - - -### Gradle dependency - -Microserver core - ```groovy - compile group: 'com.aol.microservices', name:'micro-core', version:'x.yz' - ``` -Microserver Spring Boot - ```groovy - compile group: 'com.aol.microservices', name:'micro-spring-boot', version:'x.yz' - ``` -##Tech Stack - -Microserver core is a lightweight server configuration engine built using Spring, Cyclops and Jackson. - - - -##Zero Configuration - -No directory structure is imposed by the server and no XML is required. There is no framework config. Just a jar file and your application. You can of course, configure your application without limit. - -Example working application :- - -###The main class :- - -```java - public class AppRunnerTest { - - - public static void main(String[] args) throws InterruptedException { - new MicroserverApp(() -> "test-app").run(); - } - - } - ``` - -This will deploy a REST server on port 8080 (configurable by test-app.port in application.properties), it will also automagically capture any Rest end points (Spring & Jersey annotations) that implement the tag interface RestResource (see below for an example). - -###A rest end point - - ```java - @Rest - @Path("/status") - public class StatusResource { - - @GET - @Produces("text/plain") - @Path("/ping") - public String ping() { - return "ok"; - } - - } - ``` -### Configuration Options - -If you find you need configuration options for your application you have two options. - -1. Override some of the available options on the Module interface (ConfigurableModule provides a builder mechanism for this) -2. [Implement a custom plugin](https://github.com/aol/micro-server/wiki/Creating-a-Microserver-plugin) (the cleanest option, which also promotes reuse across services). - -### Application configuration (for Grizzly with Jersey) - -The core of Microserver is a Spring 4.x Dependency Injection container which is used to store all the main classes of your Microservice (s). The Spring Dependency Injection container can be configured by the @Microservice Annotation on your main class, or by the Config object (optionally passed as a parameter to startup). - -### Micro-monolith Architectural Overview - -Each Microservice is a Jersey REST Application, these can deployed independently as pure Microservices or together as a micro-monolith. Multiple Microservices can run on the same server, by adding them to the classpath at runtime. They share a common Spring Dependency Injection container (as they are smaller services, we feel it makes sense to share resources such as ThreadPools, Datasources etc), but act as totally separate Rest applications. - -When creating embedded Microservices (multiple services colocated on the same JVM and Spring container), the development project should be independent, but the colocated instances should be tested as they will be depolyed in production. There will be more info to follow on the wiki, on how and why we have implemented and scaled this pattern (the goal is to achieve both the benefits of a full Microservice architecture, but minimise the costs as articulated by Robert (Uncle Bob) C. Martin and others - e.g. [here: Microservices and Jars](http://blog.cleancoder.com/uncle-bob/2014/09/19/MicroServicesAndJars.html) . - -Jersey REST Applications are configured by the Module interface (at least one of which must be specified on startup). - -![high level architecture](https://cloud.githubusercontent.com/assets/9964792/6375067/a6e4f65a-bd0c-11e4-85dc-82ae0d95d44b.png) - - -####Rest configuration - -The configuration of your Rest end points can be managed via the Module interface. The Module interface has a number of Java 8 default methods and a single abstract method (getContext). It behaves as a functional interface, and can be defined by a lambda expression. When used in this way the lambda represents the context the Microserver will create Rest end points on. - -e.g. - - ```java - new MicroserverApp(() -> "context").start(); - ``` - -() -> "context" is a Module! - - -####Configurable Options - -Module provides the following default methods, that clients can override - - ```java - default Map getPropertyOverrides(){ - return Maps.newHashMap(); - } - default Set getSpringConfigurationClasses(){ - return Sets.newHashSet(Classes.CORE_CLASSES.getClasses()); - } - default List getRestResourceClasses() { - return Arrays.asList(RestResource.class); - } - default List getRestAnnotationClasses() { - return Arrays.asList(Rest.class); - } - - default List getDefaultJaxRsPackages(){ - return Arrays.asList("com.wordnik.swagger.sample.resource", - "com.wordnik.swagger.sample.util" ); - } - - default List getDefaultResources(){ - return Arrays.asList(JacksonFeature.class, - //SWAGGER CLASSES - ApiListingResourceJSON.class,JerseyApiDeclarationProvider.class, - JerseyResourceListingProvider.class); - } - - default List getListeners(ServerData data){ - return ImmutableList.of(new ContextLoaderListener(data - .getRootContext()), - new JerseySpringIntegrationContextListener(data), - new SwaggerInitializer(data)); - } - default Map getFilters(ServerData data) { - return ImmutableMap.of("/*",new QueryIPRetriever()); - } - default Map getServlets(ServerData data) { - return ImmutableMap.of(); - } - - default String getJaxWsRsApplication(){ - return JerseyRestApplication.class.getCanonicalName(); - } - default String getProviders(){ - return "com.aol.micro.server.rest.providers"; - } - ``` -RestResource class defines the tag interface used to identify Rest end points for this module. - -Filters provides a map of Servlet filters and the paths to which they should be applied - -Providers allows client code to change the Jersey Providers packages - -JaxWsRsApplication allows client code to completely override the Microserver jax.ws.rs.Application - -####Property file configuration - -Microserver supports auto-discovery of application.properties. Microserver will assume a default file name of 'application.properties'. Microserver will check for a properties in the following order - -1. System property 'application.property.file' and if present will load the property file from disk using that. - -2. Otherwise Microserver will look for a System Property 'application.env' and will load the application property file from the classpath using the resource name 'application-${application.env}.properties. - -3. Alternatively Microserver will load application.properties directly from the classpath. - -4. If still not found Microserver will load application.properties from disk in the current directory - -The default file name application.properties can be configured by exception (use PropertyFileConfig.setApplicationPropertyFileName(String filename). - -Microserver application properties loading is configured by the class PropertyFileConfig. You can replace this with your own Spring configuration file to load property files by a different set of rules (by passing in your class to the constructor of Microserver). - -##Embed and colocate Microservices - -Microserver supports the embedding of multiple microservices within a single Microserver, this is not the default mode of operation and involves a little more work to setup. All Microservices will share a single Spring context, so some care needs to be taken when authoring such Microservices to avoid conflicts. This does mean that they can share resources (such as database connections) where it makes sense to do so. - -Embedded microservices should be collated at '''runtime only'''. There should be no compile time dependency between embedded microservices (otherwise you are not building microservices but a monolithc application). - -Embedding microservices is an optimisation that allows better performance, enhanced robustness and reliability and easier management of microservices - while still maintaining the advantages of horizontal scalability offered by the microservices approach. - -###Embeded Microservices example - -This example will start two different Rest end points - one on context "test-app" and another on context "alternative-app". -"test-app" will automagically wire in any Jersey end points that implement TestAppRestResource. -"alternative-app" will automagically wire in any Jersey end points that implement AltAppRestResource. - ```java - @Microserver - public class EmbeddedAppRunnerTest { - - public static void main(String[] args) throws InterruptedException { - new MicroserverApp(EmbeddedAppRunnerTest.class, - new EmbeddedModule(TestAppRestResource.class,"test-app"), - new EmbeddedModule(AltAppRestResource.class,"alternative-app")).start(); - - - - } - } - - ``` - - -##Building a 'fat' Jar - -We recommend the Gradle plugin Shadow Jar. For Gradle 2.0 simply define it in your plugins section -> - ```groovy -plugins { - id 'java' // or 'groovy' Must be explicitly applied - id 'com.github.johnrengelman.shadow' version '1.2.0' -} - ``` -Maven users can use Shade plugin or equivalent (Maven assembly plugin). - diff --git a/settings.gradle b/settings.gradle index 1d7570381..8be68d73c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,5 @@ -rootProject.name = 'com.aol.microservices' +rootProject.name = 'com.oath.microservices' +include ':micro-manifest-comparator' include ':micro-core' include ':micro-grizzly' include ':micro-jersey' @@ -19,7 +20,6 @@ include ':micro-application-register' include ':micro-mysql' include ':micro-machine-stats' include ':micro-couchbase' -include ':micro-javaslang' include ':micro-transactions' include ':micro-curator' include ':micro-general-exception-mapper' @@ -32,3 +32,12 @@ include ':micro-log4j' include ':micro-logback' include ':micro-s3' include ':micro-tutorial' +include ':micro-dist-lock' +include ':micro-async-data-loader' +include ':micro-async-data-writer' +include ':micro-error-codes' +include ':micro-event-metrics' +include ':micro-metrics-datadog' +include ':micro-log-streamer' +include ':micro-jmx-metrics' +include ':micro-memcached'