diff --git a/pay-app-spring-microservices-fix/README.md b/pay-app-spring-microservices-fix/README.md new file mode 100644 index 0000000..bc7c0ba --- /dev/null +++ b/pay-app-spring-microservices-fix/README.md @@ -0,0 +1,25 @@ +# Microservicios con Spring Boot + +![Architecture](./resources/microservicesarchitecture.png) + +## Información de los microservicios +El microservicio de invoices, debe listar las facturas de clientes y además debe consumir una cola para cambiar el estado de la factura cuando esta se paga a través del microservicio de pago. +El microservicio de pago debe registrar el pago en su respectiva bd y además debe dejar un mensaje en una cola para actualizar la factura en el microservicio de facturas y además debe dejar un mensaje en una cola para registrar el movimiento en el microservicio de transacciones. +El microservicio de transacciones debe listar las transacciones de una factura, además debe consumir una cola para obtener las transacciones de pago del microservicio de pago. +Todos los microservicios deben consumir la cadena de conexión desde el servicio de configuración centralizada. + +La información de los endpoints disponibles por microservicio se incluyen en el documento de INFO.md +## Scripts de creación de bases de datos + +La informacion de como crear las bases de datos y sus respectivas tablas se incluyen en google.com + +## Tecnologías utilizadas + +- Spring Boot (Java Framework JDK v11+) +- Gradle (Gestor de dependencias) +- Postman (Test de endpoints/servicios rest) +- Postgresql (Base de Datos) +- MySQL (Base de Datos) +- MongoDB (Base de Datos NoSQL) +- Kafka (Gestor de Mensajería) +- Github (Repositorio para proyecto y Configuraciones de micorservicios) diff --git a/pay-app-spring-microservices-fix/app-config/.gitignore b/pay-app-spring-microservices-fix/app-config/.gitignore new file mode 100644 index 0000000..c2065bc --- /dev/null +++ b/pay-app-spring-microservices-fix/app-config/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/pay-app-spring-microservices-fix/app-config/Dockerfile b/pay-app-spring-microservices-fix/app-config/Dockerfile new file mode 100644 index 0000000..03735c2 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-config/Dockerfile @@ -0,0 +1,13 @@ +FROM openjdk:13-alpine as stage1 +COPY . /app +WORKDIR /app +RUN chmod 777 gradlew +RUN ./gradlew clean +RUN ./gradlew bootJar + + +FROM openjdk:13-alpine +EXPOSE 8010 +COPY --from=stage1 /app/build/libs/app-config-1.0.0.jar app-config.jar +#ADD ./build/libs/app-config-1.0.0.jar app-config.jar +ENTRYPOINT ["java", "-jar", "/app-config.jar"] \ No newline at end of file diff --git a/pay-app-spring-microservices-fix/app-config/build.gradle b/pay-app-spring-microservices-fix/app-config/build.gradle new file mode 100644 index 0000000..e49e8f8 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-config/build.gradle @@ -0,0 +1,36 @@ +plugins { + id 'org.springframework.boot' version '2.3.10.RELEASE' + id 'io.spring.dependency-management' version '1.0.11.RELEASE' + id 'java' +} + +group = 'com.aforo' +version = '1.0.0' +sourceCompatibility = '11' + +repositories { + mavenCentral() +} + +ext { + set('springCloudVersion', "Hoxton.SR11") +} + +dependencies { + implementation 'org.springframework.cloud:spring-cloud-config-server' +// implementation 'org.springframework.cloud:spring-cloud-starter-consul-discovery' + + testImplementation('org.springframework.boot:spring-boot-starter-test') { + exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' + } +} + +dependencyManagement { + imports { + mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" + } +} + +test { + useJUnitPlatform() +} diff --git a/pay-app-spring-microservices-fix/app-config/gradle/wrapper/gradle-wrapper.jar b/pay-app-spring-microservices-fix/app-config/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/pay-app-spring-microservices-fix/app-config/gradle/wrapper/gradle-wrapper.jar differ diff --git a/pay-app-spring-microservices-fix/app-config/gradle/wrapper/gradle-wrapper.properties b/pay-app-spring-microservices-fix/app-config/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..549d844 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-config/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/pay-app-spring-microservices-fix/app-config/gradlew b/pay-app-spring-microservices-fix/app-config/gradlew new file mode 100644 index 0000000..8f89047 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-config/gradlew @@ -0,0 +1,184 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## 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='"-Xmx64m" "-Xms64m"' + +# 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 or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ]; 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=$(expr $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" + +exec "$JAVACMD" "$@" diff --git a/pay-app-spring-microservices-fix/app-config/gradlew.bat b/pay-app-spring-microservices-fix/app-config/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-config/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@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 Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@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="-Xmx64m" "-Xms64m" + +@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 execute + +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 execute + +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 + +: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 %* + +: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/pay-app-spring-microservices-fix/app-config/settings.gradle b/pay-app-spring-microservices-fix/app-config/settings.gradle new file mode 100644 index 0000000..7c9d23a --- /dev/null +++ b/pay-app-spring-microservices-fix/app-config/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'app-config' diff --git a/pay-app-spring-microservices-fix/app-config/src/main/java/com/aforo/appconfig/AppConfigApplication.java b/pay-app-spring-microservices-fix/app-config/src/main/java/com/aforo/appconfig/AppConfigApplication.java new file mode 100644 index 0000000..c64a6b2 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-config/src/main/java/com/aforo/appconfig/AppConfigApplication.java @@ -0,0 +1,15 @@ +package com.aforo.appconfig; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; + +@SpringBootApplication +@EnableConfigServer +public class AppConfigApplication { + + public static void main(String[] args) { + SpringApplication.run(AppConfigApplication.class, args); + } + +} diff --git a/pay-app-spring-microservices-fix/app-config/src/main/resources/application.properties b/pay-app-spring-microservices-fix/app-config/src/main/resources/application.properties new file mode 100644 index 0000000..72012d1 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-config/src/main/resources/application.properties @@ -0,0 +1,15 @@ +# Server +spring.application.name=app-config +server.port=8888 + +# Config +spring.cloud.config.server.git.uri=https://github.com/icesi-ops/training_microservices.git +spring.cloud.config.server.default-label=master +spring.cloud.config.server.git.search-paths=pay-app-spring-microservices/config +spring.cloud.config.server.git.skip-ssl-validation=true + +# Consul +#spring.cloud.consul.host=consul +#spring.cloud.consul.port=8500 +#spring.cloud.consul.discovery.health-check-interval=5s +#spring.cloud.consul.discovery.prefer-ip-address=true diff --git a/pay-app-spring-microservices-fix/app-config/src/test/java/com/aforo/appconfig/AppConfigApplicationTests.java b/pay-app-spring-microservices-fix/app-config/src/test/java/com/aforo/appconfig/AppConfigApplicationTests.java new file mode 100644 index 0000000..90d6ce9 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-config/src/test/java/com/aforo/appconfig/AppConfigApplicationTests.java @@ -0,0 +1,13 @@ +package com.aforo.appconfig; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class AppConfigApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/pay-app-spring-microservices-fix/app-invoice/.gitignore b/pay-app-spring-microservices-fix/app-invoice/.gitignore new file mode 100644 index 0000000..c2065bc --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/pay-app-spring-microservices-fix/app-invoice/Dockerfile b/pay-app-spring-microservices-fix/app-invoice/Dockerfile new file mode 100644 index 0000000..dbbe310 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/Dockerfile @@ -0,0 +1,13 @@ +FROM openjdk:13-alpine as stage1 +COPY . /app +WORKDIR /app +RUN chmod 777 gradlew +RUN ./gradlew clean +RUN ./gradlew bootJar + + +FROM openjdk:13-alpine +EXPOSE 8010 +COPY --from=stage1 /app/build/libs/app-invoice-1.0.0.jar app-invoice.jar +#ADD ./build/libs/app-config-1.0.0.jar app-config.jar +ENTRYPOINT ["java", "-jar", "/app-invoice.jar"] diff --git a/pay-app-spring-microservices-fix/app-invoice/build.gradle b/pay-app-spring-microservices-fix/app-invoice/build.gradle new file mode 100644 index 0000000..76d0556 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/build.gradle @@ -0,0 +1,47 @@ +plugins { + id 'org.springframework.boot' version '2.3.10.RELEASE' + id 'io.spring.dependency-management' version '1.0.11.RELEASE' + id 'java' +} + + +group = 'com.aforo' +version = '1.0.0' +sourceCompatibility = '11' + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +repositories { + mavenCentral() +} + +ext { + set('springCloudVersion', "Hoxton.SR11") +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.kafka:spring-kafka' + implementation 'org.springframework.cloud:spring-cloud-starter-config' + + compileOnly 'org.projectlombok:lombok' + runtimeOnly 'org.postgresql:postgresql' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.kafka:spring-kafka-test' +} + +dependencyManagement { + imports { + mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" + } +} + +test { + useJUnitPlatform() +} diff --git a/pay-app-spring-microservices-fix/app-invoice/gradle/wrapper/gradle-wrapper.jar b/pay-app-spring-microservices-fix/app-invoice/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/pay-app-spring-microservices-fix/app-invoice/gradle/wrapper/gradle-wrapper.jar differ diff --git a/pay-app-spring-microservices-fix/app-invoice/gradle/wrapper/gradle-wrapper.properties b/pay-app-spring-microservices-fix/app-invoice/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..549d844 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/pay-app-spring-microservices-fix/app-invoice/gradlew b/pay-app-spring-microservices-fix/app-invoice/gradlew new file mode 100644 index 0000000..8f89047 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/gradlew @@ -0,0 +1,184 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## 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='"-Xmx64m" "-Xms64m"' + +# 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 or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ]; 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=$(expr $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" + +exec "$JAVACMD" "$@" diff --git a/pay-app-spring-microservices-fix/app-invoice/gradlew.bat b/pay-app-spring-microservices-fix/app-invoice/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@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 Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@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="-Xmx64m" "-Xms64m" + +@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 execute + +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 execute + +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 + +: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 %* + +: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/pay-app-spring-microservices-fix/app-invoice/settings.gradle b/pay-app-spring-microservices-fix/app-invoice/settings.gradle new file mode 100644 index 0000000..e21d591 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'app-invoice' diff --git a/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/AppInvoiceApplication.java b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/AppInvoiceApplication.java new file mode 100644 index 0000000..da591f6 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/AppInvoiceApplication.java @@ -0,0 +1,13 @@ +package com.aforo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AppInvoiceApplication { + + public static void main(String[] args) { + SpringApplication.run(AppInvoiceApplication.class, args); + } + +} diff --git a/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/controller/InvoiceController.java b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/controller/InvoiceController.java new file mode 100644 index 0000000..9694557 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/controller/InvoiceController.java @@ -0,0 +1,29 @@ +package com.aforo.controller; + +import com.aforo.model.Invoice; +import com.aforo.service.InvoiceService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +public class InvoiceController { + + @Autowired + private InvoiceService service; + + private Logger log = LoggerFactory.getLogger(InvoiceController.class); + + @GetMapping("/all") + public ResponseEntity> findAllInvoices() { + log.info("Consultando Invoices"); + var respose = service.findAllInvoices(); + return ResponseEntity.status(HttpStatus.CREATED).body(respose); + } +} diff --git a/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/dao/InvoiceDao.java b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/dao/InvoiceDao.java new file mode 100644 index 0000000..42bac4b --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/dao/InvoiceDao.java @@ -0,0 +1,18 @@ +package com.aforo.dao; + +import com.aforo.model.Invoice; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface InvoiceDao extends CrudRepository { + + @Query("select i from Invoice i order by i.idInvoice") + List findAllInvoices(); + + @Query("select i from Invoice i where i.idInvoice=:id") + Invoice findInvoiceById(Integer id); +} diff --git a/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/kafka/consumer/ConsumerConfig.java b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/kafka/consumer/ConsumerConfig.java new file mode 100644 index 0000000..4c0b63d --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/kafka/consumer/ConsumerConfig.java @@ -0,0 +1,9 @@ +package com.aforo.kafka.consumer; + +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.annotation.EnableKafka; + +@Configuration +@EnableKafka +public class ConsumerConfig { +} diff --git a/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/kafka/consumer/TransactionEvents.java b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/kafka/consumer/TransactionEvents.java new file mode 100644 index 0000000..aca57b9 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/kafka/consumer/TransactionEvents.java @@ -0,0 +1,33 @@ +package com.aforo.kafka.consumer; + +import com.aforo.dao.InvoiceDao; +import com.aforo.model.Invoice; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class TransactionEvents { + + @Autowired + private InvoiceDao _dao; + + @Autowired + private ObjectMapper objectMapper; + + private Logger log = LoggerFactory.getLogger(TransactionEvents.class); + + public void processTransactionEvent(ConsumerRecord consumerRecord) throws JsonProcessingException { + Invoice event = objectMapper.readValue(consumerRecord.value(), Invoice.class); + log.info("Actulizando Invoice ***" + event.getIdInvoice()); + event.setState(1); + log.info("Se ha pagado la factura # " + event.getIdInvoice()); + Invoice old_event = _dao.findInvoiceById(event.getIdInvoice()); + event.setAmount(old_event.getAmount() - event.getAmount()); + _dao.save(event); + } +} diff --git a/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/kafka/listener/ConsumerListener.java b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/kafka/listener/ConsumerListener.java new file mode 100644 index 0000000..29f4394 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/kafka/listener/ConsumerListener.java @@ -0,0 +1,27 @@ +package com.aforo.kafka.listener; + +import com.aforo.kafka.consumer.TransactionEvents; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Component; + +@Component +public class ConsumerListener { + + @Autowired + private TransactionEvents events; + + private Logger log = LoggerFactory.getLogger(ConsumerListener.class); + + @KafkaListener(topics = {"transaction-events"}) + public void onMessage(ConsumerRecord consumerRecord) throws JsonMappingException, JsonProcessingException { + log.info("*************** MICROSERVICE APP INVOICE *******************"); + log.info("ConsumerRecord : {}", consumerRecord.value()); + events.processTransactionEvent(consumerRecord); + } +} diff --git a/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/model/Invoice.java b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/model/Invoice.java new file mode 100644 index 0000000..bd907fd --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/model/Invoice.java @@ -0,0 +1,18 @@ +package com.aforo.model; + +import lombok.Data; + +import javax.persistence.*; +import java.io.Serializable; + +@Entity +@Table(name="invoice") +@Data +public class Invoice implements Serializable { + + private static final long serialVersionUID = 1L; + @Id + private Integer idInvoice; + private Double amount ; + private Integer state ; +} diff --git a/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/service/InvoiceService.java b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/service/InvoiceService.java new file mode 100644 index 0000000..f77a162 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/src/main/java/com/aforo/service/InvoiceService.java @@ -0,0 +1,19 @@ +package com.aforo.service; + +import com.aforo.dao.InvoiceDao; +import com.aforo.model.Invoice; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class InvoiceService { + + @Autowired + private InvoiceDao _dao; + + public List findAllInvoices() { + return _dao.findAllInvoices(); + } +} diff --git a/pay-app-spring-microservices-fix/app-invoice/src/main/resources/application.properties b/pay-app-spring-microservices-fix/app-invoice/src/main/resources/application.properties new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/pay-app-spring-microservices-fix/app-invoice/src/main/resources/bootstrap.properties b/pay-app-spring-microservices-fix/app-invoice/src/main/resources/bootstrap.properties new file mode 100644 index 0000000..b254c68 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/src/main/resources/bootstrap.properties @@ -0,0 +1,3 @@ +spring.application.name=app-invoice +spring.profiles.active=dev +spring.cloud.config.uri=http://app-config:8888 diff --git a/pay-app-spring-microservices-fix/app-invoice/src/test/java/com/aforo/AppInvoiceApplicationTests.java b/pay-app-spring-microservices-fix/app-invoice/src/test/java/com/aforo/AppInvoiceApplicationTests.java new file mode 100644 index 0000000..faa2489 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-invoice/src/test/java/com/aforo/AppInvoiceApplicationTests.java @@ -0,0 +1,13 @@ +package com.aforo; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class AppInvoiceApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/pay-app-spring-microservices-fix/app-pay/.gitignore b/pay-app-spring-microservices-fix/app-pay/.gitignore new file mode 100644 index 0000000..c2065bc --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/pay-app-spring-microservices-fix/app-pay/Dockerfile b/pay-app-spring-microservices-fix/app-pay/Dockerfile new file mode 100644 index 0000000..95034c5 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/Dockerfile @@ -0,0 +1,13 @@ +FROM openjdk:13-alpine as stage1 +COPY . /app +WORKDIR /app +RUN chmod 777 gradlew +RUN ./gradlew clean +RUN ./gradlew bootJar + + +FROM openjdk:13-alpine +EXPOSE 8010 +COPY --from=stage1 /app/build/libs/app-pay-1.0.0.jar app-pay.jar +#ADD ./build/libs/app-config-1.0.0.jar app-config.jar +ENTRYPOINT ["java", "-jar", "/app-pay.jar"] \ No newline at end of file diff --git a/pay-app-spring-microservices-fix/app-pay/README.md b/pay-app-spring-microservices-fix/app-pay/README.md new file mode 100644 index 0000000..253df8a --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/README.md @@ -0,0 +1,12 @@ +# App Pay + +Microservicio encargado de registrar el pago de una factura y dejar un mensaje a la cola de kafka +para actualizar la factura desde el microservicio de app-invoice. También debe dejar un mensaje +para registrar el movimiento en el microservicio de transacciones. + +## Dependencias +* JPA (Hibernate) +* Apache Kafka +* Spring Cloud Config +* PostgreSQL +* Lombok diff --git a/pay-app-spring-microservices-fix/app-pay/build.gradle b/pay-app-spring-microservices-fix/app-pay/build.gradle new file mode 100644 index 0000000..fdaf2e0 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/build.gradle @@ -0,0 +1,46 @@ +plugins { + id 'org.springframework.boot' version '2.3.10.RELEASE' + id 'io.spring.dependency-management' version '1.0.11.RELEASE' + id 'java' +} + +group = 'com.aforo' +version = '1.0.0' +sourceCompatibility = '11' + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +repositories { + mavenCentral() +} + +ext { + set('springCloudVersion', "Hoxton.SR11") +} + + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.kafka:spring-kafka' + implementation 'org.springframework.cloud:spring-cloud-starter-config' + compileOnly 'org.projectlombok:lombok' + runtimeOnly 'mysql:mysql-connector-java' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.kafka:spring-kafka-test' +} + +dependencyManagement { + imports { + mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" + } +} + +test { + useJUnitPlatform() +} diff --git a/pay-app-spring-microservices-fix/app-pay/gradle/wrapper/gradle-wrapper.jar b/pay-app-spring-microservices-fix/app-pay/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/pay-app-spring-microservices-fix/app-pay/gradle/wrapper/gradle-wrapper.jar differ diff --git a/pay-app-spring-microservices-fix/app-pay/gradle/wrapper/gradle-wrapper.properties b/pay-app-spring-microservices-fix/app-pay/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..549d844 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/pay-app-spring-microservices-fix/app-pay/gradlew b/pay-app-spring-microservices-fix/app-pay/gradlew new file mode 100644 index 0000000..8f89047 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/gradlew @@ -0,0 +1,184 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## 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='"-Xmx64m" "-Xms64m"' + +# 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 or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ]; 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=$(expr $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" + +exec "$JAVACMD" "$@" diff --git a/pay-app-spring-microservices-fix/app-pay/gradlew.bat b/pay-app-spring-microservices-fix/app-pay/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@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 Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@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="-Xmx64m" "-Xms64m" + +@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 execute + +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 execute + +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 + +: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 %* + +: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/pay-app-spring-microservices-fix/app-pay/settings.gradle b/pay-app-spring-microservices-fix/app-pay/settings.gradle new file mode 100644 index 0000000..36f0da7 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'app-pay' diff --git a/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/AppPayApplication.java b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/AppPayApplication.java new file mode 100644 index 0000000..6a38973 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/AppPayApplication.java @@ -0,0 +1,13 @@ +package com.aforo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AppPayApplication { + + public static void main(String[] args) { + SpringApplication.run(AppPayApplication.class, args); + } + +} diff --git a/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/config/AutoCreateConfig.java b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/config/AutoCreateConfig.java new file mode 100644 index 0000000..9ef4dcf --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/config/AutoCreateConfig.java @@ -0,0 +1,19 @@ +package com.aforo.config; + +import org.apache.kafka.clients.admin.NewTopic; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.TopicBuilder; + +@Configuration +public class AutoCreateConfig { + + @Bean + public NewTopic depositEvent() { + return TopicBuilder + .name("trasaction-events") + .partitions(3) + .replicas(1) + .build(); + } +} diff --git a/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/controller/PayController.java b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/controller/PayController.java new file mode 100644 index 0000000..d627039 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/controller/PayController.java @@ -0,0 +1,36 @@ +package com.aforo.controller; + +import com.aforo.kafka.producer.PayEventProducer; +import com.aforo.model.Pay; +import com.aforo.service.PayService; +import com.fasterxml.jackson.core.JsonProcessingException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PayController { + + @Autowired + private PayService service; + + @Autowired + PayEventProducer producer; + + private Logger log = LoggerFactory.getLogger(PayController.class); + + @PostMapping("/pay") + public ResponseEntity postDepositEvent(@RequestBody Pay pay) throws JsonProcessingException { + log.info("Registrando nuevo pago"); + var respose = service.registerPay(pay); + log.info("Enviando mensaje a Kafka"); + producer.sendPayEvent(respose); + log.info("Mensaje agregado a la cola correctamente"); + return ResponseEntity.status(HttpStatus.CREATED).body(respose); + } +} diff --git a/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/dao/PayDao.java b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/dao/PayDao.java new file mode 100644 index 0000000..4a7ee91 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/dao/PayDao.java @@ -0,0 +1,9 @@ +package com.aforo.dao; + +import com.aforo.model.Pay; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PayDao extends CrudRepository { +} diff --git a/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/kafka/producer/PayEventProducer.java b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/kafka/producer/PayEventProducer.java new file mode 100644 index 0000000..1f970f4 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/kafka/producer/PayEventProducer.java @@ -0,0 +1,73 @@ +package com.aforo.kafka.producer; + +import com.aforo.model.Pay; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.header.Header; +import org.apache.kafka.common.header.internals.RecordHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.support.SendResult; +import org.springframework.stereotype.Component; +import org.springframework.util.concurrent.ListenableFuture; +import org.springframework.util.concurrent.ListenableFutureCallback; + +import java.util.List; + + +@Component +public class PayEventProducer { + + @Autowired + private KafkaTemplate kafkaTemplate; + + @Autowired + private ObjectMapper objectMapper; + + private Logger log = LoggerFactory.getLogger(PayEventProducer.class); + String topic = "transaction-events"; + + public ListenableFuture> sendPayEvent(Pay pay) throws JsonProcessingException { + Integer key = pay.getIdOperation(); + String value = objectMapper.writeValueAsString(pay); + + ProducerRecord producerRecord = buildProducerRecord(key, value, topic); + ListenableFuture> listenableFuture = kafkaTemplate.send(producerRecord); + listenableFuture.addCallback(new ListenableFutureCallback<>() { + + @Override + public void onSuccess(SendResult result) { + handleSuccess(key, value, result); + } + + @Override + public void onFailure(Throwable ex) { + handleFailure(key, value, ex); + } + }); + + return listenableFuture; + } + + private ProducerRecord buildProducerRecord(Integer key, String value, String topic) { + List
recordHeaders = List.of(new RecordHeader("payment-event-source", "scanner".getBytes())); + return new ProducerRecord<>(topic, null, key, value, recordHeaders); + } + + private void handleFailure(Integer key, String value, Throwable e) { + log.error("Error enviando el mensaje, error: {} ", e.getMessage()); + try { + + } catch (Throwable ex) { + log.error("Error OnFailure: {}", ex.getMessage()); + } + } + + private void handleSuccess(Integer key, String value, SendResult result) { + log.info("Message Sent Successfully for the key :{} and the value is {},partition is {}", key, value, + result.getRecordMetadata().partition()); + } +} diff --git a/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/model/Pay.java b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/model/Pay.java new file mode 100644 index 0000000..2379867 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/model/Pay.java @@ -0,0 +1,24 @@ +package com.aforo.model; + +import lombok.Data; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.Date; + +@Entity +@Table(name="pay") +@Data +public class Pay implements Serializable { + + private static final long serialVersionUID = 1L; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id_operation") + private Integer idOperation; + @Column(name = "id_invoice") + private Integer idInvoice; + private Double amount; + @Temporal(TemporalType.TIMESTAMP) + private Date dateTime; +} diff --git a/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/service/PayService.java b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/service/PayService.java new file mode 100644 index 0000000..ae70de3 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/src/main/java/com/aforo/service/PayService.java @@ -0,0 +1,17 @@ +package com.aforo.service; + +import com.aforo.dao.PayDao; +import com.aforo.model.Pay; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class PayService { + + @Autowired + private PayDao _dao; + + public Pay registerPay(Pay pay) { + return _dao.save(pay); + } +} diff --git a/pay-app-spring-microservices-fix/app-pay/src/main/resources/application.properties b/pay-app-spring-microservices-fix/app-pay/src/main/resources/application.properties new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/pay-app-spring-microservices-fix/app-pay/src/main/resources/bootstrap.properties b/pay-app-spring-microservices-fix/app-pay/src/main/resources/bootstrap.properties new file mode 100644 index 0000000..91cb925 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/src/main/resources/bootstrap.properties @@ -0,0 +1,3 @@ +spring.application.name=app-pay +spring.profiles.active=dev +spring.cloud.config.uri=http://app-config:8888 diff --git a/pay-app-spring-microservices-fix/app-pay/src/test/java/com/aforo/AppPayApplicationTests.java b/pay-app-spring-microservices-fix/app-pay/src/test/java/com/aforo/AppPayApplicationTests.java new file mode 100644 index 0000000..d45f2ea --- /dev/null +++ b/pay-app-spring-microservices-fix/app-pay/src/test/java/com/aforo/AppPayApplicationTests.java @@ -0,0 +1,13 @@ +package com.aforo; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class AppPayApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/pay-app-spring-microservices-fix/app-transaction/.gitignore b/pay-app-spring-microservices-fix/app-transaction/.gitignore new file mode 100644 index 0000000..c2065bc --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/pay-app-spring-microservices-fix/app-transaction/Dockerfile b/pay-app-spring-microservices-fix/app-transaction/Dockerfile new file mode 100644 index 0000000..a74e386 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/Dockerfile @@ -0,0 +1,13 @@ +FROM openjdk:13-alpine as stage1 +COPY . /app +WORKDIR /app +RUN chmod 777 gradlew +RUN ./gradlew clean +RUN ./gradlew bootJar + + +FROM openjdk:13-alpine +EXPOSE 8010 +COPY --from=stage1 /app/build/libs/app-transaction-1.0.0.jar app-transaction.jar +#ADD ./build/libs/app-config-1.0.0.jar app-config.jar +ENTRYPOINT ["java", "-jar", "/app-transaction.jar"] \ No newline at end of file diff --git a/pay-app-spring-microservices-fix/app-transaction/build.gradle b/pay-app-spring-microservices-fix/app-transaction/build.gradle new file mode 100644 index 0000000..1ca3403 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/build.gradle @@ -0,0 +1,44 @@ +plugins { + id 'org.springframework.boot' version '2.3.10.RELEASE' + id 'io.spring.dependency-management' version '1.0.11.RELEASE' + id 'java' +} + +group = 'com.aforo' +version = '1.0.0' +sourceCompatibility = '11' + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +repositories { + mavenCentral() +} + +ext { + set('springCloudVersion', "Hoxton.SR11") +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.kafka:spring-kafka' + implementation 'org.springframework.cloud:spring-cloud-starter-config' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.kafka:spring-kafka-test' +} + +dependencyManagement { + imports { + mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" + } +} + +test { + useJUnitPlatform() +} diff --git a/pay-app-spring-microservices-fix/app-transaction/gradle/wrapper/gradle-wrapper.jar b/pay-app-spring-microservices-fix/app-transaction/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/pay-app-spring-microservices-fix/app-transaction/gradle/wrapper/gradle-wrapper.jar differ diff --git a/pay-app-spring-microservices-fix/app-transaction/gradle/wrapper/gradle-wrapper.properties b/pay-app-spring-microservices-fix/app-transaction/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..549d844 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/pay-app-spring-microservices-fix/app-transaction/gradlew b/pay-app-spring-microservices-fix/app-transaction/gradlew new file mode 100644 index 0000000..8f89047 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/gradlew @@ -0,0 +1,184 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## 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='"-Xmx64m" "-Xms64m"' + +# 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 or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ]; 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=$(expr $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" + +exec "$JAVACMD" "$@" diff --git a/pay-app-spring-microservices-fix/app-transaction/gradlew.bat b/pay-app-spring-microservices-fix/app-transaction/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@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 Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@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="-Xmx64m" "-Xms64m" + +@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 execute + +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 execute + +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 + +: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 %* + +: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/pay-app-spring-microservices-fix/app-transaction/settings.gradle b/pay-app-spring-microservices-fix/app-transaction/settings.gradle new file mode 100644 index 0000000..22a90a6 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'app-transaction' diff --git a/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/AppTransactionApplication.java b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/AppTransactionApplication.java new file mode 100644 index 0000000..83b1bf1 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/AppTransactionApplication.java @@ -0,0 +1,13 @@ +package com.aforo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AppTransactionApplication { + + public static void main(String[] args) { + SpringApplication.run(AppTransactionApplication.class, args); + } + +} diff --git a/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/controller/TransactionController.java b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/controller/TransactionController.java new file mode 100644 index 0000000..ed44a2d --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/controller/TransactionController.java @@ -0,0 +1,29 @@ +package com.aforo.controller; + +import com.aforo.model.Transaction; +import com.aforo.service.TransactionService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +public class TransactionController { + + @Autowired + private TransactionService service; + + private Logger log = LoggerFactory.getLogger(TransactionController.class); + + @GetMapping("/all") + public ResponseEntity> findAllInvoices() { + log.info("Consultando Invoices"); + var respose = service.findAllTransaction(); + return ResponseEntity.status(HttpStatus.CREATED).body(respose); + } +} diff --git a/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/dao/TransactionDao.java b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/dao/TransactionDao.java new file mode 100644 index 0000000..bb01f57 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/dao/TransactionDao.java @@ -0,0 +1,9 @@ +package com.aforo.dao; + +import com.aforo.model.Transaction; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface TransactionDao extends MongoRepository { +} diff --git a/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/kafka/consumer/ConsumerConfig.java b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/kafka/consumer/ConsumerConfig.java new file mode 100644 index 0000000..4c0b63d --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/kafka/consumer/ConsumerConfig.java @@ -0,0 +1,9 @@ +package com.aforo.kafka.consumer; + +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.annotation.EnableKafka; + +@Configuration +@EnableKafka +public class ConsumerConfig { +} diff --git a/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/kafka/consumer/TransactionEvents.java b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/kafka/consumer/TransactionEvents.java new file mode 100644 index 0000000..341cc69 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/kafka/consumer/TransactionEvents.java @@ -0,0 +1,31 @@ +package com.aforo.kafka.consumer; + +import com.aforo.dao.TransactionDao; +import com.aforo.model.Transaction; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import java.util.UUID; + +@Service +public class TransactionEvents { + + @Autowired + private TransactionDao _dao; + + @Autowired + private ObjectMapper objectMapper; + + private Logger log = LoggerFactory.getLogger(TransactionEvents.class); + + public void processTransactionEvent(ConsumerRecord consumerRecord) throws JsonProcessingException { + Transaction event = objectMapper.readValue(consumerRecord.value(), Transaction.class); + log.info("Registrando Transaccion Invoice ***" + event.getIdInvoice()); + event.setIdTransaction(UUID.randomUUID().toString()); + _dao.save(event); + } +} diff --git a/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/kafka/listener/ConsumerListener.java b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/kafka/listener/ConsumerListener.java new file mode 100644 index 0000000..f82cbd5 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/kafka/listener/ConsumerListener.java @@ -0,0 +1,27 @@ +package com.aforo.kafka.listener; + +import com.aforo.kafka.consumer.TransactionEvents; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Component; + +@Component +public class ConsumerListener { + + @Autowired + private TransactionEvents events; + + private Logger log = LoggerFactory.getLogger(ConsumerListener.class); + + @KafkaListener(topics = {"transaction-events"}) + public void onMessage(ConsumerRecord consumerRecord) throws JsonMappingException, JsonProcessingException { + log.info("*************** MICROSERVICE APP TRANSACTION *******************"); + log.info("ConsumerRecord : {}", consumerRecord.value()); + events.processTransactionEvent(consumerRecord); + } +} diff --git a/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/model/Transaction.java b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/model/Transaction.java new file mode 100644 index 0000000..1b4dcfb --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/model/Transaction.java @@ -0,0 +1,20 @@ +package com.aforo.model; + +import lombok.Data; +import org.bson.codecs.pojo.annotations.BsonId; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.io.Serializable; +import java.util.Date; + +@Document +@Data +public class Transaction implements Serializable { + + private static final long serialVersionUID = 1L; + @BsonId + private String idTransaction; + private Integer idInvoice; + private Double amount ; + private Date dateTime; +} diff --git a/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/service/TransactionService.java b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/service/TransactionService.java new file mode 100644 index 0000000..e92eb45 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/src/main/java/com/aforo/service/TransactionService.java @@ -0,0 +1,19 @@ +package com.aforo.service; + +import com.aforo.dao.TransactionDao; +import com.aforo.model.Transaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class TransactionService { + + @Autowired + private TransactionDao _dao; + + public List findAllTransaction() { + return _dao.findAll(); + } +} diff --git a/pay-app-spring-microservices-fix/app-transaction/src/main/resources/application.properties b/pay-app-spring-microservices-fix/app-transaction/src/main/resources/application.properties new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/pay-app-spring-microservices-fix/app-transaction/src/main/resources/bootstrap.properties b/pay-app-spring-microservices-fix/app-transaction/src/main/resources/bootstrap.properties new file mode 100644 index 0000000..2bd5d08 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/src/main/resources/bootstrap.properties @@ -0,0 +1,3 @@ +spring.application.name=app-transaction +spring.profiles.active=dev +spring.cloud.config.uri=http://app-config:8888 diff --git a/pay-app-spring-microservices-fix/app-transaction/src/test/java/com/aforo/AppTransactionApplicationTests.java b/pay-app-spring-microservices-fix/app-transaction/src/test/java/com/aforo/AppTransactionApplicationTests.java new file mode 100644 index 0000000..9416622 --- /dev/null +++ b/pay-app-spring-microservices-fix/app-transaction/src/test/java/com/aforo/AppTransactionApplicationTests.java @@ -0,0 +1,13 @@ +package com.aforo; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class AppTransactionApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/pay-app-spring-microservices-fix/appgw/gateway.config.yml b/pay-app-spring-microservices-fix/appgw/gateway.config.yml new file mode 100644 index 0000000..1a7f68b --- /dev/null +++ b/pay-app-spring-microservices-fix/appgw/gateway.config.yml @@ -0,0 +1,35 @@ +http: + port: 8080 +admin: + port: 9876 + host: localhost +apiEndpoints: + appconfig: + host: localhost + paths: ['/config','/config/*'] +serviceEndpoints: + appconfig: + url: 'http://loadbalancer/config/' +policies: + - basic-auth + - cors + - expression + - key-auth + - log + - oauth2 + - proxy + - rate-limit +pipelines: + default: + apiEndpoints: + - appconfig + policies: + # Uncomment `key-auth:` when instructed to in the Getting Started guide. + - key-auth: + - proxy: + - action: + serviceEndpoint: appconfig + changeOrigin: true + prependPath: false + ignorePath: false + stripPath: false diff --git a/pay-app-spring-microservices-fix/appgw/models/applications.json b/pay-app-spring-microservices-fix/appgw/models/applications.json new file mode 100644 index 0000000..8b9c248 --- /dev/null +++ b/pay-app-spring-microservices-fix/appgw/models/applications.json @@ -0,0 +1,16 @@ +{ + "$id": "http://express-gateway.io/models/applications.json", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "redirectUri": { + "type": "string", + "format": "uri" + } + }, + "required": [ + "name" + ] +} diff --git a/pay-app-spring-microservices-fix/appgw/models/credentials.json b/pay-app-spring-microservices-fix/appgw/models/credentials.json new file mode 100644 index 0000000..3762505 --- /dev/null +++ b/pay-app-spring-microservices-fix/appgw/models/credentials.json @@ -0,0 +1,85 @@ +{ + "$id": "http://express-gateway.io/models/credentials.json", + "type": "object", + "definitions": { + "credentialBase": { + "type": "object", + "properties": { + "autoGeneratePassword": { + "type": "boolean", + "default": true + }, + "scopes": { + "type": [ + "string", + "array" + ], + "items": { + "type": "string" + } + } + }, + "required": [ + "autoGeneratePassword" + ] + } + }, + "properties": { + "basic-auth": { + "allOf": [ + { + "$ref": "#/definitions/credentialBase" + }, + { + "type": "object", + "properties": { + "passwordKey": { + "type": "string", + "default": "password" + } + }, + "required": [ + "passwordKey" + ] + } + ] + }, + "key-auth": { + "type": "object", + "properties": { + "scopes": { + "type": [ + "string", + "array" + ], + "items": { + "type": "string" + } + } + } + }, + "jwt": { + "type": "object", + "properties": {} + }, + "oauth2": { + "allOf": [ + { + "$ref": "#/definitions/credentialBase" + }, + { + "type": "object", + "properties": { + "passwordKey": { + "type": "string", + "default": "secret" + } + }, + "required": [ + "passwordKey" + ] + } + ] + } + } +} diff --git a/pay-app-spring-microservices-fix/appgw/models/users.json b/pay-app-spring-microservices-fix/appgw/models/users.json new file mode 100644 index 0000000..0ad047f --- /dev/null +++ b/pay-app-spring-microservices-fix/appgw/models/users.json @@ -0,0 +1,28 @@ +{ + "$id": "http://express-gateway.io/models/users.json", + "type": "object", + "properties": { + "firstname": { + "type": "string" + }, + "lastname": { + "type": "string" + }, + "username": { + "type": "string" + }, + "email": { + "type": "string", + "format": "email" + }, + "redirectUri": { + "type": "string", + "format": "uri" + } + }, + "required": [ + "username", + "firstname", + "lastname" + ] +} diff --git a/pay-app-spring-microservices-fix/appgw/system.config.yml b/pay-app-spring-microservices-fix/appgw/system.config.yml new file mode 100644 index 0000000..7f3e32a --- /dev/null +++ b/pay-app-spring-microservices-fix/appgw/system.config.yml @@ -0,0 +1,27 @@ +# Core +db: + redis: + host: express-gateway-data-store + port: 6379 + namespace: EG + +#plugins: + # express-gateway-plugin-example: + # param1: 'param from system.config' + +crypto: + cipherKey: sensitiveKey + algorithm: aes256 + saltRounds: 10 + +# OAuth2 Settings +session: + secret: keyboard cat + resave: false + saveUninitialized: false +accessTokens: + timeToExpiry: 7200000 +refreshTokens: + timeToExpiry: 7200000 +authorizationCodes: + timeToExpiry: 300000 diff --git a/pay-app-spring-microservices-fix/commands.md b/pay-app-spring-microservices-fix/commands.md new file mode 100644 index 0000000..4c7fa26 --- /dev/null +++ b/pay-app-spring-microservices-fix/commands.md @@ -0,0 +1,98 @@ +docker network create distribuidos +docker run -p 5432:5432 --name postgres --network distribuidos -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=db_invoice -d icesiops/postgres:0.1.0 + +docker run -p 3306:3306 --name mysql --network distribuidos -e MYSQL_ROOT_PASSWORD=mysql -e MYSQL_DATABASE=db_operation -d icesiops/mysql:0.1.0 + +docker run -p 27017:27017 --network distribuidos --name mongodb -d mongo + +docker run -p 2181:2181 -d -p 9092:9092 --name servicekafka --network distribuidos -e ADVERTISED_HOST=servicekafka -e NUM_PARTITIONS=3 johnnypark/kafka-zookeeper + +docker run -d -p 8888:8888 --network distribuidos --name app-config icesiops/appconfig:0.1.0 + +docker run -d -p 8006:8006 --network distribuidos --name app-invoice icesiops/appinvoice:0.1.0 + +docker run -d -p 8010:8010 --network distribuidos --name app-pay icesiops/apppay:0.1.0 + +docker run -d -p 8082:8082 --network distribuidos --name app-transaction icesiops/apptransaction:0.1.0 + +psql -h localhost -d db_invoice -U postgres -f data.sql + +#### consul + +Modify application.properties file according to consul server information. +Add the line implementation 'org.springframework.cloud:spring-cloud-starter-consul-discovery' into build.gradle depedencies +Install dnsmasq +Create a config file for dnsmasq below the path /etc/dnsmasq.d +Add the next line server=/consul/127.0.0.1#8600 +start dnsmasq +modifiy resolv.conf to add ip loopback like dns server +run command: dig app-service.service.consul + +docker run -d -p 8500:8500 -p 8600:8600/udp --network distribuidos --name consul consul:latest agent -server -bootstrap-expect 1 -ui -data-dir /tmp -client=0.0.0.0 + +### Load Balancer +Create dockerfile +FROM haproxy:2.3 +COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg + +Create haproxy config +defaults + timeout connect 5s + timeout client 1m + timeout server 1m + +frontend stats + bind *:1936 + mode http + stats uri / + stats show-legends + no log + +frontend http_front + bind *:80 + default_backend http_back + +backend http_back + balance roundrobin + server-template mywebapp 1-10 _web._tcp.service.consul resolvers consul resolve-opts allow-dup-ip resolve-prefer ipv4 check + +resolvers consul + nameserver consul 127.0.0.1:8600 + accepted_payload_size 8192 + hold valid 5s + +docker build -t icesiops/loadbalancer:0.1.0 . + +### Application Gateway + +In order to use Identity features, we need to have a data storage like Redis. + +docker run --network distribuidos -d --name express-gateway-data-store \ + -p 6379:6379 \ + redis:alpine +2. Start the Express-Gateway instance +Run the command inside appgw directory o keep in mind change the volume path to pointing to gateway.config.yml +docker run -d --name express-gateway \ + --network distribuidos \ + -v .:/var/lib/eg \ + -p 8080:8080 \ + -p 9876:9876 \ + express-gateway + +3. uncoment #key-auth +4. connect to gw container +docker exec -it express-gateway sh + +5. create users +eg users create + +6. assign auth key +eg credentials create -c sebas -t key-auth -q + +7. copy key 3DvE2HCfZCyfgxAjF40tOk:2U4Cojm11JaPJF6WRUcFBL + +8. Curl API endpoint as Sebas with key credentials - SUCCESS! + +curl -H "Authorization: apiKey ${keyId}:${keySecret}" http://localhost:8080/config/app-pay/dev + +curl -H "Authorization: apiKey 3DvE2HCfZCyfgxAjF40tOk:2U4Cojm11JaPJF6WRUcFBL" http://localhost:8080/config/app-pay/dev diff --git a/pay-app-spring-microservices-fix/config/app-invoice-dev.properties b/pay-app-spring-microservices-fix/config/app-invoice-dev.properties new file mode 100644 index 0000000..ff17d97 --- /dev/null +++ b/pay-app-spring-microservices-fix/config/app-invoice-dev.properties @@ -0,0 +1,25 @@ +# Server +spring.application.name=app-invoice +server.port=8006 + +# Kafka +spring.kafka.consumer.bootstrap-servers=servicekafka:9092 +#spring.kafka.consumer.bootstrap-servers=servicekafka:9092 +#spring.kafka.admin.properties.bootstrap.servers=servicekafka:9092 +#spring.kafka.admin.properties.bootstrap.servers=servicekafka:9092 +spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.IntegerDeserializer +spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer +spring.kafka.consumer.group-id=invoice-events-listener-group + +# JPA +logging.level.org.hibernate.SQL=debug +spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true +spring.jpa.hibernate.ddl-auto=create + +# Postgresql +spring.datasource.url=jdbc:postgresql://postgres:5432/db_invoice +#spring.datasource.url=jdbc:postgresql://postgres:5432/db_invoice +spring.datasource.username=postgres +spring.datasource.password=postgres +spring.datasource.driver-class-name=org.postgresql.Driver +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL95Dialect \ No newline at end of file diff --git a/pay-app-spring-microservices-fix/config/app-pay-dev.properties b/pay-app-spring-microservices-fix/config/app-pay-dev.properties new file mode 100644 index 0000000..b7959d8 --- /dev/null +++ b/pay-app-spring-microservices-fix/config/app-pay-dev.properties @@ -0,0 +1,25 @@ +# Server +spring.application.name=app-pay +server.port=8010 + +# Kafka +spring.kafka.template.default-topic=transaction-events +spring.kafka.producer.bootstrap-servers=servicekafka:9092 +#spring.kafka.producer.bootstrap-servers=servicekafka:9092 +spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.IntegerSerializer +spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer +spring.kafka.admin.properties.bootstrap.servers=servicekafka:9092 +#spring.kafka.admin.properties.bootstrap.servers=servicekafka:9092 + +# JPA +logging.level.org.hibernate.SQL=debug +spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true +spring.jpa.hibernate.ddl-auto=create + +# MySQL +spring.datasource.url=jdbc:mysql://mysql:3306/db_operation?serverTimezone=America/Lima&allowPublicKeyRetrieval=true&useSSL=false +#spring.datasource.url=jdbc:mysql://mysql:3306/db_operation?serverTimezone=America/Lima&allowPublicKeyRetrieval=true&useSSL=false +spring.datasource.username=root +spring.datasource.password=mysql +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect \ No newline at end of file diff --git a/pay-app-spring-microservices-fix/config/app-transaction-dev.properties b/pay-app-spring-microservices-fix/config/app-transaction-dev.properties new file mode 100644 index 0000000..17d29f4 --- /dev/null +++ b/pay-app-spring-microservices-fix/config/app-transaction-dev.properties @@ -0,0 +1,16 @@ +# Server +spring.application.name=app-transaction +server.port=8082 + +# Kafka +spring.kafka.consumer.bootstrap-servers=servicekafka:9092 +#spring.kafka.consumer.bootstrap-servers=servicekafka:9092 +spring.kafka.admin.properties.bootstrap.servers=servicekafka:9092 +#spring.kafka.admin.properties.bootstrap.servers=servicekafka:9092 +spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.IntegerDeserializer +spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer +spring.kafka.consumer.group-id=transaction-events-listener-group + +# MongoDB +spring.data.mongodb.uri=mongodb://mongodb:27017/db_transaction +#spring.data.mongodb.uri=mongodb://mongodb:27017/db_transaction \ No newline at end of file diff --git a/pay-app-spring-microservices-fix/haproxy/Dockerfile b/pay-app-spring-microservices-fix/haproxy/Dockerfile new file mode 100644 index 0000000..9e9a3ad --- /dev/null +++ b/pay-app-spring-microservices-fix/haproxy/Dockerfile @@ -0,0 +1,2 @@ +FROM haproxy:2.3 +COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg \ No newline at end of file diff --git a/pay-app-spring-microservices-fix/haproxy/haproxy.cfg b/pay-app-spring-microservices-fix/haproxy/haproxy.cfg new file mode 100644 index 0000000..3b54b0c --- /dev/null +++ b/pay-app-spring-microservices-fix/haproxy/haproxy.cfg @@ -0,0 +1,34 @@ +defaults + timeout connect 5s + timeout client 1m + timeout server 1m + +frontend stats + bind *:1936 + mode http + stats uri / + stats show-legends + no log + +frontend http_front + bind *:80 + mode http + acl url_config path_beg /config + use_backend config_back if url_config + + default_backend http_back + +backend config_back + mode http + balance roundrobin + http-request set-path "%[path,regsub(^/config/,/)]" + server appconfig app-config.service.consul:8888 resolvers consul resolve-prefer ipv4 check +backend http_back + mode http + balance roundrobin + server-template mywebapp 1-10 _web._tcp.service.consul resolvers consul resolve-prefer ipv4 check + +resolvers consul + nameserver consul consul:8600 + accepted_payload_size 8192 + hold valid 5s diff --git a/pay-app-spring-microservices-fix/idTransaction-fix-evidence.png b/pay-app-spring-microservices-fix/idTransaction-fix-evidence.png new file mode 100755 index 0000000..2b23bc8 Binary files /dev/null and b/pay-app-spring-microservices-fix/idTransaction-fix-evidence.png differ diff --git a/pay-app-spring-microservices-fix/pay-fix-evidence.mp4 b/pay-app-spring-microservices-fix/pay-fix-evidence.mp4 new file mode 100644 index 0000000..3cd99a8 Binary files /dev/null and b/pay-app-spring-microservices-fix/pay-fix-evidence.mp4 differ diff --git a/pay-app-spring-microservices-fix/resources/DB.md b/pay-app-spring-microservices-fix/resources/DB.md new file mode 100644 index 0000000..231dbb3 --- /dev/null +++ b/pay-app-spring-microservices-fix/resources/DB.md @@ -0,0 +1,54 @@ +# Endpoints + +A continuacion se detallan los scripts para la creación de las bases de datos respectivas para los microservicios + + +## PostgreSQL + +1. Levantar docker de PostgreSQL (Al levantar el docker automaticamente se incluye la base de datos a crear) +``` +$ docker run -p 5434:5432 --name postgres --network aforo255-test -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=db_invoice -d postgres:12-alpine +``` + +2. Si se desea agregar nueva base de datos se debe ingresar al docker de Postgres y crear la base: +``` +$ docker exec -it postgres bash +$ psql -U postgres +$ CREATE TABLE db_invoice; +``` + +3. Conectarse a la base de datos desde cualquier cliente SQL (Ejemplo: Dbeaver) y ejecutar el script: +``` +CREATE TABLE IF NOT EXISTS invoice +( + id_invoice integer not null, + amount numeric, + state integer, + primary key (id_invoice) +); +``` + +## MySQL + +1. Levantar docker de MySQL (Al levantar el docker automaticamente se incluye la base de datos a crear) +``` +$ docker run -p 3307:3306 --name microservicio-mysql8 --network aforo255-test -e MYSQL_ROOT_PASSWORD=mysql -e MYSQL_DATABASE=db_operation -d mysql:8 +``` + +2. Conectarse a la base de datos desde cualquier cliente SQL (Ejemplo: Dbeaver) y ejecutar el script: +``` +CREATE TABLE pay +( + id_invoice integer not null, + amount numeric, + state integer, + primary key (id_invoice) +); +``` + +## MongoDB + +1. Levantar docker de MongoDB (Al levantar el microservicio y almacenar un registro se crea automaticamente la coleccion en mongo) +``` +$ docker run -p 27018:27017 --network aforo255-test --name mongodb -d mongo +``` \ No newline at end of file diff --git a/pay-app-spring-microservices-fix/resources/INFO.md b/pay-app-spring-microservices-fix/resources/INFO.md new file mode 100644 index 0000000..7bfc0c1 --- /dev/null +++ b/pay-app-spring-microservices-fix/resources/INFO.md @@ -0,0 +1,63 @@ +# Endpoints + +A continuacion se detallan los endpoints y se adjuntan los Curl respectivos de cada microservicio para cumplir con las funcionalidad del trabajo + + +## Microservicios + +#### app-config + +Microservicio que se encarga de manejar las configuraciones de los microservicios, las configuraciones están en el siguiente directorio: + +[Configuraciones](https://github.com/icesi-ops/training_microservices.git) + +Endpoints para consultar configuraciones de los microservicios: + +* Curl consultar las configuraciones de los microservicios almacenadas en el repositorio +``` +curl --location --request GET 'http://localhost:8888/app-pay/dev' + +curl --location --request GET 'http://localhost:8888/app-invoice/dev' + +curl --location --request GET 'http://localhost:8888/app-transaction/dev' +``` + +#### app-pay + +Microservicio que se encarga de registrar los pagos de una factura + +[Dockerfile](https://github.com/icesi-ops/training_microservices.git) + +* Curl del servicio para registrar pagos +``` +curl --location --request POST 'http://localhost:8010/pay' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "idOperation": 1, + "idInvoice": 1, + "amount": 900, + "dateTime": "2021-05-21" +}' +``` + +#### app-inovice + +Microservicio que se encarga de obtener los mensajes de kafka y actualizar el estado de una factura segun el pago registrado + +[Dockerfile](https://github.com/icesi-ops/training_microservices.git) + +* Curl del servicio para obtener el detalle de todos los invoices +``` +curl --location --request GET 'http://localhost:8006/all' +``` + +#### app-transaction + +Microservicio que se encarga de obtener los mensajes de kafka y registrar las transacciones que se realizan con el pago de las facturas + +[Dockerfile](https://github.com/icesi-ops/training_microservices.git) + +* Curl del servicio para obtener el detalle de todos los invoices +``` +curl --location --request GET 'http://localhost:8082/all' +``` diff --git a/pay-app-spring-microservices-fix/resources/microservicesarchitecture.png b/pay-app-spring-microservices-fix/resources/microservicesarchitecture.png new file mode 100755 index 0000000..c10185b Binary files /dev/null and b/pay-app-spring-microservices-fix/resources/microservicesarchitecture.png differ diff --git a/pay-app-spring-microservices-fix/resources/mysql/Dockerfile b/pay-app-spring-microservices-fix/resources/mysql/Dockerfile new file mode 100644 index 0000000..32bc267 --- /dev/null +++ b/pay-app-spring-microservices-fix/resources/mysql/Dockerfile @@ -0,0 +1,6 @@ +FROM mysql:8 + +env MYSQL_ROOT_PASSWORD=MYSQL +env MYSQL_DATABASE=db_operation +COPY ./mysql.sql /docker-entrypoint-initdb.d + diff --git a/pay-app-spring-microservices-fix/resources/mysql/mysql.sql b/pay-app-spring-microservices-fix/resources/mysql/mysql.sql new file mode 100644 index 0000000..37a094a --- /dev/null +++ b/pay-app-spring-microservices-fix/resources/mysql/mysql.sql @@ -0,0 +1,6 @@ +CREATE TABLE pay ( + id_invoice integer not null, + amount numeric, + state integer, + primary key (id_invoice) +); \ No newline at end of file diff --git a/pay-app-spring-microservices-fix/resources/postgres/Dockerfile b/pay-app-spring-microservices-fix/resources/postgres/Dockerfile new file mode 100644 index 0000000..450d83f --- /dev/null +++ b/pay-app-spring-microservices-fix/resources/postgres/Dockerfile @@ -0,0 +1,6 @@ +FROM postgres:12-alpine + +env POSTGRES_PASSWORD=postgres +env POSTGRES_DB=db_invoice +COPY ./postgres.sql /docker-entrypoint-initdb.d + diff --git a/pay-app-spring-microservices-fix/resources/postgres/data.sql b/pay-app-spring-microservices-fix/resources/postgres/data.sql new file mode 100644 index 0000000..dac1339 --- /dev/null +++ b/pay-app-spring-microservices-fix/resources/postgres/data.sql @@ -0,0 +1,5 @@ +INSERT INTO invoice(id_invoice, amount, state) VALUES(1, 1000, 0); +INSERT INTO invoice(id_invoice, amount, state) VALUES(2, 5000, 1); +INSERT INTO invoice(id_invoice, amount, state) VALUES(3, 300, 0); +INSERT INTO invoice(id_invoice, amount, state) VALUES(4, 600, 0); +INSERT INTO invoice(id_invoice, amount, state) VALUES(5, 400, 0); \ No newline at end of file diff --git a/pay-app-spring-microservices-fix/resources/postgres/postgres.sql b/pay-app-spring-microservices-fix/resources/postgres/postgres.sql new file mode 100644 index 0000000..0478485 --- /dev/null +++ b/pay-app-spring-microservices-fix/resources/postgres/postgres.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS invoice ( + id_invoice integer GENERATED by default as IDENTITY PRIMARY KEY, + amount numeric, + state integer +); + +INSERT INTO invoice(id_invoice, amount, state) VALUES(1, 1000, 0); +INSERT INTO invoice(id_invoice, amount, state) VALUES(2, 5000, 1); +INSERT INTO invoice(id_invoice, amount, state) VALUES(3, 300, 0); +INSERT INTO invoice(id_invoice, amount, state) VALUES(4, 600, 0); +INSERT INTO invoice(id_invoice, amount, state) VALUES(5, 400, 0);