Back merged from offical repo
This commit is contained in:
11
.github/workflows/ci.yml
vendored
11
.github/workflows/ci.yml
vendored
@@ -33,3 +33,14 @@ jobs:
|
||||
AWS_REGION: us-east-1
|
||||
run: |
|
||||
chmod 755 build-all.sh && ./build-all.sh $MODULE
|
||||
|
||||
- name: "Zip build reports"
|
||||
if: failure()
|
||||
run: zip -r reports.zip **/**/build/reports
|
||||
|
||||
- uses: actions/upload-artifact@v1
|
||||
name: "Upload build reports"
|
||||
if: failure()
|
||||
with:
|
||||
name: reports
|
||||
path: reports.zip
|
||||
|
||||
14
aws/aws-hello-world/README.md
Normal file
14
aws/aws-hello-world/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# AWS Hello World
|
||||
|
||||
A simple Spring Boot application you can use to test deployments to AWS (or any other cloud provider, for that matter).
|
||||
|
||||
This application is also available as a Docker image on Docker Hub: [https://hub.docker.com/r/reflectoring/aws-hello-world](https://hub.docker.com/r/reflectoring/aws-hello-world).
|
||||
|
||||
## Blog posts
|
||||
|
||||
Blog posts about this topic:
|
||||
|
||||
* [The AWS Journey Part 1: Deploying Your First Docker Image](https://reflectoring.io/aws-deploy-docker-image-via-web-console/)
|
||||
* [The AWS Journey Part 2: Deploying a Docker Image with AWS CloudFormation](https://reflectoring.io/aws-cloudformation-deploy-docker-image/)
|
||||
* [The AWS Journey Part 3: Connecting a Spring Boot Application to an RDS Instance with CloudFormation](https://reflectoring.io/aws-cloudformation-rds/)
|
||||
* [The AWS Journey Part 4: Zero-Downtime Deployment with CloudFormation and ECS](https://reflectoring.io/aws-cloudformation-ecs-deployment/)
|
||||
@@ -23,3 +23,18 @@ Use the image instead of your real application to test AWS CloudFormation stacks
|
||||
```
|
||||
5. If the Spring Boot application can connect to the database, it will start up sucessfully and serve a message on the endpoint `/hello`.
|
||||
|
||||
# AWS Hello World
|
||||
|
||||
A simple Spring Boot application you can use to test deployments to AWS (or any other cloud provider, for that matter).
|
||||
|
||||
This application is also available as a Docker image on Docker Hub: [https://hub.docker.com/r/reflectoring/aws-hello-world](https://hub.docker.com/r/reflectoring/aws-hello-world).
|
||||
|
||||
## Blog posts
|
||||
|
||||
Blog posts about this topic:
|
||||
|
||||
* [The AWS Journey Part 1: Deploying Your First Docker Image](https://reflectoring.io/aws-deploy-docker-image-via-web-console/)
|
||||
* [The AWS Journey Part 2: Deploying a Docker Image with AWS CloudFormation](https://reflectoring.io/aws-cloudformation-deploy-docker-image/)
|
||||
* [The AWS Journey Part 3: Connecting a Spring Boot Application to an RDS Instance with CloudFormation](https://reflectoring.io/aws-cloudformation-rds/)
|
||||
* [The AWS Journey Part 4: Zero-Downtime Deployment with CloudFormation and ECS](https://reflectoring.io/aws-cloudformation-ecs-deployment/)
|
||||
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
|
||||

|
||||
|
||||
# Companion Blog Post
|
||||
## Blog posts
|
||||
|
||||
[The AWS Journey Part 2: Deploying a Docker image from the Command Line with CloudFormation](https://reflectoring.io/aws-cloudformation-deploy-docker-image/)
|
||||
Blog posts about this topic:
|
||||
|
||||
* [The AWS Journey Part 1: Deploying Your First Docker Image](https://reflectoring.io/aws-deploy-docker-image-via-web-console/)
|
||||
* [The AWS Journey Part 2: Deploying a Docker Image with AWS CloudFormation](https://reflectoring.io/aws-cloudformation-deploy-docker-image/)
|
||||
* [The AWS Journey Part 3: Connecting a Spring Boot Application to an RDS Instance with CloudFormation](https://reflectoring.io/aws-cloudformation-rds/)
|
||||
* [The AWS Journey Part 4: Zero-Downtime Deployment with CloudFormation and ECS](https://reflectoring.io/aws-cloudformation-ecs-deployment/)
|
||||
|
||||
|
||||
@@ -2,7 +2,14 @@
|
||||
|
||||

|
||||
|
||||
# Companion Blog Post
|
||||
## Blog posts
|
||||
|
||||
Blog posts about this topic:
|
||||
|
||||
* [The AWS Journey Part 1: Deploying Your First Docker Image](https://reflectoring.io/aws-deploy-docker-image-via-web-console/)
|
||||
* [The AWS Journey Part 2: Deploying a Docker Image with AWS CloudFormation](https://reflectoring.io/aws-cloudformation-deploy-docker-image/)
|
||||
* [The AWS Journey Part 3: Connecting a Spring Boot Application to an RDS Instance with CloudFormation](https://reflectoring.io/aws-cloudformation-rds/)
|
||||
* [The AWS Journey Part 4: Zero-Downtime Deployment with CloudFormation and ECS](https://reflectoring.io/aws-cloudformation-ecs-deployment/)
|
||||
|
||||
|
||||
[The AWS Journey Part 4: Zero-Downtime Deployment with CloudFormation and ECS](https://reflectoring.io/aws-cloudformation-ecs-deployment/)
|
||||
|
||||
|
||||
10
aws/localstack/README.md
Normal file
10
aws/localstack/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Localstack
|
||||
|
||||
Example code to test against AWS services locally using Localstack.
|
||||
|
||||
## Blog posts
|
||||
|
||||
Blog posts about this topic:
|
||||
|
||||
* [Local Development with AWS on LocalStack](https://reflectoring.io/aws-localstack/)
|
||||
|
||||
@@ -87,11 +87,12 @@ then
|
||||
# ADD NEW MODULES HERE
|
||||
# (add new modules above the rest so you get quicker feedback if it fails)
|
||||
|
||||
build_gradle_module "spring-boot/cache"
|
||||
build_gradle_module "spring-boot/bean-lifecycle"
|
||||
build_gradle_module "spring-boot/request-response/client"
|
||||
build_gradle_module "spring-boot/request-response/server"
|
||||
build_gradle_module "spring-boot/hazelcast/hazelcast-embedded-cache"
|
||||
build_gradle_module "spring-boot/hazelcast/hazelcast-client-server"
|
||||
build_gradle_module "spring-boot/cache"
|
||||
|
||||
echo ""
|
||||
echo "+++"
|
||||
@@ -122,12 +123,12 @@ fi
|
||||
|
||||
if [[ "$MODULE" == "module2" ]]
|
||||
then
|
||||
build_gradle_module "solid/isp"
|
||||
build_maven_module "solid/lsp"
|
||||
build_maven_module "resilience4j/retry"
|
||||
build_maven_module "resilience4j/ratelimiter"
|
||||
build_maven_module "resilience4j/timelimiter"
|
||||
build_maven_module "solid/lsp"
|
||||
build_gradle_module "spring-data/spring-data-jdbc-converter"
|
||||
build_gradle_module "solid"
|
||||
build_gradle_module "reactive"
|
||||
build_gradle_module "junit/assumptions"
|
||||
build_gradle_module "logging"
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Examples with JUnit 4 and JUnit 5
|
||||
# Examples for assumptions with JUnit 4 and 5
|
||||
|
||||
Have a look at [the code](/src/test/java/com/example/demo/)
|
||||
Have a look at [the code](/src/test/java/com/example/demo/).
|
||||
|
||||
## Blog posts
|
||||
|
||||
* [Assumptions and Conditional Test Execution with JUnit 4 and 5](https://reflectoring.io/conditional-junit4-junit5-tests/)
|
||||
|
||||
7
reactive/README.md
Normal file
7
reactive/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Reactive code examples
|
||||
|
||||
Some code examples using reactive code.
|
||||
|
||||
## Blog posts
|
||||
|
||||
* [Reactive Multi-Threading with RxJava - Pitfalls and Solutions](https://reflectoring.io/rxjava-reactive-batch-processing/)
|
||||
10
resilience4j/ratelimiter/README.md
Normal file
10
resilience4j/ratelimiter/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Rate limiting with Resilience4J
|
||||
|
||||
Run the Examples program.
|
||||
|
||||
## Blog posts
|
||||
|
||||
* [Implementing Rate Limiting with Resilience4j](https://reflectoring.io/rate-limiting-with-resilience4j)
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
Code for the examples used in the article at
|
||||
https://reflectoring.io/rate-limiting-with-resilience4j
|
||||
|
||||
Run the Examples program.
|
||||
|
||||
7
resilience4j/retry/README.md
Normal file
7
resilience4j/retry/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Retry with Resilience4J
|
||||
|
||||
Run the Examples program
|
||||
|
||||
## Blog posts
|
||||
|
||||
* [Implementing Retry with Resilience4j](https://reflectoring.io/retry-with-resilience4j/)
|
||||
@@ -1 +0,0 @@
|
||||
Run the Examples program
|
||||
7
solid/isp/README.md
Normal file
7
solid/isp/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Interface Segregation Principle
|
||||
|
||||
Example code showing the Interface Segregation Principle
|
||||
|
||||
## Blog posts
|
||||
|
||||
* [Everything You Need to Know About the Interface Segregation Principle](https://reflectoring.io/interface-segregation-principle/)
|
||||
0
solid/gradlew → solid/isp/gradlew
vendored
0
solid/gradlew → solid/isp/gradlew
vendored
@@ -1,3 +1,5 @@
|
||||
# Liskov Substition Principle
|
||||
|
||||
There are 5 programs under com/reflectoring/examples/lsp/paymentexample.
|
||||
|
||||
Run in this order to see class design evolution:
|
||||
@@ -11,4 +13,8 @@ Packages are organized similarly: violation, forcefit, forcefitandconditional,
|
||||
and redesigned have specific classes modified at that point in the evolution.
|
||||
|
||||
Common code is in common, common/exceptions, common/external and
|
||||
common/instruments.
|
||||
common/instruments.
|
||||
|
||||
## Blog posts
|
||||
|
||||
* [The Liskov Substitution Principle Explained](https://reflectoring.io/lsp-explained/)
|
||||
5
spring-boot/argumentresolver/README.md
Normal file
5
spring-boot/argumentresolver/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Custom Argument Resolvers with Spring Boot
|
||||
|
||||
## Blog posts
|
||||
|
||||
* [Custom Web Controller Arguments with Spring MVC and Spring Boot](https://reflectoring.io/spring-boot-argumentresolver/)
|
||||
26
spring-boot/bean-lifecycle/.gitignore
vendored
Normal file
26
spring-boot/bean-lifecycle/.gitignore
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
.gradle
|
||||
/build/
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
/out/
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
6
spring-boot/bean-lifecycle/README.md
Normal file
6
spring-boot/bean-lifecycle/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Spring Bean Lifecycle
|
||||
|
||||
This code shows how to hook in to the phases of the Spring bean lifecycle.
|
||||
|
||||
## Blog Posts
|
||||
* [Hooking into the Spring Bean Lifecycle](https://reflectoring.io/spring-bean-lifecycle)
|
||||
26
spring-boot/bean-lifecycle/build.gradle
Normal file
26
spring-boot/bean-lifecycle/build.gradle
Normal file
@@ -0,0 +1,26 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '2.3.2.RELEASE'
|
||||
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'io.reflectoring'
|
||||
version = '0.0.1-SNAPSHOT'
|
||||
sourceCompatibility = '11'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-quartz'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-jersey'
|
||||
testImplementation('org.springframework.boot:spring-boot-starter-test') {
|
||||
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
BIN
spring-boot/bean-lifecycle/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
spring-boot/bean-lifecycle/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
spring-boot/bean-lifecycle/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
spring-boot/bean-lifecycle/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#Tue Feb 06 12:27:20 CET 2018
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
||||
172
spring-boot/bean-lifecycle/gradlew
vendored
Executable file
172
spring-boot/bean-lifecycle/gradlew
vendored
Executable file
@@ -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 environment 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 environment 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" "$@"
|
||||
84
spring-boot/bean-lifecycle/gradlew.bat
vendored
Normal file
84
spring-boot/bean-lifecycle/gradlew.bat
vendored
Normal file
@@ -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 environment 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 environment 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
|
||||
1
spring-boot/bean-lifecycle/settings.gradle
Normal file
1
spring-boot/bean-lifecycle/settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = 'beanlifecycle'
|
||||
@@ -0,0 +1,12 @@
|
||||
package io.reflectoring.beanlifecycle;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class BeanLifecycleApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(BeanLifecycleApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package io.reflectoring.beanlifecycle;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
|
||||
public class MyBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (bean instanceof MySpringBean) {
|
||||
System.out.println("--- postProcessBeforeInitialization executed ---");
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (bean instanceof MySpringBean) {
|
||||
System.out.println("--- postProcessAfterInitialization executed ---");
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package io.reflectoring.beanlifecycle;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
public class MySpringBean implements BeanNameAware, ApplicationContextAware,
|
||||
InitializingBean, DisposableBean {
|
||||
|
||||
private String message;
|
||||
|
||||
public void sendMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanName(String name) {
|
||||
System.out.println("--- setBeanName executed ---");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
System.out.println("--- setApplicationContext executed ---");
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
System.out.println("--- @PostConstruct executed ---");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
System.out.println("--- afterPropertiesSet executed ---");
|
||||
}
|
||||
|
||||
public void initMethod() {
|
||||
System.out.println("--- init-method executed ---");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void preDestroy() {
|
||||
System.out.println("--- @PreDestroy executed ---");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
System.out.println("--- destroy executed ---");
|
||||
}
|
||||
|
||||
public void destroyMethod() {
|
||||
System.out.println("--- destroy-method executed ---");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package io.reflectoring.beanlifecycle;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class MySpringConfiguration {
|
||||
|
||||
@Bean
|
||||
public MyBeanPostProcessor myBeanPostProcessor(){
|
||||
return new MyBeanPostProcessor();
|
||||
}
|
||||
|
||||
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
|
||||
public MySpringBean mySpringBean(){
|
||||
return new MySpringBean();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package io.reflectoring.beanlifecycle.ipdatabase;
|
||||
|
||||
public class IpDatabaseRepository {
|
||||
|
||||
private String file;
|
||||
|
||||
public IpDatabaseRepository(String file) {
|
||||
this.file = file;
|
||||
// some logic to download and update the new database file
|
||||
}
|
||||
|
||||
public String lookup(String ipAddress){
|
||||
// hardcoded for examplary purposes
|
||||
return "DE";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.reflectoring.beanlifecycle.ipdatabase;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class IpToLocationService implements BeanFactoryAware {
|
||||
|
||||
DefaultListableBeanFactory listableBeanFactory;
|
||||
IpDatabaseRepository ipDatabaseRepository;
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
listableBeanFactory = (DefaultListableBeanFactory) beanFactory;
|
||||
updateIpDatabase();
|
||||
}
|
||||
|
||||
public void updateIpDatabase(){
|
||||
String updateUrl = "https://download.acme.com/latest/ip-address-database.mdb";
|
||||
|
||||
AbstractBeanDefinition definition = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(IpDatabaseRepository.class)
|
||||
.addConstructorArgValue(updateUrl)
|
||||
.getBeanDefinition();
|
||||
|
||||
listableBeanFactory.registerBeanDefinition("ipDatabaseRepository", definition);
|
||||
this.ipDatabaseRepository = listableBeanFactory.getBean(IpDatabaseRepository.class);
|
||||
}
|
||||
|
||||
public String getCountry(String ipAddress){
|
||||
return ipDatabaseRepository.lookup(ipAddress);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.reflectoring.beanlifecycle.jersey;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
@Configuration
|
||||
public class JerseyConfig extends ResourceConfig {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@PostConstruct
|
||||
public void registerResources() {
|
||||
applicationContext.getBeansWithAnnotation(Path.class).values().forEach(this::register);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package io.reflectoring.beanlifecycle.jersey;
|
||||
|
||||
import io.reflectoring.beanlifecycle.ipdatabase.IpToLocationService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
@Component
|
||||
@Path("/api")
|
||||
public class LocationResource {
|
||||
|
||||
@Autowired
|
||||
HttpServletRequest servletRequest;
|
||||
|
||||
@Autowired
|
||||
IpToLocationService locationService;
|
||||
|
||||
@GET
|
||||
@Path("/location")
|
||||
public String location() {
|
||||
return locationService.getCountry(servletRequest.getRemoteAddr());
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/update")
|
||||
public void update() {
|
||||
locationService.updateIpDatabase();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.reflectoring.beanlifecycle.logging;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class NamedSpringBean implements BeanNameAware {
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(NamedSpringBean.class);
|
||||
|
||||
public void setBeanName(String name) {
|
||||
logger.info(name + " created.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.reflectoring.beanlifecycle.quartz;
|
||||
|
||||
import org.quartz.spi.TriggerFiredBundle;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
|
||||
|
||||
/**
|
||||
* Custom Quartz {@link org.quartz.spi.JobFactory} to provide bean autowire capability
|
||||
*/
|
||||
public class AutowireCapableJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
|
||||
|
||||
private AutowireCapableBeanFactory beanFactory;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(final ApplicationContext context) {
|
||||
this.beanFactory = context.getAutowireCapableBeanFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
|
||||
final Object job = super.createJobInstance(bundle);
|
||||
this.beanFactory.autowireBean(job);
|
||||
return job;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package io.reflectoring.beanlifecycle.quartz;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
|
||||
|
||||
@Configuration
|
||||
public class QuartzConfig {
|
||||
|
||||
@Autowired
|
||||
ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* Create custom {@link SchedulerFactoryBean} for Quartz
|
||||
*/
|
||||
@Bean
|
||||
public SchedulerFactoryBean schedulerFactoryBean(){
|
||||
AutowireCapableJobFactory jobFactory = new AutowireCapableJobFactory();
|
||||
jobFactory.setApplicationContext(applicationContext);
|
||||
|
||||
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
|
||||
factoryBean.setJobFactory(jobFactory);
|
||||
|
||||
return factoryBean;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.reflectoring.beanlifecycle;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest
|
||||
public class BeanLifecycleApplicationTests {
|
||||
|
||||
@Autowired
|
||||
public MySpringBean mySpringBean;
|
||||
|
||||
@Test
|
||||
public void testMySpringBeanLifecycle() {
|
||||
String message = "Hello World";
|
||||
mySpringBean.sendMessage(message);
|
||||
assertThat(mySpringBean.getMessage()).isEqualTo(message);
|
||||
}
|
||||
|
||||
}
|
||||
5
spring-boot/boundaries/README.md
Normal file
5
spring-boot/boundaries/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Clean Architecture Boundaries with Spring Boot and ArchUnit
|
||||
|
||||
## Blog posts
|
||||
|
||||
* [Clean Architecture Boundaries with Spring Boot and ArchUnit](https://reflectoring.io/java-components-clean-boundaries/)
|
||||
22
spring-boot/cache/src/test/java/io/reflectoring/cache/AbstractIntegrationTest.java
vendored
Normal file
22
spring-boot/cache/src/test/java/io/reflectoring/cache/AbstractIntegrationTest.java
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
package io.reflectoring.cache;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.testcontainers.containers.FixedHostPortGenericContainer;
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
|
||||
public class AbstractIntegrationTest {
|
||||
|
||||
static GenericContainer firstMember =
|
||||
new FixedHostPortGenericContainer("hazelcast/hazelcast:4.0.1")
|
||||
.withFixedExposedPort(5701, 5701);
|
||||
|
||||
static GenericContainer secondMember =
|
||||
new FixedHostPortGenericContainer("hazelcast/hazelcast:4.0.1")
|
||||
.withFixedExposedPort(5702, 5701);
|
||||
|
||||
@BeforeAll
|
||||
public static void init() {
|
||||
firstMember.start();
|
||||
secondMember.start();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package io.reflectoring.cache.rest;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.reflectoring.cache.AbstractIntegrationTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
@@ -16,7 +17,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
@ActiveProfiles("client")
|
||||
class CarResourceClientCacheIntegrationTest {
|
||||
class CarResourceClientCacheIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
Reference in New Issue
Block a user