first commit
This commit is contained in:
commit
058f4ac97a
5
.dockerignore
Normal file
5
.dockerignore
Normal file
@ -0,0 +1,5 @@
|
||||
*
|
||||
!target/*-runner
|
||||
!target/*-runner.jar
|
||||
!target/lib/*
|
||||
!target/quarkus-app/*
|
||||
45
.gitignore
vendored
Normal file
45
.gitignore
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
#Maven
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
release.properties
|
||||
.flattened-pom.xml
|
||||
|
||||
# Eclipse
|
||||
.project
|
||||
.classpath
|
||||
.settings/
|
||||
bin/
|
||||
|
||||
# IntelliJ
|
||||
.idea
|
||||
*.ipr
|
||||
*.iml
|
||||
*.iws
|
||||
|
||||
# NetBeans
|
||||
nb-configuration.xml
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode
|
||||
.factorypath
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# patch
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
# Local environment
|
||||
.env
|
||||
|
||||
# Plugin directory
|
||||
/.quarkus/cli/plugins/
|
||||
# TLS Certificates
|
||||
.certs/
|
||||
3
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
3
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
wrapperVersion=3.3.4
|
||||
distributionType=only-script
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.12/apache-maven-3.9.12-bin.zip
|
||||
54
README.md
Normal file
54
README.md
Normal file
@ -0,0 +1,54 @@
|
||||
# bus-retrieve-security-notification
|
||||
|
||||
This project uses Quarkus, the Supersonic Subatomic Java Framework.
|
||||
|
||||
If you want to learn more about Quarkus, please visit its website: <https://quarkus.io/>.
|
||||
|
||||
## Running the application in dev mode
|
||||
|
||||
You can run your application in dev mode that enables live coding using:
|
||||
|
||||
```shell script
|
||||
./mvnw quarkus:dev
|
||||
```
|
||||
|
||||
> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at <http://localhost:8080/q/dev/>.
|
||||
|
||||
## Packaging and running the application
|
||||
|
||||
The application can be packaged using:
|
||||
|
||||
```shell script
|
||||
./mvnw package
|
||||
```
|
||||
|
||||
It produces the `quarkus-run.jar` file in the `target/quarkus-app/` directory.
|
||||
Be aware that it’s not an _über-jar_ as the dependencies are copied into the `target/quarkus-app/lib/` directory.
|
||||
|
||||
The application is now runnable using `java -jar target/quarkus-app/quarkus-run.jar`.
|
||||
|
||||
If you want to build an _über-jar_, execute the following command:
|
||||
|
||||
```shell script
|
||||
./mvnw package -Dquarkus.package.jar.type=uber-jar
|
||||
```
|
||||
|
||||
The application, packaged as an _über-jar_, is now runnable using `java -jar target/*-runner.jar`.
|
||||
|
||||
## Creating a native executable
|
||||
|
||||
You can create a native executable using:
|
||||
|
||||
```shell script
|
||||
./mvnw package -Dnative
|
||||
```
|
||||
|
||||
Or, if you don't have GraalVM installed, you can run the native executable build in a container using:
|
||||
|
||||
```shell script
|
||||
./mvnw package -Dnative -Dquarkus.native.container-build=true
|
||||
```
|
||||
|
||||
You can then execute your native executable with: `./target/bus-retrieve-security-notification-1.0-native-quarkus-jdk17-runner`
|
||||
|
||||
If you want to learn more about building native executables, please consult <https://quarkus.io/guides/maven-tooling>.
|
||||
295
mvnw
vendored
Normal file
295
mvnw
vendored
Normal file
@ -0,0 +1,295 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Apache Maven Wrapper startup batch script, version 3.3.4
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
|
||||
# MVNW_REPOURL - repo url base for downloading maven distribution
|
||||
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
|
||||
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
set -euf
|
||||
[ "${MVNW_VERBOSE-}" != debug ] || set -x
|
||||
|
||||
# OS specific support.
|
||||
native_path() { printf %s\\n "$1"; }
|
||||
case "$(uname)" in
|
||||
CYGWIN* | MINGW*)
|
||||
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
|
||||
native_path() { cygpath --path --windows "$1"; }
|
||||
;;
|
||||
esac
|
||||
|
||||
# set JAVACMD and JAVACCMD
|
||||
set_java_home() {
|
||||
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
|
||||
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"
|
||||
JAVACCMD="$JAVA_HOME/jre/sh/javac"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACCMD="$JAVA_HOME/bin/javac"
|
||||
|
||||
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
|
||||
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
|
||||
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
JAVACMD="$(
|
||||
'set' +e
|
||||
'unset' -f command 2>/dev/null
|
||||
'command' -v java
|
||||
)" || :
|
||||
JAVACCMD="$(
|
||||
'set' +e
|
||||
'unset' -f command 2>/dev/null
|
||||
'command' -v javac
|
||||
)" || :
|
||||
|
||||
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
|
||||
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# hash string like Java String::hashCode
|
||||
hash_string() {
|
||||
str="${1:-}" h=0
|
||||
while [ -n "$str" ]; do
|
||||
char="${str%"${str#?}"}"
|
||||
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
|
||||
str="${str#?}"
|
||||
done
|
||||
printf %x\\n $h
|
||||
}
|
||||
|
||||
verbose() { :; }
|
||||
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
|
||||
|
||||
die() {
|
||||
printf %s\\n "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
trim() {
|
||||
# MWRAPPER-139:
|
||||
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
|
||||
# Needed for removing poorly interpreted newline sequences when running in more
|
||||
# exotic environments such as mingw bash on Windows.
|
||||
printf "%s" "${1}" | tr -d '[:space:]'
|
||||
}
|
||||
|
||||
scriptDir="$(dirname "$0")"
|
||||
scriptName="$(basename "$0")"
|
||||
|
||||
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
|
||||
while IFS="=" read -r key value; do
|
||||
case "${key-}" in
|
||||
distributionUrl) distributionUrl=$(trim "${value-}") ;;
|
||||
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
|
||||
esac
|
||||
done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||
|
||||
case "${distributionUrl##*/}" in
|
||||
maven-mvnd-*bin.*)
|
||||
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
|
||||
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
|
||||
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
|
||||
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
|
||||
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
|
||||
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
|
||||
*)
|
||||
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
|
||||
distributionPlatform=linux-amd64
|
||||
;;
|
||||
esac
|
||||
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
|
||||
;;
|
||||
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
|
||||
*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
|
||||
esac
|
||||
|
||||
# apply MVNW_REPOURL and calculate MAVEN_HOME
|
||||
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
|
||||
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
|
||||
distributionUrlName="${distributionUrl##*/}"
|
||||
distributionUrlNameMain="${distributionUrlName%.*}"
|
||||
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
|
||||
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
|
||||
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
|
||||
|
||||
exec_maven() {
|
||||
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
|
||||
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
|
||||
}
|
||||
|
||||
if [ -d "$MAVEN_HOME" ]; then
|
||||
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
|
||||
exec_maven "$@"
|
||||
fi
|
||||
|
||||
case "${distributionUrl-}" in
|
||||
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
|
||||
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
|
||||
esac
|
||||
|
||||
# prepare tmp dir
|
||||
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
|
||||
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
|
||||
trap clean HUP INT TERM EXIT
|
||||
else
|
||||
die "cannot create temp dir"
|
||||
fi
|
||||
|
||||
mkdir -p -- "${MAVEN_HOME%/*}"
|
||||
|
||||
# Download and Install Apache Maven
|
||||
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
|
||||
verbose "Downloading from: $distributionUrl"
|
||||
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||
|
||||
# select .zip or .tar.gz
|
||||
if ! command -v unzip >/dev/null; then
|
||||
distributionUrl="${distributionUrl%.zip}.tar.gz"
|
||||
distributionUrlName="${distributionUrl##*/}"
|
||||
fi
|
||||
|
||||
# verbose opt
|
||||
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
|
||||
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
|
||||
|
||||
# normalize http auth
|
||||
case "${MVNW_PASSWORD:+has-password}" in
|
||||
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
|
||||
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
|
||||
esac
|
||||
|
||||
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
|
||||
verbose "Found wget ... using wget"
|
||||
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
|
||||
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
|
||||
verbose "Found curl ... using curl"
|
||||
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
|
||||
elif set_java_home; then
|
||||
verbose "Falling back to use Java to download"
|
||||
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
|
||||
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||
cat >"$javaSource" <<-END
|
||||
public class Downloader extends java.net.Authenticator
|
||||
{
|
||||
protected java.net.PasswordAuthentication getPasswordAuthentication()
|
||||
{
|
||||
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
|
||||
}
|
||||
public static void main( String[] args ) throws Exception
|
||||
{
|
||||
setDefault( new Downloader() );
|
||||
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
|
||||
}
|
||||
}
|
||||
END
|
||||
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
|
||||
verbose " - Compiling Downloader.java ..."
|
||||
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
|
||||
verbose " - Running Downloader.java ..."
|
||||
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
|
||||
fi
|
||||
|
||||
# If specified, validate the SHA-256 sum of the Maven distribution zip file
|
||||
if [ -n "${distributionSha256Sum-}" ]; then
|
||||
distributionSha256Result=false
|
||||
if [ "$MVN_CMD" = mvnd.sh ]; then
|
||||
echo "Checksum validation is not supported for maven-mvnd." >&2
|
||||
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
|
||||
exit 1
|
||||
elif command -v sha256sum >/dev/null; then
|
||||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then
|
||||
distributionSha256Result=true
|
||||
fi
|
||||
elif command -v shasum >/dev/null; then
|
||||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
|
||||
distributionSha256Result=true
|
||||
fi
|
||||
else
|
||||
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
|
||||
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ $distributionSha256Result = false ]; then
|
||||
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
|
||||
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# unzip and move
|
||||
if command -v unzip >/dev/null; then
|
||||
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
|
||||
else
|
||||
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
|
||||
fi
|
||||
|
||||
# Find the actual extracted directory name (handles snapshots where filename != directory name)
|
||||
actualDistributionDir=""
|
||||
|
||||
# First try the expected directory name (for regular distributions)
|
||||
if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then
|
||||
if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then
|
||||
actualDistributionDir="$distributionUrlNameMain"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If not found, search for any directory with the Maven executable (for snapshots)
|
||||
if [ -z "$actualDistributionDir" ]; then
|
||||
# enable globbing to iterate over items
|
||||
set +f
|
||||
for dir in "$TMP_DOWNLOAD_DIR"/*; do
|
||||
if [ -d "$dir" ]; then
|
||||
if [ -f "$dir/bin/$MVN_CMD" ]; then
|
||||
actualDistributionDir="$(basename "$dir")"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
set -f
|
||||
fi
|
||||
|
||||
if [ -z "$actualDistributionDir" ]; then
|
||||
verbose "Contents of $TMP_DOWNLOAD_DIR:"
|
||||
verbose "$(ls -la "$TMP_DOWNLOAD_DIR")"
|
||||
die "Could not find Maven distribution directory in extracted archive"
|
||||
fi
|
||||
|
||||
verbose "Found extracted Maven distribution directory: $actualDistributionDir"
|
||||
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url"
|
||||
mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
|
||||
|
||||
clean || :
|
||||
exec_maven "$@"
|
||||
189
mvnw.cmd
vendored
Normal file
189
mvnw.cmd
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
<# : batch portion
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Apache Maven Wrapper startup batch script, version 3.3.4
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM MVNW_REPOURL - repo url base for downloading maven distribution
|
||||
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
|
||||
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
|
||||
@SET __MVNW_CMD__=
|
||||
@SET __MVNW_ERROR__=
|
||||
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
|
||||
@SET PSModulePath=
|
||||
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
|
||||
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
|
||||
)
|
||||
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
|
||||
@SET __MVNW_PSMODULEP_SAVE=
|
||||
@SET __MVNW_ARG0_NAME__=
|
||||
@SET MVNW_USERNAME=
|
||||
@SET MVNW_PASSWORD=
|
||||
@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*)
|
||||
@echo Cannot start maven from wrapper >&2 && exit /b 1
|
||||
@GOTO :EOF
|
||||
: end batch / begin powershell #>
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
if ($env:MVNW_VERBOSE -eq "true") {
|
||||
$VerbosePreference = "Continue"
|
||||
}
|
||||
|
||||
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
|
||||
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
|
||||
if (!$distributionUrl) {
|
||||
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||
}
|
||||
|
||||
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
|
||||
"maven-mvnd-*" {
|
||||
$USE_MVND = $true
|
||||
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
|
||||
$MVN_CMD = "mvnd.cmd"
|
||||
break
|
||||
}
|
||||
default {
|
||||
$USE_MVND = $false
|
||||
$MVN_CMD = $script -replace '^mvnw','mvn'
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
# apply MVNW_REPOURL and calculate MAVEN_HOME
|
||||
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
|
||||
if ($env:MVNW_REPOURL) {
|
||||
$MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" }
|
||||
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')"
|
||||
}
|
||||
$distributionUrlName = $distributionUrl -replace '^.*/',''
|
||||
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
|
||||
|
||||
$MAVEN_M2_PATH = "$HOME/.m2"
|
||||
if ($env:MAVEN_USER_HOME) {
|
||||
$MAVEN_M2_PATH = "$env:MAVEN_USER_HOME"
|
||||
}
|
||||
|
||||
if (-not (Test-Path -Path $MAVEN_M2_PATH)) {
|
||||
New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null
|
||||
}
|
||||
|
||||
$MAVEN_WRAPPER_DISTS = $null
|
||||
if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {
|
||||
$MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists"
|
||||
} else {
|
||||
$MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists"
|
||||
}
|
||||
|
||||
$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain"
|
||||
$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
|
||||
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
|
||||
|
||||
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
|
||||
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
|
||||
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
|
||||
exit $?
|
||||
}
|
||||
|
||||
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
|
||||
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
|
||||
}
|
||||
|
||||
# prepare tmp dir
|
||||
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
|
||||
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
|
||||
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
|
||||
trap {
|
||||
if ($TMP_DOWNLOAD_DIR.Exists) {
|
||||
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
|
||||
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
|
||||
}
|
||||
}
|
||||
|
||||
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
|
||||
|
||||
# Download and Install Apache Maven
|
||||
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
|
||||
Write-Verbose "Downloading from: $distributionUrl"
|
||||
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||
|
||||
$webclient = New-Object System.Net.WebClient
|
||||
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
|
||||
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
|
||||
}
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
|
||||
|
||||
# If specified, validate the SHA-256 sum of the Maven distribution zip file
|
||||
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
|
||||
if ($distributionSha256Sum) {
|
||||
if ($USE_MVND) {
|
||||
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
|
||||
}
|
||||
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
|
||||
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
|
||||
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
|
||||
}
|
||||
}
|
||||
|
||||
# unzip and move
|
||||
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
|
||||
|
||||
# Find the actual extracted directory name (handles snapshots where filename != directory name)
|
||||
$actualDistributionDir = ""
|
||||
|
||||
# First try the expected directory name (for regular distributions)
|
||||
$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain"
|
||||
$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD"
|
||||
if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) {
|
||||
$actualDistributionDir = $distributionUrlNameMain
|
||||
}
|
||||
|
||||
# If not found, search for any directory with the Maven executable (for snapshots)
|
||||
if (!$actualDistributionDir) {
|
||||
Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object {
|
||||
$testPath = Join-Path $_.FullName "bin/$MVN_CMD"
|
||||
if (Test-Path -Path $testPath -PathType Leaf) {
|
||||
$actualDistributionDir = $_.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$actualDistributionDir) {
|
||||
Write-Error "Could not find Maven distribution directory in extracted archive"
|
||||
}
|
||||
|
||||
Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir"
|
||||
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null
|
||||
try {
|
||||
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
|
||||
} catch {
|
||||
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
|
||||
Write-Error "fail to move MAVEN_HOME"
|
||||
}
|
||||
} finally {
|
||||
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
|
||||
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
|
||||
}
|
||||
|
||||
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
|
||||
156
pom.xml
Normal file
156
pom.xml
Normal file
@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.banesco</groupId>
|
||||
<artifactId>bus-retrieve-security-notification</artifactId>
|
||||
<version>1.0-native-quarkus-jdk17</version>
|
||||
<name>bus-retrieve-security-notification</name>
|
||||
<description>API Business - Read payment statuses of the file by ID</description>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.release>17</maven.compiler.release>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<compiler-plugin.version>3.14.1</compiler-plugin.version>
|
||||
<compiler-plugin-openshift.version>1.18.2</compiler-plugin-openshift.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
|
||||
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
|
||||
<quarkus.platform.version>3.22.3</quarkus.platform.version>
|
||||
<lombok.version>1.18.42</lombok.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${quarkus.platform.group-id}</groupId>
|
||||
<artifactId>${quarkus.platform.artifact-id}</artifactId>
|
||||
<version>${quarkus.platform.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${quarkus.platform.group-id}</groupId>
|
||||
<artifactId>quarkus-camel-bom</artifactId>
|
||||
<version>${quarkus.platform.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-rest</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-rest-jackson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-hibernate-validator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-smallrye-openapi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-arc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-config-yaml</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-rest-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-rest-client-jackson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-smallrye-health</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.jkube</groupId>
|
||||
<artifactId>openshift-maven-plugin</artifactId>
|
||||
<version>${compiler-plugin-openshift.version}</version>
|
||||
<configuration>
|
||||
<resources>
|
||||
<volumeMounts>
|
||||
<volumeMount>
|
||||
<name>maven-volumen</name>
|
||||
<mountPath>/root/.m2</mountPath>
|
||||
</volumeMount>
|
||||
</volumeMounts>
|
||||
</resources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>${quarkus.platform.group-id}</groupId>
|
||||
<artifactId>quarkus-maven-plugin</artifactId>
|
||||
<version>${quarkus.platform.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>build</goal>
|
||||
<goal>generate-code</goal>
|
||||
<goal>native-image-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<parameters>true</parameters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>native</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>native</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<quarkus.package.type>native</quarkus.package.type>
|
||||
<quarkus.native.enabled>true</quarkus.native.enabled>
|
||||
</properties>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>application-dev.yaml</exclude>
|
||||
<exclude>application-local.yaml</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
31
scripts/native/Dockerfile
Normal file
31
scripts/native/Dockerfile
Normal file
@ -0,0 +1,31 @@
|
||||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
|
||||
# It uses a micro base image, tuned for Quarkus native executables.
|
||||
# It reduces the size of the resulting container image.
|
||||
# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image.
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./mvnw package -Dnative
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/rec-legal-customer-product-directory .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/rec-legal-customer-product-directory
|
||||
#
|
||||
###
|
||||
FROM quay.io/quarkus/quarkus-micro-image:2.0
|
||||
RUN mkdir -p /work
|
||||
ENV TZ="America/Caracas"
|
||||
ENV LANGUAGE='en_US:en'
|
||||
VOLUME /tmp
|
||||
COPY /file/*-runner /work/app
|
||||
RUN chmod -R 775 /work
|
||||
RUN ls -ltra /work/
|
||||
EXPOSE 8080
|
||||
WORKDIR /work/
|
||||
|
||||
ENTRYPOINT ["./app", "-Dquarkus.http.host=0.0.0.0"]
|
||||
Binary file not shown.
98
src/main/docker/Dockerfile.jvm
Normal file
98
src/main/docker/Dockerfile.jvm
Normal file
@ -0,0 +1,98 @@
|
||||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./mvnw package
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/bus-retrieve-security-notification-jvm .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/bus-retrieve-security-notification-jvm
|
||||
#
|
||||
# If you want to include the debug port into your docker image
|
||||
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
|
||||
# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
|
||||
# when running the container
|
||||
#
|
||||
# Then run the container using :
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/bus-retrieve-security-notification-jvm
|
||||
#
|
||||
# This image uses the `run-java.sh` script to run the application.
|
||||
# This scripts computes the command line to execute your Java application, and
|
||||
# includes memory/GC tuning.
|
||||
# You can configure the behavior using the following environment properties:
|
||||
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") - Be aware that this will override
|
||||
# the default JVM options, use `JAVA_OPTS_APPEND` to append options
|
||||
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
|
||||
# in JAVA_OPTS (example: "-Dsome.property=foo")
|
||||
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
|
||||
# used to calculate a default maximal heap memory based on a containers restriction.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
|
||||
# of the container available memory as set here. The default is `50` which means 50%
|
||||
# of the available memory is used as an upper boundary. You can skip this mechanism by
|
||||
# setting this value to `0` in which case no `-Xmx` option is added.
|
||||
# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
|
||||
# is used to calculate a default initial heap memory based on the maximum heap memory.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
|
||||
# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
|
||||
# is used as the initial heap size. You can skip this mechanism by setting this value
|
||||
# to `0` in which case no `-Xms` option is added (example: "25")
|
||||
# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
|
||||
# This is used to calculate the maximum value of the initial heap memory. If used in
|
||||
# a container without any memory constraints for the container then this option has
|
||||
# no effect. If there is a memory constraint then `-Xms` is limited to the value set
|
||||
# here. The default is 4096MB which means the calculated value of `-Xms` never will
|
||||
# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
|
||||
# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
|
||||
# when things are happening. This option, if set to true, will set
|
||||
# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
|
||||
# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
|
||||
# true").
|
||||
# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
|
||||
# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
|
||||
# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
|
||||
# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
|
||||
# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
|
||||
# (example: "20")
|
||||
# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
|
||||
# (example: "40")
|
||||
# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
|
||||
# (example: "4")
|
||||
# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
|
||||
# previous GC times. (example: "90")
|
||||
# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
|
||||
# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
|
||||
# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
|
||||
# contain the necessary JRE command-line options to specify the required GC, which
|
||||
# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
|
||||
# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
|
||||
# accessed directly. (example: "foo.example.com,bar.example.com")
|
||||
#
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi9/openjdk-17:1.23
|
||||
|
||||
ENV LANGUAGE='en_US:en'
|
||||
|
||||
|
||||
# We make four distinct layers so if there are application changes the library layers can be re-used
|
||||
COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/
|
||||
COPY --chown=185 target/quarkus-app/*.jar /deployments/
|
||||
COPY --chown=185 target/quarkus-app/app/ /deployments/app/
|
||||
COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/
|
||||
|
||||
EXPOSE 8080
|
||||
USER 185
|
||||
ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
||||
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
|
||||
|
||||
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
|
||||
|
||||
94
src/main/docker/Dockerfile.legacy-jar
Normal file
94
src/main/docker/Dockerfile.legacy-jar
Normal file
@ -0,0 +1,94 @@
|
||||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./mvnw package -Dquarkus.package.jar.type=legacy-jar
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/bus-retrieve-security-notification-legacy-jar .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/bus-retrieve-security-notification-legacy-jar
|
||||
#
|
||||
# If you want to include the debug port into your docker image
|
||||
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
|
||||
# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
|
||||
# when running the container
|
||||
#
|
||||
# Then run the container using :
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/bus-retrieve-security-notification-legacy-jar
|
||||
#
|
||||
# This image uses the `run-java.sh` script to run the application.
|
||||
# This scripts computes the command line to execute your Java application, and
|
||||
# includes memory/GC tuning.
|
||||
# You can configure the behavior using the following environment properties:
|
||||
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") - Be aware that this will override
|
||||
# the default JVM options, use `JAVA_OPTS_APPEND` to append options
|
||||
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
|
||||
# in JAVA_OPTS (example: "-Dsome.property=foo")
|
||||
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
|
||||
# used to calculate a default maximal heap memory based on a containers restriction.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
|
||||
# of the container available memory as set here. The default is `50` which means 50%
|
||||
# of the available memory is used as an upper boundary. You can skip this mechanism by
|
||||
# setting this value to `0` in which case no `-Xmx` option is added.
|
||||
# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
|
||||
# is used to calculate a default initial heap memory based on the maximum heap memory.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
|
||||
# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
|
||||
# is used as the initial heap size. You can skip this mechanism by setting this value
|
||||
# to `0` in which case no `-Xms` option is added (example: "25")
|
||||
# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
|
||||
# This is used to calculate the maximum value of the initial heap memory. If used in
|
||||
# a container without any memory constraints for the container then this option has
|
||||
# no effect. If there is a memory constraint then `-Xms` is limited to the value set
|
||||
# here. The default is 4096MB which means the calculated value of `-Xms` never will
|
||||
# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
|
||||
# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
|
||||
# when things are happening. This option, if set to true, will set
|
||||
# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
|
||||
# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
|
||||
# true").
|
||||
# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
|
||||
# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
|
||||
# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
|
||||
# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
|
||||
# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
|
||||
# (example: "20")
|
||||
# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
|
||||
# (example: "40")
|
||||
# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
|
||||
# (example: "4")
|
||||
# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
|
||||
# previous GC times. (example: "90")
|
||||
# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
|
||||
# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
|
||||
# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
|
||||
# contain the necessary JRE command-line options to specify the required GC, which
|
||||
# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
|
||||
# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
|
||||
# accessed directly. (example: "foo.example.com,bar.example.com")
|
||||
#
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi9/openjdk-17:1.23
|
||||
|
||||
ENV LANGUAGE='en_US:en'
|
||||
|
||||
|
||||
COPY target/lib/* /deployments/lib/
|
||||
COPY target/*-runner.jar /deployments/quarkus-run.jar
|
||||
|
||||
EXPOSE 8080
|
||||
USER 185
|
||||
ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
||||
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
|
||||
|
||||
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
|
||||
29
src/main/docker/Dockerfile.native
Normal file
29
src/main/docker/Dockerfile.native
Normal file
@ -0,0 +1,29 @@
|
||||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./mvnw package -Dnative
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.native -t quarkus/bus-retrieve-security-notification .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/bus-retrieve-security-notification
|
||||
#
|
||||
# The ` registry.access.redhat.com/ubi9/ubi-minimal:9.7` base image is based on UBI 9.
|
||||
# To use UBI 8, switch to `quay.io/ubi8/ubi-minimal:8.10`.
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi9/ubi-minimal:9.7
|
||||
WORKDIR /work/
|
||||
RUN chown 1001 /work \
|
||||
&& chmod "g+rwX" /work \
|
||||
&& chown 1001:root /work
|
||||
COPY --chown=1001:root --chmod=0755 target/*-runner /work/application
|
||||
|
||||
EXPOSE 8080
|
||||
USER 1001
|
||||
|
||||
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
|
||||
32
src/main/docker/Dockerfile.native-micro
Normal file
32
src/main/docker/Dockerfile.native-micro
Normal file
@ -0,0 +1,32 @@
|
||||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
|
||||
# It uses a micro base image, tuned for Quarkus native executables.
|
||||
# It reduces the size of the resulting container image.
|
||||
# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image.
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./mvnw package -Dnative
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/bus-retrieve-security-notification .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/bus-retrieve-security-notification
|
||||
#
|
||||
# The `quay.io/quarkus/ubi9-quarkus-micro-image:2.0` base image is based on UBI 9.
|
||||
# To use UBI 8, switch to `quay.io/quarkus/quarkus-micro-image:2.0`.
|
||||
###
|
||||
FROM quay.io/quarkus/ubi9-quarkus-micro-image:2.0
|
||||
WORKDIR /work/
|
||||
RUN chown 1001 /work \
|
||||
&& chmod "g+rwX" /work \
|
||||
&& chown 1001:root /work
|
||||
COPY --chown=1001:root --chmod=0755 target/*-runner /work/application
|
||||
|
||||
EXPOSE 8080
|
||||
USER 1001
|
||||
|
||||
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
|
||||
@ -0,0 +1,234 @@
|
||||
package com.banesco.common.application.helper;
|
||||
|
||||
import com.banesco.common.domain.exception.HttpStatusCodeException;
|
||||
import com.banesco.common.domain.model.ApiResponse;
|
||||
import com.banesco.common.domain.model.ErrorMapping;
|
||||
import com.banesco.common.domain.model.StatusResponse;
|
||||
import com.banesco.common.infrastructure.config.MessagesConfig;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Slf4j
|
||||
@ApplicationScoped
|
||||
@RegisterForReflection
|
||||
public class MessageHelper {
|
||||
|
||||
private final MessagesConfig messagesConfig;
|
||||
private final Map<String, ErrorMapping> errorMappings;
|
||||
private static final String ERROR_DEFAULT = "default";
|
||||
private static final String SUCCESS_DEFAULT = "200";
|
||||
private static final String ERROR_FILE_PATH = "errors-mapping/errors.json";
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@Inject
|
||||
public MessageHelper(
|
||||
ObjectMapper objectMapper,
|
||||
MessagesConfig messagesConfig
|
||||
) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.messagesConfig = messagesConfig;
|
||||
this.errorMappings = initializeErrorMappings();
|
||||
}
|
||||
|
||||
public Response handleSuccess(Object data, String statusCode) {
|
||||
log.info(
|
||||
"Respuesta exitosa controlada: {}",
|
||||
statusCode
|
||||
);
|
||||
return buildResponse(data, statusCode);
|
||||
}
|
||||
|
||||
public Response handleException(HttpStatusCodeException exception) {
|
||||
log.error(
|
||||
"Error interno controlado: {} -> {}",
|
||||
exception.getStatusCode(),
|
||||
exception.getErrorCode()
|
||||
);
|
||||
return buildErrorResponse(exception);
|
||||
}
|
||||
|
||||
public Response handleGenericException(Exception exception) {
|
||||
log.error("Error interno no controlado: {}", exception.getMessage());
|
||||
return buildErrorResponse(HttpStatusCodeException.internalServer("500"));
|
||||
}
|
||||
|
||||
public StatusResponse createStatusResponse(String code) {
|
||||
ErrorMapping successMapping = getError(code);
|
||||
|
||||
return StatusResponse.builder()
|
||||
.statusCode(successMapping.getStatusCode())
|
||||
.message(successMapping.getDescription())
|
||||
.build();
|
||||
}
|
||||
|
||||
public StatusResponse createError(
|
||||
ErrorMapping mapping,
|
||||
String fieldPath
|
||||
) {
|
||||
String message = mapping.getDescription();
|
||||
|
||||
if (fieldPath != null && message != null && message.contains("%s")) {
|
||||
message = String.format(message, fieldPath);
|
||||
}
|
||||
|
||||
return StatusResponse.builder()
|
||||
.statusCode(mapping.getStatusCode())
|
||||
.message(message)
|
||||
.build();
|
||||
}
|
||||
|
||||
public <T> ApiResponse<T> buildServiceUnavailableResponse() {
|
||||
return new ApiResponse<>(createStatusResponse("503"));
|
||||
}
|
||||
|
||||
private ErrorMapping getError(String errorCode) {
|
||||
return errorMappings.getOrDefault(
|
||||
errorCode, errorMappings.getOrDefault(ERROR_DEFAULT, createDefaultMapping())
|
||||
);
|
||||
}
|
||||
|
||||
private Response buildErrorResponse(HttpStatusCodeException exception) {
|
||||
ErrorMapping mapping = errorMappings.getOrDefault(
|
||||
exception.getErrorCode(), errorMappings.getOrDefault(
|
||||
String.valueOf(exception.getStatusCode()),
|
||||
createDefaultMapping()
|
||||
)
|
||||
);
|
||||
StatusResponse status = createError(mapping, exception.getFieldPath());
|
||||
|
||||
log.error(
|
||||
"[{}] Message {} -> {}",
|
||||
exception.getExceptionType(),
|
||||
exception.getErrorCode(),
|
||||
status.getMessage()
|
||||
);
|
||||
|
||||
return Response.status(mapping.getHttpCode())
|
||||
.entity(new ApiResponse<>(status))
|
||||
.build();
|
||||
}
|
||||
|
||||
private Response buildResponse(Object data, String statusCode) {
|
||||
ErrorMapping mapping = errorMappings.getOrDefault(
|
||||
statusCode, errorMappings.getOrDefault(
|
||||
statusCode, createDefaultMapping()
|
||||
)
|
||||
);
|
||||
StatusResponse status = createError(mapping, null);
|
||||
|
||||
log.error(
|
||||
"[Success] Message {} -> {}",
|
||||
statusCode,
|
||||
status.getMessage()
|
||||
);
|
||||
|
||||
return Response.status(mapping.getHttpCode())
|
||||
.entity(new ApiResponse<>(data, status))
|
||||
.build();
|
||||
}
|
||||
|
||||
private Map<String, ErrorMapping> initializeErrorMappings() {
|
||||
try {
|
||||
String json;
|
||||
|
||||
if (isReadingFromProps()) {
|
||||
json = messagesConfig.getErrorMessagesJson();
|
||||
log.info("Cargando mensajes de errores desde properties");
|
||||
} else {
|
||||
json = loadFromJsonFile();
|
||||
log.info("Cargando mensajes de errores desde la notificacion JSON");
|
||||
}
|
||||
|
||||
if (json == null || json.isEmpty()) {
|
||||
log.warn("No se encontro JSON de errores");
|
||||
return createDefaultMappings();
|
||||
}
|
||||
|
||||
List<ErrorMapping> mappings = objectMapper.readValue(json, new TypeReference<List<ErrorMapping>>() {});
|
||||
Map<String, ErrorMapping> result = new ConcurrentHashMap<>();
|
||||
|
||||
for (ErrorMapping mapping : mappings) {
|
||||
if (mapping.getBackendCode() != null && !mapping.getBackendCode().trim().isEmpty()) {
|
||||
if (result.containsKey(mapping.getBackendCode())) {
|
||||
log.warn("Clave duplicada encontrada en mappings de errores: {}", mapping.getBackendCode());
|
||||
} else {
|
||||
result.put(mapping.getBackendCode(), mapping);
|
||||
}
|
||||
} else {
|
||||
log.warn("Ignorando mapping sin backendCode valido: {}", mapping.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
log.info("Mappings de errores cargados exitosamente, total validos: {}", result.size());
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.error("Error cargando mappings de errores: {}", e.getMessage());
|
||||
return createDefaultMappings();
|
||||
}
|
||||
}
|
||||
|
||||
private String loadFromJsonFile() {
|
||||
try (InputStream is = MessageHelper.class.getClassLoader().getResourceAsStream(ERROR_FILE_PATH)) {
|
||||
if (is == null) {
|
||||
log.warn("No se encontro la notificacion de errores: {}", ERROR_FILE_PATH);
|
||||
return "";
|
||||
}
|
||||
return new String(is.readAllBytes());
|
||||
} catch (Exception e) {
|
||||
log.error("Error leyendo archivo de errores: {}", e.getMessage());
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, ErrorMapping> createDefaultMappings() {
|
||||
Map<String, ErrorMapping> defaults = new ConcurrentHashMap<>();
|
||||
defaults.put(ERROR_DEFAULT, createDefaultMapping());
|
||||
defaults.put(SUCCESS_DEFAULT, createSuccessMapping());
|
||||
return defaults;
|
||||
}
|
||||
|
||||
private ErrorMapping createDefaultMapping() {
|
||||
ErrorMapping mapping = new ErrorMapping();
|
||||
mapping.setBackendCode(ERROR_DEFAULT);
|
||||
mapping.setHttpCode(409);
|
||||
mapping.setStatusCode("409");
|
||||
mapping.setDescription("Conflicto");
|
||||
return mapping;
|
||||
}
|
||||
|
||||
private ErrorMapping createSuccessMapping() {
|
||||
ErrorMapping mapping = new ErrorMapping();
|
||||
mapping.setBackendCode(SUCCESS_DEFAULT);
|
||||
mapping.setHttpCode(200);
|
||||
mapping.setStatusCode("200");
|
||||
mapping.setDescription("Operacion exitosa");
|
||||
return mapping;
|
||||
}
|
||||
|
||||
public boolean isReadingFromProps() {
|
||||
return messagesConfig.isReadFromProps();
|
||||
}
|
||||
|
||||
public boolean isSuccessStatusCode(StatusResponse statusResponse) {
|
||||
if (statusResponse == null || statusResponse.getStatusCode() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
int statusCode = Integer.parseInt(statusResponse.getStatusCode());
|
||||
return statusCode >= 200 && statusCode < 300;
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,561 @@
|
||||
package com.banesco.common.application.service;
|
||||
|
||||
import com.banesco.common.application.usecase.HttpClientUseCase;
|
||||
import com.banesco.common.domain.exception.HttpApiResponseException;
|
||||
import com.banesco.common.domain.exception.HttpStatusCodeException;
|
||||
import com.banesco.common.domain.model.*;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.client.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@ApplicationScoped
|
||||
public class HttpClientService implements HttpClientUseCase {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@Inject
|
||||
public HttpClientService(ObjectMapper objectMapper) {
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T execute(HttpRequest request) {
|
||||
return executeRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, R> Either<T, R> executeEither(HttpRequest request) {
|
||||
return executeEitherInternal(request, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, R> Either<List<T>, R> executeEitherList(HttpRequest request) {
|
||||
return executeEitherInternal(request, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ApiResponse<T> executeApiResponse(HttpRequest request) {
|
||||
return executeRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ApiResponse<List<T>> executeApiResponseList(HttpRequest request) {
|
||||
return executeRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ApiPrivateResponse<Either<T, ApiPrivateError>> executeApiPrivateResponse(HttpRequest request) {
|
||||
return executeRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ApiPrivateResponse<Either<List<T>, ApiPrivateError>> executeApiPrivateResponseList(HttpRequest request) {
|
||||
return executeRequest(request);
|
||||
}
|
||||
|
||||
private <T, R> Either<T, R> executeEitherInternal(HttpRequest request, boolean isList) {
|
||||
try (Client client = createClient(request.getConnectTimeout(), request.getReadTimeout())) {
|
||||
WebTarget target = client.target(buildFinalUrl(request));
|
||||
Invocation.Builder builder = target.request(MediaType.APPLICATION_JSON);
|
||||
|
||||
if (request.getHeaders() != null) {
|
||||
request.getHeaders().forEach(builder::header);
|
||||
}
|
||||
|
||||
Response response = buildRequest(builder, request);
|
||||
return handleEitherResponse(request, response, isList);
|
||||
|
||||
} catch (HttpStatusCodeException | HttpApiResponseException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw handleConnectionError(request, e);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T executeRequest(HttpRequest request) {
|
||||
try (Client client = createClient(request.getConnectTimeout(), request.getReadTimeout())) {
|
||||
WebTarget target = client.target(buildFinalUrl(request));
|
||||
Invocation.Builder builder = target.request(MediaType.APPLICATION_JSON);
|
||||
|
||||
if (request.getHeaders() != null) {
|
||||
request.getHeaders().forEach(builder::header);
|
||||
}
|
||||
|
||||
Response response = buildRequest(builder, request);
|
||||
return handleResponse(request, response);
|
||||
} catch (HttpStatusCodeException | HttpApiResponseException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw handleConnectionError(request, e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T, R> Either<T, R> handleEitherResponse(HttpRequest request, Response response, boolean isList) {
|
||||
int statusCode = response.getStatus();
|
||||
|
||||
try (response) {
|
||||
String responseBody = response.readEntity(String.class);
|
||||
logResponse(request, statusCode, responseBody);
|
||||
|
||||
if (statusCode >= 200 && statusCode < 300) {
|
||||
Object successData = isList
|
||||
? parseSuccessListResponse(request, responseBody)
|
||||
: parseSuccessResponse(request, responseBody);
|
||||
return Either.left((T) successData);
|
||||
} else {
|
||||
logErrorResponse(request, statusCode, responseBody);
|
||||
R errorData = tryParseErrorResponse(request, responseBody);
|
||||
|
||||
if (errorData != null) {
|
||||
return Either.right(errorData);
|
||||
}
|
||||
|
||||
throw mapHttpStatusToException(statusCode, responseBody);
|
||||
}
|
||||
} catch (HttpStatusCodeException | HttpApiResponseException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw handleProcessingError(request, e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T parseSuccessResponse(HttpRequest request, String responseBody) throws JsonProcessingException {
|
||||
Type successType = extractSuccessType(request);
|
||||
|
||||
if (successType != null) {
|
||||
if (successType instanceof Class) {
|
||||
return objectMapper.readValue(responseBody, (Class<T>) successType);
|
||||
} else if (successType instanceof ParameterizedType) {
|
||||
JavaType javaType = objectMapper.getTypeFactory().constructType(successType);
|
||||
return objectMapper.readValue(responseBody, javaType);
|
||||
}
|
||||
}
|
||||
|
||||
if (request.getResponseType() != null && request.getResponseType() != Object.class) {
|
||||
return objectMapper.readValue(responseBody, objectMapper.getTypeFactory().constructType(request.getResponseType()));
|
||||
}
|
||||
|
||||
return (T) objectMapper.readValue(responseBody, Object.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> List<T> parseSuccessListResponse(HttpRequest request, String responseBody) throws JsonProcessingException {
|
||||
Type successType = extractSuccessType(request);
|
||||
|
||||
if (
|
||||
successType instanceof ParameterizedType paramType &&
|
||||
paramType.getRawType() == List.class &&
|
||||
paramType.getActualTypeArguments().length > 0
|
||||
) {
|
||||
Type elementType = paramType.getActualTypeArguments()[0];
|
||||
if (elementType instanceof Class) {
|
||||
JavaType javaType = objectMapper.getTypeFactory().constructCollectionType(
|
||||
List.class, (Class<T>) elementType
|
||||
);
|
||||
return objectMapper.readValue(responseBody, javaType);
|
||||
}
|
||||
}
|
||||
|
||||
return objectMapper.readValue(responseBody, List.class);
|
||||
}
|
||||
|
||||
private Type extractSuccessType(HttpRequest request) {
|
||||
if (
|
||||
request.getComplexType() != null &&
|
||||
request.getComplexType() instanceof ParameterizedType paramType &&
|
||||
paramType.getRawType() == Either.class &&
|
||||
paramType.getActualTypeArguments().length > 0
|
||||
) {
|
||||
return paramType.getActualTypeArguments()[0];
|
||||
}
|
||||
|
||||
if (request.getGenericType() != null) {
|
||||
return request.getGenericType();
|
||||
}
|
||||
|
||||
return request.getResponseType();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <R> R tryParseErrorResponse(HttpRequest request, String responseBody) {
|
||||
if (responseBody == null || responseBody.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
if (request.getErrorType() != null) {
|
||||
return (R) objectMapper.readValue(responseBody, request.getErrorType());
|
||||
}
|
||||
|
||||
if (request.getComplexType() != null && request.getComplexType() instanceof ParameterizedType paramType) {
|
||||
Type[] typeArgs = paramType.getActualTypeArguments();
|
||||
if (typeArgs.length >= 2 && typeArgs[1] instanceof Class) {
|
||||
return objectMapper.readValue(responseBody, (Class<R>) typeArgs[1]);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("No se pudo parsear la respuesta como error type: {}", e.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String buildFinalUrl(HttpRequest request) {
|
||||
String finalUrl = request.getUrl();
|
||||
|
||||
if (request.getPathParams() != null && !request.getPathParams().isEmpty()) {
|
||||
for (Map.Entry<String, String> entry : request.getPathParams().entrySet()) {
|
||||
String placeholder = "{" + entry.getKey() + "}";
|
||||
finalUrl = finalUrl.replace(placeholder, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
String url = appendQueryParams(finalUrl, request.getQueryParams());
|
||||
|
||||
log.info("Url Final: {}", url);
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
private String appendQueryParams(String url, Map<String, String> queryParams) {
|
||||
if (queryParams == null || queryParams.isEmpty()) {
|
||||
return url;
|
||||
}
|
||||
|
||||
StringBuilder urlBuilder = new StringBuilder(url);
|
||||
boolean firstParam = !url.contains("?");
|
||||
|
||||
for (Map.Entry<String, String> entry : queryParams.entrySet()) {
|
||||
if (firstParam) {
|
||||
urlBuilder.append("?");
|
||||
firstParam = false;
|
||||
} else {
|
||||
urlBuilder.append("&");
|
||||
}
|
||||
|
||||
String encodedKey = URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8);
|
||||
String encodedValue = entry.getValue() != null
|
||||
? URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8)
|
||||
: "";
|
||||
|
||||
urlBuilder.append(encodedKey).append("=").append(encodedValue);
|
||||
}
|
||||
|
||||
return urlBuilder.toString();
|
||||
}
|
||||
|
||||
private Response buildRequest(Invocation.Builder builder, HttpRequest request) {
|
||||
log.info("Metodo HTTP: {}", request.getMethod().name());
|
||||
|
||||
if(request.getBody() != null) {
|
||||
log.info("Peticion Cuerpo: {}", request.getBody());
|
||||
}
|
||||
|
||||
return switch (request.getMethod()) {
|
||||
case GET -> builder.get();
|
||||
case POST -> builder.post(Entity.entity(request.getBody(), MediaType.APPLICATION_JSON));
|
||||
case PUT -> builder.put(Entity.entity(request.getBody(), MediaType.APPLICATION_JSON));
|
||||
case DELETE -> builder.delete();
|
||||
case PATCH -> builder.method("PATCH", Entity.entity(request.getBody(), MediaType.APPLICATION_JSON));
|
||||
case HEAD -> builder.head();
|
||||
case OPTIONS -> builder.options();
|
||||
default -> throw new IllegalArgumentException("Metodo HTTP no soportado: " + request.getMethod());
|
||||
};
|
||||
}
|
||||
|
||||
private Client createClient(int connectTimeout, int readTimeout) {
|
||||
return ClientBuilder.newBuilder()
|
||||
.connectTimeout(connectTimeout, TimeUnit.MILLISECONDS)
|
||||
.readTimeout(readTimeout, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
}
|
||||
|
||||
private <T> T handleResponse(HttpRequest request, Response response) {
|
||||
int statusCode = response.getStatus();
|
||||
|
||||
try (response) {
|
||||
String responseBody = response.readEntity(String.class);
|
||||
logResponse(request, statusCode, responseBody);
|
||||
|
||||
if (statusCode >= 200 && statusCode < 300) {
|
||||
if (request.getResponseType() == Void.class || request.getResponseType() == void.class) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return responseResult(request, responseBody);
|
||||
} else {
|
||||
logErrorResponse(request, statusCode, responseBody);
|
||||
|
||||
if (isApiResponseFormat(responseBody)) {
|
||||
ApiResponse<?> apiResponse = deserializeApiResponse(responseBody, request);
|
||||
throw new HttpApiResponseException(statusCode, apiResponse);
|
||||
} else {
|
||||
throw mapHttpStatusToException(statusCode, responseBody);
|
||||
}
|
||||
}
|
||||
} catch (HttpStatusCodeException | HttpApiResponseException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw handleProcessingError(request, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void logResponse(HttpRequest request, int statusCode, String responseBody) {
|
||||
if (request.isLogResponseBody()) {
|
||||
log.info("Respuesta {} - Status: {}", request.getMethod(), statusCode);
|
||||
log.info("Respuesta Cuerpo: {}", responseBody);
|
||||
}
|
||||
}
|
||||
|
||||
private void logErrorResponse(HttpRequest request, int statusCode, String responseBody) {
|
||||
log.error(
|
||||
"Error HTTP {} {} - Status: {} - Body: {}",
|
||||
request.getMethod(),
|
||||
request.getUrl(),
|
||||
statusCode,
|
||||
responseBody
|
||||
);
|
||||
}
|
||||
|
||||
private HttpStatusCodeException handleConnectionError(HttpRequest request, Exception e) {
|
||||
log.error("Error de conexion {}: {}", request.getMethod(), e.getMessage());
|
||||
|
||||
return HttpStatusCodeException.serviceUnavailable(
|
||||
"503", "Error de conexion con el servicio externo: " + e.getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
private HttpStatusCodeException handleProcessingError(HttpRequest request, Exception e) {
|
||||
log.error(
|
||||
"Error procesando respuesta {} {}: {}",
|
||||
request.getMethod(),
|
||||
request.getUrl(),
|
||||
e.getMessage()
|
||||
);
|
||||
return HttpStatusCodeException.internalServer(
|
||||
"500", "Error procesando respuesta del servicio externo: " + e.getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
private <T> T responseResult(HttpRequest request, String responseBody) throws JsonProcessingException {
|
||||
if (request.isApiPrivateResponse() && request.isEitherResponse()) {
|
||||
return handleApiPrivateResponseWithEither(request, responseBody);
|
||||
}
|
||||
|
||||
if (request.getResponseType() == ApiResponse.class) {
|
||||
return deserializeApiResponse(responseBody, request);
|
||||
} else if (request.getComplexType() != null) {
|
||||
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(
|
||||
request.getResponseType(), objectMapper.getTypeFactory().constructType(request.getComplexType())
|
||||
);
|
||||
return objectMapper.readValue(responseBody, javaType);
|
||||
} else if (request.getGenericType() != null) {
|
||||
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(
|
||||
request.getResponseType(), objectMapper.getTypeFactory().constructType(request.getGenericType())
|
||||
);
|
||||
return objectMapper.readValue(responseBody, javaType);
|
||||
} else {
|
||||
return objectMapper.readValue(
|
||||
responseBody, objectMapper.getTypeFactory().constructType(request.getResponseType())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T handleApiPrivateResponseWithEither(HttpRequest request, String responseBody) throws JsonProcessingException {
|
||||
JsonNode rootNode = objectMapper.readTree(responseBody);
|
||||
String status = rootNode.has("estatus") ? rootNode.get("estatus").asText() : null;
|
||||
String message = rootNode.has("mensaje") ? rootNode.get("mensaje").asText() : null;
|
||||
JsonNode detailNode = rootNode.get("detalle");
|
||||
|
||||
if (request.getStatusSuccess().equals(status)) {
|
||||
return handleSuccessResponse(request, status, message, detailNode);
|
||||
} else {
|
||||
return handleErrorResponse(status, message, detailNode);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T handleSuccessResponse(HttpRequest request, String status, String message, JsonNode detailNode) {
|
||||
Object successData;
|
||||
|
||||
if (request.isListResponse()) {
|
||||
successData = handleListSuccess(request, detailNode);
|
||||
ApiPrivateResponse<Either<List<Object>, ApiPrivateError>> response = new ApiPrivateResponse<>();
|
||||
|
||||
response.setEstatus(status);
|
||||
response.setMensaje(message);
|
||||
response.setDetalle(Either.left((List<Object>) successData));
|
||||
return (T) response;
|
||||
} else {
|
||||
successData = handleObjectSuccess(request, detailNode);
|
||||
ApiPrivateResponse<Either<Object, ApiPrivateError>> response = new ApiPrivateResponse<>();
|
||||
|
||||
response.setEstatus(status);
|
||||
response.setMensaje(message);
|
||||
response.setDetalle(Either.left(successData));
|
||||
return (T) response;
|
||||
}
|
||||
}
|
||||
|
||||
private Object handleListSuccess(HttpRequest request, JsonNode detailNode) {
|
||||
Class<?> elementType = getElementTypeFromRequest(request);
|
||||
JavaType listType = objectMapper.getTypeFactory().constructCollectionType(List.class, elementType);
|
||||
|
||||
if (detailNode != null && !detailNode.isNull()) {
|
||||
return objectMapper.convertValue(detailNode, listType);
|
||||
}
|
||||
|
||||
return List.of();
|
||||
}
|
||||
|
||||
private Object handleObjectSuccess(HttpRequest request, JsonNode detailNode) {
|
||||
Class<?> elementType = getElementTypeFromRequest(request);
|
||||
|
||||
if (detailNode != null && !detailNode.isNull()) {
|
||||
return objectMapper.convertValue(detailNode, elementType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T handleErrorResponse(String status, String message, JsonNode detailNode) {
|
||||
ApiPrivateError error = buildApiPrivateError(detailNode, message);
|
||||
ApiPrivateResponse<Either<Object, ApiPrivateError>> response = new ApiPrivateResponse<>();
|
||||
|
||||
response.setEstatus(status);
|
||||
response.setMensaje(message);
|
||||
response.setDetalle(Either.right(error));
|
||||
|
||||
return (T) response;
|
||||
}
|
||||
|
||||
private ApiPrivateError buildApiPrivateError(JsonNode detailNode, String message) {
|
||||
if (detailNode != null && !detailNode.isNull()) {
|
||||
try {
|
||||
return objectMapper.convertValue(detailNode, ApiPrivateError.class);
|
||||
} catch (Exception e) {
|
||||
log.warn("Cannot map detail to ApiPrivateError, creating default error. Detail: {}", detailNode);
|
||||
}
|
||||
}
|
||||
|
||||
return ApiPrivateError.builder()
|
||||
.codError(null)
|
||||
.mensajeError(message)
|
||||
.constraintName(null)
|
||||
.build();
|
||||
}
|
||||
|
||||
private Class<?> getElementTypeFromRequest(HttpRequest request) {
|
||||
if (request.getGenericType() != null) {
|
||||
return request.getGenericType();
|
||||
}
|
||||
|
||||
if (request.getComplexType() instanceof ParameterizedType pt) {
|
||||
Type[] typeArgs = pt.getActualTypeArguments();
|
||||
|
||||
if (typeArgs.length > 0) {
|
||||
Type firstArg = typeArgs[0];
|
||||
|
||||
if (firstArg instanceof ParameterizedType innerPt) {
|
||||
Type[] innerArgs = innerPt.getActualTypeArguments();
|
||||
|
||||
if (innerArgs.length > 0 && innerArgs[0] instanceof Class<?> innerClass) {
|
||||
return innerClass;
|
||||
}
|
||||
} else if (firstArg instanceof Class<?> elementClass) {
|
||||
return elementClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.warn("No se pudo determinar el elementType del request, usando Object.class");
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T deserializeApiResponse(String responseBody, HttpRequest request) {
|
||||
try {
|
||||
if (request.getGenericType() != null) {
|
||||
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(
|
||||
ApiResponse.class, objectMapper.getTypeFactory().constructType(request.getGenericType())
|
||||
);
|
||||
return objectMapper.readValue(responseBody, javaType);
|
||||
} else {
|
||||
return (T) objectMapper.readValue(responseBody, ApiResponse.class);
|
||||
}
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error("Error deserializando respuesta JSON: {}", e.getMessage());
|
||||
throw HttpStatusCodeException.internalServer(
|
||||
"500", "Error deserializando respuesta JSON: " + e.getMessage()
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.error("Error desconocido al deserializar respuesta: {}", e.getMessage());
|
||||
throw HttpStatusCodeException.internalServer(
|
||||
"500", "Error desconocido al deserializar respuesta: " + e.getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isApiResponseFormat(String responseBody) {
|
||||
try {
|
||||
if (responseBody == null || responseBody.trim().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return responseBody.contains("\"data\"") &&
|
||||
responseBody.contains("\"statusResponse\"") &&
|
||||
responseBody.contains("\"statusCode\"") &&
|
||||
responseBody.contains("\"message\"");
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private HttpStatusCodeException mapHttpStatusToException(int statusCode, String errorBody) {
|
||||
String errorCode = "HTTP_" + statusCode;
|
||||
String defaultMessage = "Error en servicio externo: HTTP " + statusCode;
|
||||
String message = errorBody != null && !errorBody.isEmpty()
|
||||
? errorBody
|
||||
: defaultMessage;
|
||||
|
||||
return switch (statusCode) {
|
||||
case 400 -> HttpStatusCodeException.badRequest(errorCode, message);
|
||||
case 401 -> HttpStatusCodeException.unauthorized(errorCode, message);
|
||||
case 403 -> HttpStatusCodeException.forbidden(errorCode, message);
|
||||
case 404 -> HttpStatusCodeException.notFound(errorCode, message);
|
||||
case 405 -> HttpStatusCodeException.methodNotAllowed(errorCode, message);
|
||||
case 408 -> HttpStatusCodeException.fromStatusCode(408, errorCode, message);
|
||||
case 409 -> HttpStatusCodeException.conflict(errorCode, message);
|
||||
case 410 -> HttpStatusCodeException.gone(errorCode, message);
|
||||
case 412 -> HttpStatusCodeException.preconditionFailed(errorCode, message);
|
||||
case 415 -> HttpStatusCodeException.unsupportedMediaType(errorCode, message);
|
||||
case 422 -> HttpStatusCodeException.unprocessableEntity(errorCode, message);
|
||||
case 429 -> HttpStatusCodeException.tooManyRequests(errorCode, message);
|
||||
case 500 -> HttpStatusCodeException.internalServer(errorCode, message);
|
||||
case 501 -> HttpStatusCodeException.notImplemented(errorCode, message);
|
||||
case 502 -> HttpStatusCodeException.badGateway(errorCode, message);
|
||||
case 503 -> HttpStatusCodeException.serviceUnavailable(errorCode, message);
|
||||
case 504 -> HttpStatusCodeException.gatewayTimeout(errorCode, message);
|
||||
default -> HttpStatusCodeException.fromStatusCode(statusCode, errorCode, message);
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.banesco.common.application.usecase;
|
||||
|
||||
import com.banesco.common.domain.model.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface HttpClientUseCase {
|
||||
|
||||
<T> T execute(HttpRequest request);
|
||||
|
||||
<T, R> Either<T, R> executeEither(HttpRequest request);
|
||||
|
||||
<T, R> Either<List<T>, R> executeEitherList(HttpRequest request);
|
||||
|
||||
<T> ApiResponse<T> executeApiResponse(HttpRequest request);
|
||||
|
||||
<T> ApiResponse<List<T>> executeApiResponseList(HttpRequest request);
|
||||
|
||||
<T> ApiPrivateResponse<Either<T, ApiPrivateError>> executeApiPrivateResponse(HttpRequest request);
|
||||
|
||||
<T> ApiPrivateResponse<Either<List<T>, ApiPrivateError>> executeApiPrivateResponseList(HttpRequest request);
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package com.banesco.common.domain.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public abstract class BaseApiException extends RuntimeException {
|
||||
private final String errorCode;
|
||||
private final String fieldPath;
|
||||
private final String exceptionType;
|
||||
|
||||
protected BaseApiException(String errorCode, String message, String fieldPath, String exceptionType) {
|
||||
super(message);
|
||||
this.errorCode = errorCode;
|
||||
this.fieldPath = fieldPath;
|
||||
this.exceptionType = exceptionType;
|
||||
}
|
||||
|
||||
protected BaseApiException(String errorCode, String fieldPath, String exceptionType) {
|
||||
this(errorCode, null, fieldPath, exceptionType);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.banesco.common.domain.exception;
|
||||
|
||||
import com.banesco.common.domain.model.ApiResponse;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class HttpApiResponseException extends RuntimeException {
|
||||
private final int statusCode;
|
||||
private final transient ApiResponse<?> apiResponse;
|
||||
|
||||
public HttpApiResponseException(int statusCode, ApiResponse<?> apiResponse) {
|
||||
super(String.format(
|
||||
"HTTP %d: %s", statusCode,
|
||||
apiResponse.getStatusResponse() != null ?
|
||||
apiResponse.getStatusResponse().getMessage() : "Error sin mensaje"
|
||||
));
|
||||
this.statusCode = statusCode;
|
||||
this.apiResponse = apiResponse;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.banesco.common.domain.exception;
|
||||
|
||||
public class HttpClientException extends RuntimeException {
|
||||
public HttpClientException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public HttpClientException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,320 @@
|
||||
package com.banesco.common.domain.exception;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
public class HttpStatusCodeException extends BaseApiException {
|
||||
private final int statusCode;
|
||||
|
||||
private static final Map<Integer, String> STATUS_CATEGORIES = new HashMap<>();
|
||||
|
||||
static {
|
||||
STATUS_CATEGORIES.put(100, "continue");
|
||||
STATUS_CATEGORIES.put(101, "switching-protocols");
|
||||
STATUS_CATEGORIES.put(102, "processing");
|
||||
STATUS_CATEGORIES.put(103, "early-hints");
|
||||
STATUS_CATEGORIES.put(200, "ok");
|
||||
STATUS_CATEGORIES.put(201, "created");
|
||||
STATUS_CATEGORIES.put(202, "accepted");
|
||||
STATUS_CATEGORIES.put(203, "non-authoritative-information");
|
||||
STATUS_CATEGORIES.put(204, "no-content");
|
||||
STATUS_CATEGORIES.put(205, "reset-content");
|
||||
STATUS_CATEGORIES.put(206, "partial-content");
|
||||
STATUS_CATEGORIES.put(207, "multi-status");
|
||||
STATUS_CATEGORIES.put(208, "already-reported");
|
||||
STATUS_CATEGORIES.put(226, "im-used");
|
||||
STATUS_CATEGORIES.put(300, "multiple-choices");
|
||||
STATUS_CATEGORIES.put(301, "moved-permanently");
|
||||
STATUS_CATEGORIES.put(302, "found");
|
||||
STATUS_CATEGORIES.put(303, "see-other");
|
||||
STATUS_CATEGORIES.put(304, "not-modified");
|
||||
STATUS_CATEGORIES.put(305, "use-proxy");
|
||||
STATUS_CATEGORIES.put(307, "temporary-redirect");
|
||||
STATUS_CATEGORIES.put(308, "permanent-redirect");
|
||||
STATUS_CATEGORIES.put(400, "bad-request");
|
||||
STATUS_CATEGORIES.put(401, "unauthorized");
|
||||
STATUS_CATEGORIES.put(402, "payment-required");
|
||||
STATUS_CATEGORIES.put(403, "forbidden");
|
||||
STATUS_CATEGORIES.put(404, "not-found");
|
||||
STATUS_CATEGORIES.put(405, "method-not-allowed");
|
||||
STATUS_CATEGORIES.put(406, "not-acceptable");
|
||||
STATUS_CATEGORIES.put(407, "proxy-authentication-required");
|
||||
STATUS_CATEGORIES.put(408, "request-timeout");
|
||||
STATUS_CATEGORIES.put(409, "conflict");
|
||||
STATUS_CATEGORIES.put(410, "gone");
|
||||
STATUS_CATEGORIES.put(411, "length-required");
|
||||
STATUS_CATEGORIES.put(412, "precondition-failed");
|
||||
STATUS_CATEGORIES.put(413, "payload-too-large");
|
||||
STATUS_CATEGORIES.put(414, "uri-too-long");
|
||||
STATUS_CATEGORIES.put(415, "unsupported-media-type");
|
||||
STATUS_CATEGORIES.put(416, "range-not-satisfiable");
|
||||
STATUS_CATEGORIES.put(417, "expectation-failed");
|
||||
STATUS_CATEGORIES.put(418, "im-a-teapot");
|
||||
STATUS_CATEGORIES.put(421, "misdirected-request");
|
||||
STATUS_CATEGORIES.put(422, "unprocessable-entity");
|
||||
STATUS_CATEGORIES.put(423, "locked");
|
||||
STATUS_CATEGORIES.put(424, "failed-dependency");
|
||||
STATUS_CATEGORIES.put(425, "too-early");
|
||||
STATUS_CATEGORIES.put(426, "upgrade-required");
|
||||
STATUS_CATEGORIES.put(428, "precondition-required");
|
||||
STATUS_CATEGORIES.put(429, "too-many-requests");
|
||||
STATUS_CATEGORIES.put(431, "request-header-fields-too-large");
|
||||
STATUS_CATEGORIES.put(451, "unavailable-for-legal-reasons");
|
||||
STATUS_CATEGORIES.put(500, "internal-server-error");
|
||||
STATUS_CATEGORIES.put(501, "not-implemented");
|
||||
STATUS_CATEGORIES.put(502, "bad-gateway");
|
||||
STATUS_CATEGORIES.put(503, "service-unavailable");
|
||||
STATUS_CATEGORIES.put(504, "gateway-timeout");
|
||||
STATUS_CATEGORIES.put(505, "http-version-not-supported");
|
||||
STATUS_CATEGORIES.put(506, "variant-also-negotiates");
|
||||
STATUS_CATEGORIES.put(507, "insufficient-storage");
|
||||
STATUS_CATEGORIES.put(508, "loop-detected");
|
||||
STATUS_CATEGORIES.put(510, "not-extended");
|
||||
STATUS_CATEGORIES.put(511, "network-authentication-required");
|
||||
}
|
||||
|
||||
public HttpStatusCodeException(int statusCode, String errorCode, String message, String fieldPath) {
|
||||
super(errorCode, message, fieldPath, getHttpStatusCategory(statusCode));
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
public HttpStatusCodeException(int statusCode, String errorCode, String message) {
|
||||
this(statusCode, errorCode, message, null);
|
||||
}
|
||||
|
||||
public HttpStatusCodeException(int statusCode, String errorCode) {
|
||||
this(statusCode, errorCode, getDefaultMessage(statusCode), null);
|
||||
}
|
||||
|
||||
public HttpStatusCodeException(int statusCode) {
|
||||
this(statusCode, "HTTP_" + statusCode);
|
||||
}
|
||||
|
||||
private static String getHttpStatusCategory(int statusCode) {
|
||||
String category = STATUS_CATEGORIES.get(statusCode);
|
||||
|
||||
if (category != null) {
|
||||
return category;
|
||||
}
|
||||
|
||||
if (statusCode >= 100 && statusCode < 200) return "informational";
|
||||
if (statusCode >= 200 && statusCode < 300) return "success";
|
||||
if (statusCode >= 300 && statusCode < 400) return "redirection";
|
||||
if (statusCode >= 400 && statusCode < 500) return "client-error";
|
||||
if (statusCode >= 500 && statusCode < 600) return "server-error";
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
private static String getDefaultMessage(int statusCode) {
|
||||
return switch (statusCode) {
|
||||
case 200 -> "OK";
|
||||
case 201 -> "Created";
|
||||
case 202 -> "Accepted";
|
||||
case 204 -> "No Content";
|
||||
case 400 -> "Bad Request";
|
||||
case 401 -> "Unauthorized";
|
||||
case 403 -> "Forbidden";
|
||||
case 404 -> "Not Found";
|
||||
case 405 -> "Method Not Allowed";
|
||||
case 408 -> "Request Timeout";
|
||||
case 409 -> "Conflict";
|
||||
case 410 -> "Gone";
|
||||
case 422 -> "Unprocessable Entity";
|
||||
case 429 -> "Too Many Requests";
|
||||
case 500 -> "Internal Server Error";
|
||||
case 502 -> "Bad Gateway";
|
||||
case 503 -> "Service Unavailable";
|
||||
case 504 -> "Gateway Timeout";
|
||||
default -> "HTTP " + statusCode;
|
||||
};
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException badRequest(String errorCode) {
|
||||
return new HttpStatusCodeException(400, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException badRequest(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(400, errorCode, getDefaultMessage(400), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException unauthorized(String errorCode) {
|
||||
return new HttpStatusCodeException(401, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException unauthorized(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(401, errorCode, getDefaultMessage(401), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException forbidden(String errorCode) {
|
||||
return new HttpStatusCodeException(403, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException forbidden(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(403, errorCode, getDefaultMessage(403), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException notFound(String errorCode) {
|
||||
return new HttpStatusCodeException(404, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException notFound(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(404, errorCode, getDefaultMessage(404), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException methodNotAllowed(String errorCode) {
|
||||
return new HttpStatusCodeException(405, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException methodNotAllowed(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(405, errorCode, getDefaultMessage(405), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException conflict(String errorCode) {
|
||||
return new HttpStatusCodeException(409, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException conflict(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(409, errorCode, getDefaultMessage(409), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException unprocessableEntity(String errorCode) {
|
||||
return new HttpStatusCodeException(422, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException unprocessableEntity(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(422, errorCode, getDefaultMessage(422), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException tooManyRequests(String errorCode) {
|
||||
return new HttpStatusCodeException(429, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException tooManyRequests(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(429, errorCode, getDefaultMessage(429), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException internalServer(String errorCode) {
|
||||
return new HttpStatusCodeException(500, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException internalServer(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(500, errorCode, getDefaultMessage(500), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException badGateway(String errorCode) {
|
||||
return new HttpStatusCodeException(502, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException badGateway(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(502, errorCode, getDefaultMessage(502), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException serviceUnavailable(String errorCode) {
|
||||
return new HttpStatusCodeException(503, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException serviceUnavailable(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(503, errorCode, getDefaultMessage(503), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException gatewayTimeout(String errorCode) {
|
||||
return new HttpStatusCodeException(504, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException gatewayTimeout(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(504, errorCode, getDefaultMessage(504), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException paymentRequired(String errorCode) {
|
||||
return new HttpStatusCodeException(402, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException paymentRequired(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(402, errorCode, getDefaultMessage(402), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException gone(String errorCode) {
|
||||
return new HttpStatusCodeException(410, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException gone(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(410, errorCode, getDefaultMessage(410), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException preconditionFailed(String errorCode) {
|
||||
return new HttpStatusCodeException(412, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException preconditionFailed(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(412, errorCode, getDefaultMessage(412), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException unsupportedMediaType(String errorCode) {
|
||||
return new HttpStatusCodeException(415, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException unsupportedMediaType(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(415, errorCode, getDefaultMessage(415), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException notImplemented(String errorCode) {
|
||||
return new HttpStatusCodeException(501, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException notImplemented(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(501, errorCode, getDefaultMessage(501), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException ok(String errorCode) {
|
||||
return new HttpStatusCodeException(200, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException ok(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(200, errorCode, getDefaultMessage(200), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException created(String errorCode) {
|
||||
return new HttpStatusCodeException(201, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException created(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(201, errorCode, getDefaultMessage(201), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException accepted(String errorCode) {
|
||||
return new HttpStatusCodeException(202, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException accepted(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(202, errorCode, getDefaultMessage(202), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException noContent(String errorCode) {
|
||||
return new HttpStatusCodeException(204, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException noContent(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(204, errorCode, getDefaultMessage(204), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException requestTimeout(String errorCode) {
|
||||
return new HttpStatusCodeException(408, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException requestTimeout(String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(408, errorCode, getDefaultMessage(408), fieldPath);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException fromStatusCode(int statusCode, String errorCode) {
|
||||
return new HttpStatusCodeException(statusCode, errorCode);
|
||||
}
|
||||
|
||||
public static HttpStatusCodeException fromStatusCode(int statusCode, String errorCode, String fieldPath) {
|
||||
return new HttpStatusCodeException(statusCode, errorCode, getDefaultMessage(statusCode), fieldPath);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.banesco.common.domain.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class ApiPrivateError {
|
||||
private Long codError;
|
||||
private String mensajeError;
|
||||
private String constraintName;
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.banesco.common.domain.model;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ApiPrivateResponse<T> {
|
||||
private String estatus;
|
||||
private String mensaje;
|
||||
private T detalle;
|
||||
private String codeline;
|
||||
private String __equalsCalc;
|
||||
private Boolean __hashCodeCalc;
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.banesco.common.domain.model;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ApiResponse<T> {
|
||||
private T data;
|
||||
private StatusResponse statusResponse;
|
||||
|
||||
public ApiResponse(StatusResponse statusResponse) {
|
||||
this.statusResponse = statusResponse;
|
||||
this.data = null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.banesco.common.domain.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class BankService {
|
||||
private String bankCode;
|
||||
private String serviceCode;
|
||||
private String eventCode;
|
||||
}
|
||||
17
src/main/java/com/banesco/common/domain/model/Device.java
Normal file
17
src/main/java/com/banesco/common/domain/model/Device.java
Normal file
@ -0,0 +1,17 @@
|
||||
package com.banesco.common.domain.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class Device {
|
||||
private String deviceType;
|
||||
private String deviceDescription;
|
||||
private String deviceIp;
|
||||
private String deviceSessionReference;
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.banesco.common.domain.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@RegisterForReflection
|
||||
public class DomainConfig {
|
||||
private String url;
|
||||
private TimeoutConfig timeout;
|
||||
}
|
||||
33
src/main/java/com/banesco/common/domain/model/Either.java
Normal file
33
src/main/java/com/banesco/common/domain/model/Either.java
Normal file
@ -0,0 +1,33 @@
|
||||
package com.banesco.common.domain.model;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class Either<L, R> {
|
||||
private final L left;
|
||||
private final R right;
|
||||
|
||||
private final boolean leftFlag;
|
||||
|
||||
private Either(L left, R right, boolean leftFlag) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.leftFlag = leftFlag;
|
||||
}
|
||||
|
||||
public static <L, R> Either<L, R> left(L left) {
|
||||
return new Either<>(left, null, true);
|
||||
}
|
||||
|
||||
public static <L, R> Either<L, R> right(R right) {
|
||||
return new Either<>(null, right, false);
|
||||
}
|
||||
|
||||
public boolean isLeft() {
|
||||
return leftFlag;
|
||||
}
|
||||
|
||||
public boolean isRight() {
|
||||
return !leftFlag;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.banesco.common.domain.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@ToString
|
||||
@RegisterForReflection
|
||||
public class ErrorMapping {
|
||||
@JsonProperty("backendCode")
|
||||
String backendCode;
|
||||
@JsonProperty("httpCode")
|
||||
int httpCode;
|
||||
@JsonProperty("statusCode")
|
||||
String statusCode;
|
||||
@JsonProperty("description")
|
||||
String description;
|
||||
}
|
||||
223
src/main/java/com/banesco/common/domain/model/HttpRequest.java
Normal file
223
src/main/java/com/banesco/common/domain/model/HttpRequest.java
Normal file
@ -0,0 +1,223 @@
|
||||
package com.banesco.common.domain.model;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class HttpRequest {
|
||||
private String url;
|
||||
private HttpMethod method;
|
||||
private Object body;
|
||||
private Map<String, String> headers;
|
||||
private Map<String, String> queryParams;
|
||||
private Map<String, String> pathParams;
|
||||
|
||||
@Builder.Default
|
||||
private Class<?> responseType = Object.class;
|
||||
|
||||
private Class<?> genericType;
|
||||
|
||||
private Type complexType;
|
||||
|
||||
private Class<?> errorType;
|
||||
|
||||
private String statusSuccess;
|
||||
|
||||
@Builder.Default
|
||||
private boolean eitherResponse = false;
|
||||
|
||||
@Builder.Default
|
||||
private boolean apiPrivateResponse = false;
|
||||
|
||||
@Builder.Default
|
||||
private boolean apiResponse = false;
|
||||
|
||||
@Builder.Default
|
||||
private boolean listResponse = false;
|
||||
|
||||
@Builder.Default
|
||||
private int connectTimeout = 5000;
|
||||
|
||||
@Builder.Default
|
||||
private int readTimeout = 10000;
|
||||
|
||||
@Builder.Default
|
||||
private boolean returnFullResponse = false;
|
||||
|
||||
@Builder.Default
|
||||
private boolean logRequestBody = true;
|
||||
|
||||
@Builder.Default
|
||||
private boolean logResponseBody = true;
|
||||
|
||||
public static <T> HttpRequest forApiResponse(
|
||||
String url,
|
||||
HttpMethod method,
|
||||
Class<T> dataType
|
||||
) {
|
||||
return HttpRequest.builder()
|
||||
.url(url)
|
||||
.method(method)
|
||||
.responseType(ApiResponse.class)
|
||||
.genericType(dataType)
|
||||
.apiResponse(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> HttpRequest forApiResponseList(
|
||||
String url,
|
||||
HttpMethod method,
|
||||
Class<T> elementType
|
||||
) {
|
||||
return HttpRequest.builder()
|
||||
.url(url)
|
||||
.method(method)
|
||||
.responseType(ApiResponse.class)
|
||||
.complexType(TypeBuilder.listOf(elementType))
|
||||
.apiResponse(true)
|
||||
.listResponse(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> HttpRequest forApiPrivateResponse(
|
||||
String url,
|
||||
String statusSuccess,
|
||||
HttpMethod method,
|
||||
Class<T> successType
|
||||
) {
|
||||
return HttpRequest.builder()
|
||||
.url(url)
|
||||
.method(method)
|
||||
.responseType(ApiPrivateResponse.class)
|
||||
.complexType(TypeBuilder.parametricType(
|
||||
Either.class,
|
||||
successType,
|
||||
ApiPrivateError.class
|
||||
))
|
||||
.apiPrivateResponse(true)
|
||||
.eitherResponse(true)
|
||||
.errorType(ApiPrivateError.class)
|
||||
.statusSuccess(statusSuccess)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> HttpRequest forApiPrivateResponseList(
|
||||
String url,
|
||||
String statusSuccess,
|
||||
HttpMethod method,
|
||||
Class<T> elementType
|
||||
) {
|
||||
return HttpRequest.builder()
|
||||
.url(url)
|
||||
.method(method)
|
||||
.responseType(ApiPrivateResponse.class)
|
||||
.complexType(TypeBuilder.parametricType(
|
||||
Either.class,
|
||||
TypeBuilder.listOf(elementType),
|
||||
ApiPrivateError.class
|
||||
))
|
||||
.apiPrivateResponse(true)
|
||||
.eitherResponse(true)
|
||||
.listResponse(true)
|
||||
.errorType(ApiPrivateError.class)
|
||||
.statusSuccess(statusSuccess)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> HttpRequest forDirectResponse(
|
||||
String url,
|
||||
HttpMethod method,
|
||||
Class<T> responseType
|
||||
) {
|
||||
return HttpRequest.builder()
|
||||
.url(url)
|
||||
.method(method)
|
||||
.responseType(responseType)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T, U> HttpRequest forGenericResponse(
|
||||
String url,
|
||||
HttpMethod method,
|
||||
Class<T> rawType,
|
||||
Class<U> genericType
|
||||
) {
|
||||
return HttpRequest.builder()
|
||||
.url(url)
|
||||
.method(method)
|
||||
.responseType(rawType)
|
||||
.complexType(TypeBuilder.parametricType(rawType, genericType))
|
||||
.build();
|
||||
}
|
||||
|
||||
public HttpRequest withHeaders(Map<String, String> headers) {
|
||||
this.headers = headers;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpRequest withQueryParams(Map<String, String> queryParams) {
|
||||
this.queryParams = queryParams;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpRequest withPathParams(Map<String, String> pathParams) {
|
||||
this.pathParams = pathParams;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpRequest withBody(Object body) {
|
||||
this.body = body;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpRequest withTimeout(int connectTimeout, int readTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
this.readTimeout = readTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpRequest disableRequestLogging() {
|
||||
this.logRequestBody = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpRequest disableResponseLogging() {
|
||||
this.logResponseBody = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ResponseType getExpectedResponseType() {
|
||||
if (apiPrivateResponse && eitherResponse) {
|
||||
return listResponse ? ResponseType.API_PRIVATE_WITH_EITHER_LIST : ResponseType.API_PRIVATE_WITH_EITHER;
|
||||
} else if (apiResponse) {
|
||||
return listResponse ? ResponseType.API_RESPONSE_LIST : ResponseType.API_RESPONSE;
|
||||
} else if (complexType != null) {
|
||||
return ResponseType.COMPLEX_TYPE;
|
||||
} else if (genericType != null) {
|
||||
return ResponseType.GENERIC_TYPE;
|
||||
} else {
|
||||
return ResponseType.DIRECT_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ResponseType {
|
||||
API_RESPONSE,
|
||||
API_RESPONSE_LIST,
|
||||
API_PRIVATE_WITH_EITHER,
|
||||
API_PRIVATE_WITH_EITHER_LIST,
|
||||
GENERIC_TYPE,
|
||||
COMPLEX_TYPE,
|
||||
DIRECT_TYPE
|
||||
}
|
||||
|
||||
public enum HttpMethod {
|
||||
GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.banesco.common.domain.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class Identifier {
|
||||
private String identifierValue;
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.banesco.common.domain.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class StatusResponse {
|
||||
private String statusCode;
|
||||
private String message;
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.banesco.common.domain.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@RegisterForReflection
|
||||
public class TimeoutConfig {
|
||||
private int connect;
|
||||
private int response;
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
package com.banesco.common.domain.model;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class TypeBuilder {
|
||||
|
||||
private TypeBuilder() {}
|
||||
|
||||
public static Type listOf(Class<?> elementType) {
|
||||
return new ParameterizedType() {
|
||||
@Override
|
||||
public Type[] getActualTypeArguments() {
|
||||
return new Type[]{elementType};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getRawType() {
|
||||
return java.util.List.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getOwnerType() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Type parametricType(Class<?> rawType, Type... typeArguments) {
|
||||
return new ParameterizedType() {
|
||||
@Override
|
||||
public Type[] getActualTypeArguments() {
|
||||
return typeArguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getRawType() {
|
||||
return rawType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getOwnerType() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Type apiPrivateResponseWithEither(Class<?> successType, Class<?> errorType) {
|
||||
Type eitherType = parametricType(Either.class, successType, errorType);
|
||||
return parametricType(ApiPrivateResponse.class, eitherType);
|
||||
}
|
||||
|
||||
public static Type apiPrivateResponseWithListEither(Class<?> successType, Class<?> errorType) {
|
||||
Type listType = listOf(successType);
|
||||
Type eitherType = parametricType(Either.class, listType, errorType);
|
||||
return parametricType(ApiPrivateResponse.class, eitherType);
|
||||
}
|
||||
|
||||
public static Type apiResponseType(Class<?> dataType) {
|
||||
return parametricType(ApiResponse.class, dataType);
|
||||
}
|
||||
|
||||
public static Type apiResponseListType(Class<?> elementType) {
|
||||
Type listType = listOf(elementType);
|
||||
return parametricType(ApiResponse.class, listType);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.banesco.common.infrastructure.config;
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import org.eclipse.microprofile.config.Config;
|
||||
|
||||
@ApplicationScoped
|
||||
@Getter
|
||||
public class MessagesConfig {
|
||||
|
||||
private final boolean readFromProps;
|
||||
private final String errorMessagesJson;
|
||||
private final String messagesKey;
|
||||
|
||||
private static final String KEY = "bus-retrieve-security-notification";
|
||||
|
||||
@Inject
|
||||
public MessagesConfig(Config config) {
|
||||
this.readFromProps = config.getValue("api.read-messages.from-props", Boolean.class);
|
||||
this.errorMessagesJson = config.getValue("api." + KEY + ".messages.content", String.class);
|
||||
this.messagesKey = config.getValue("api." + KEY + ".messages.key", String.class);
|
||||
}
|
||||
|
||||
public String getErrorMessagesJson() {
|
||||
if (readFromProps) {
|
||||
return errorMessagesJson != null ? errorMessagesJson : "";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
package com.banesco.common.infrastructure.config;
|
||||
|
||||
import com.banesco.common.domain.model.DomainConfig;
|
||||
import com.banesco.module.security_trace.domain.model.SecurityTraceConfig;
|
||||
import com.banesco.module.service_status.domain.model.ServiceStatusConfig;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.microprofile.config.Config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@ApplicationScoped
|
||||
@RegisterForReflection
|
||||
public class RestClientConfig {
|
||||
|
||||
private final Config config;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
private static final String API_BASE = "api.rest-client.";
|
||||
private static final String API_DOMAIN_NAME = "dom-retrieve-security-notification";
|
||||
private static final String API_SECURITY_TRACE_NAME = "security-trace";
|
||||
private static final String API_SERVICE_STATUS_NAME = "service-status";
|
||||
|
||||
@Inject
|
||||
public RestClientConfig(
|
||||
Config config,
|
||||
ObjectMapper objectMapper
|
||||
) {
|
||||
this.config = config;
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
public DomainConfig getDomServiceIssueConfig() {
|
||||
return getConfig(API_DOMAIN_NAME, DomainConfig.class);
|
||||
}
|
||||
|
||||
public SecurityTraceConfig getSecurityTraceConfig() {
|
||||
return getConfig(API_SECURITY_TRACE_NAME, SecurityTraceConfig.class);
|
||||
}
|
||||
|
||||
public ServiceStatusConfig getServiceStatusConfig() {
|
||||
return getConfig(API_SERVICE_STATUS_NAME, ServiceStatusConfig.class);
|
||||
}
|
||||
|
||||
private <T> T getConfig(
|
||||
String configName,
|
||||
Class<T> configType
|
||||
) {
|
||||
try {
|
||||
String fullConfigName = API_BASE + configName;
|
||||
String json = config.getValue(fullConfigName, String.class);
|
||||
log.info("Configurando {}: {}", fullConfigName, json);
|
||||
|
||||
if (json == null || json.trim().isEmpty()) {
|
||||
throw new IllegalStateException("Configuracion no encontrada para: " + fullConfigName);
|
||||
}
|
||||
|
||||
Map<String, Object> configMap = objectMapper.readValue(json, new TypeReference<>() {});
|
||||
return objectMapper.convertValue(configMap, configType);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new IllegalArgumentException("Formato JSON invalido para " + configName + ": " + e.getMessage(), e);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Error cargando configuracion del servicio " + configName + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public String toJsonString(Object object) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(object);
|
||||
} catch (Exception e) {
|
||||
log.error("Error al convertir a json string: {}", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.banesco.common.infrastructure.context;
|
||||
|
||||
import org.slf4j.MDC;
|
||||
|
||||
public class RequestContext {
|
||||
|
||||
private RequestContext() {}
|
||||
|
||||
public static final String REQUEST_ID = "requestId";
|
||||
public static final String DEVICE = "device";
|
||||
public static final String DEVICE_SESSION_REFERENCE = "deviceSessionReference";
|
||||
|
||||
public static String getRequestId() {
|
||||
return MDC.get(REQUEST_ID);
|
||||
}
|
||||
|
||||
public static void setRequestId(String requestId) {
|
||||
MDC.put(REQUEST_ID, requestId);
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
MDC.remove(REQUEST_ID);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
package com.banesco.common.infrastructure.filter;
|
||||
|
||||
import com.banesco.common.infrastructure.context.RequestContext;
|
||||
import jakarta.ws.rs.container.ContainerRequestContext;
|
||||
import jakarta.ws.rs.container.ContainerRequestFilter;
|
||||
import jakarta.ws.rs.container.ContainerResponseContext;
|
||||
import jakarta.ws.rs.container.ContainerResponseFilter;
|
||||
import jakarta.ws.rs.ext.Provider;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.UUID;
|
||||
|
||||
@Slf4j
|
||||
@Provider
|
||||
public class RequestIdFilter implements ContainerRequestFilter, ContainerResponseFilter {
|
||||
|
||||
@Override
|
||||
public void filter(ContainerRequestContext requestContext) {
|
||||
String requestId = requestContext.getHeaderString(RequestContext.DEVICE_SESSION_REFERENCE);
|
||||
|
||||
if (isEmpty(requestId)) {
|
||||
requestId = requestContext.getUriInfo()
|
||||
.getQueryParameters()
|
||||
.getFirst(RequestContext.DEVICE_SESSION_REFERENCE);
|
||||
}
|
||||
|
||||
if (isEmpty(requestId) && hasJsonBody(requestContext)) {
|
||||
requestId = extractRequestIdFromBody(requestContext);
|
||||
}
|
||||
|
||||
if (isEmpty(requestId)) {
|
||||
requestId = UUID.randomUUID().toString().substring(0, 13);
|
||||
}
|
||||
|
||||
RequestContext.setRequestId(requestId);
|
||||
}
|
||||
|
||||
private boolean isEmpty(String value) {
|
||||
return value == null || value.trim().isEmpty();
|
||||
}
|
||||
|
||||
private boolean hasJsonBody(ContainerRequestContext context) {
|
||||
try {
|
||||
String method = context.getMethod();
|
||||
String contentType = context.getHeaderString("Content-Type");
|
||||
|
||||
return ("POST".equals(method) || "PUT".equals(method))
|
||||
&& contentType != null
|
||||
&& contentType.contains("application/json");
|
||||
} catch (Exception e) {
|
||||
log.warn("La peticion no es un POST o PUT: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private String extractRequestIdFromBody(ContainerRequestContext context) {
|
||||
try {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
context.getEntityStream().transferTo(buffer);
|
||||
byte[] bodyBytes = buffer.toByteArray();
|
||||
|
||||
context.setEntityStream(new ByteArrayInputStream(bodyBytes));
|
||||
|
||||
String bodyString = new String(bodyBytes, StandardCharsets.UTF_8);
|
||||
io.vertx.core.json.JsonObject jsonObject = new io.vertx.core.json.JsonObject(bodyString);
|
||||
|
||||
if (jsonObject.containsKey(RequestContext.DEVICE)) {
|
||||
io.vertx.core.json.JsonObject device = jsonObject.getJsonObject(RequestContext.DEVICE);
|
||||
|
||||
if (device.containsKey(RequestContext.DEVICE_SESSION_REFERENCE)) {
|
||||
return device.getString(RequestContext.DEVICE_SESSION_REFERENCE);
|
||||
}
|
||||
}
|
||||
|
||||
if (jsonObject.containsKey(RequestContext.REQUEST_ID)) {
|
||||
return jsonObject.getString(RequestContext.REQUEST_ID);
|
||||
}
|
||||
|
||||
if (jsonObject.containsKey(RequestContext.DEVICE_SESSION_REFERENCE)) {
|
||||
return jsonObject.getString(RequestContext.DEVICE_SESSION_REFERENCE);
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
log.error("Error extrayendo el requestId del cuerpo de la peticion: {}", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(
|
||||
ContainerRequestContext requestContext,
|
||||
ContainerResponseContext responseContext
|
||||
) {
|
||||
try {
|
||||
RequestContext.clear();
|
||||
} catch (Exception e) {
|
||||
log.error("Error limpiando el filtro: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.banesco.module.banking_product.domain.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class BankingProduct {
|
||||
private String productType; // codeTypeAlert
|
||||
private String productDescription; // idDiffusion
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.banesco.module.banking_product.domain.model;
|
||||
|
||||
public enum BankingProductType {
|
||||
LOAN_PRODUCT,
|
||||
CURRENT_ACCOUNT_PRODUCT,
|
||||
SAVING_ACCOUNT_PRODUCT,
|
||||
BROKERED_PRODUCT,
|
||||
TERM_DEPOSIT_PRODUCT,
|
||||
MOBILE_PAYMENT,
|
||||
NETUNO
|
||||
}
|
||||
@ -0,0 +1,144 @@
|
||||
package com.banesco.module.correspondence.application.service;
|
||||
|
||||
import com.banesco.common.application.helper.MessageHelper;
|
||||
import com.banesco.common.domain.exception.HttpStatusCodeException;
|
||||
import com.banesco.common.domain.model.ApiResponse;
|
||||
import com.banesco.common.infrastructure.context.RequestContext;
|
||||
import com.banesco.module.correspondence.application.usecase.DomainUseCase;
|
||||
import com.banesco.module.correspondence.application.usecase.CorrespondenceUseCase;
|
||||
import com.banesco.module.correspondence.domain.dto.request.CorrespondenceRequest;
|
||||
import com.banesco.module.correspondence.domain.dto.response.CorrespondenceResponse;
|
||||
import com.banesco.module.security_trace.application.usecase.SecurityTraceUseCase;
|
||||
import com.banesco.module.security_trace.domain.dto.response.SecurityTraceResponse;
|
||||
import com.banesco.module.service_status.application.usecase.ServiceStatusUseCase;
|
||||
import com.banesco.module.service_status.domain.dto.request.ServiceStatusRequest;
|
||||
import com.banesco.module.service_status.domain.dto.response.ServiceStatusResponse;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
@ApplicationScoped
|
||||
public class CorrespondenceService implements CorrespondenceUseCase {
|
||||
|
||||
private final MessageHelper messageHelper;
|
||||
private final ServiceStatusUseCase serviceStatusUseCase;
|
||||
private final SecurityTraceUseCase securityTraceUseCase;
|
||||
private final DomainUseCase domainUseCase;
|
||||
|
||||
@Inject
|
||||
public CorrespondenceService(
|
||||
MessageHelper messageHelper,
|
||||
ServiceStatusUseCase serviceStatusUseCase,
|
||||
SecurityTraceUseCase securityTraceUseCase,
|
||||
DomainUseCase domainUseCase
|
||||
) {
|
||||
this.messageHelper = messageHelper;
|
||||
this.serviceStatusUseCase = serviceStatusUseCase;
|
||||
this.securityTraceUseCase = securityTraceUseCase;
|
||||
this.domainUseCase = domainUseCase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response execute(
|
||||
CorrespondenceRequest request
|
||||
) {
|
||||
log.info("Iniciando ejecucion para la transaccion: {}", request.getId());
|
||||
|
||||
Response response = null;
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
if(!isServiceStatusActive(request)) {
|
||||
log.info("Estatus del servicio no disponible: {}", request.getId());
|
||||
throw HttpStatusCodeException.serviceUnavailable("VRN04");
|
||||
}
|
||||
|
||||
ApiResponse<CorrespondenceResponse> apiResponse = domain(request);
|
||||
|
||||
response = messageHelper.handleSuccess(
|
||||
apiResponse.getData(),
|
||||
apiResponse.getStatusResponse().getStatusCode()
|
||||
);
|
||||
} catch (HttpStatusCodeException e) {
|
||||
log.error("Excepcion HTTP del api de dominio: {} - {}", e.getStatusCode(), e.getErrorCode());
|
||||
response = messageHelper.handleException(e);
|
||||
} catch (Exception e) {
|
||||
log.error("Excepcion generica del api de dominio: {}", e.getMessage());
|
||||
response = messageHelper.handleGenericException(e);
|
||||
} finally {
|
||||
long endTime = System.currentTimeMillis();
|
||||
securityTrace(request, response, startTime, endTime);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private ApiResponse<CorrespondenceResponse> domain(
|
||||
CorrespondenceRequest request
|
||||
) {
|
||||
log.info("Ejecutando llamada al api de dominio: {}", request.getId());
|
||||
return domainUseCase.execute(request, CorrespondenceResponse.class);
|
||||
}
|
||||
|
||||
private boolean isServiceStatusActive(
|
||||
CorrespondenceRequest request
|
||||
) {
|
||||
log.info("Ejecutando llamada al api de la consulta del estatus del servicio");
|
||||
|
||||
boolean isServiceActive = false;
|
||||
|
||||
try {
|
||||
ServiceStatusResponse response = serviceStatusUseCase.execute(
|
||||
ServiceStatusRequest.builder()
|
||||
.applicationId(request.getAppId())
|
||||
.transactionId(RequestContext.getRequestId())
|
||||
.build(),
|
||||
ServiceStatusResponse.class
|
||||
);
|
||||
|
||||
isServiceActive = Objects.equals(response.getStatus(), "A");
|
||||
} catch (HttpStatusCodeException e) {
|
||||
log.info(
|
||||
"Error HTTP al ejecutar la consulta del estatus del servicio: {} -> {}",
|
||||
e.getStatusCode(),
|
||||
e.getMessage()
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.info(
|
||||
"Error al ejecutar la consulta del estatus del servicio: {}",
|
||||
e.getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
return isServiceActive;
|
||||
}
|
||||
|
||||
private void securityTrace(
|
||||
CorrespondenceRequest request,
|
||||
Response response,
|
||||
long startTime,
|
||||
long endTime
|
||||
) {
|
||||
log.info("Ejecutando llamada al api de la traza de seguridad");
|
||||
|
||||
try {
|
||||
securityTraceUseCase.execute(
|
||||
request, response,
|
||||
startTime, endTime,
|
||||
SecurityTraceResponse.class
|
||||
);
|
||||
} catch (HttpStatusCodeException e) {
|
||||
log.info(
|
||||
"Error HTTP al ejecutar la traza de seguridad: {} -> {}",
|
||||
e.getStatusCode(),
|
||||
e.getMessage()
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.info("Error al ejecutar la traza de seguridad: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.banesco.module.correspondence.application.usecase;
|
||||
|
||||
import com.banesco.module.correspondence.domain.dto.request.CorrespondenceRequest;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
public interface CorrespondenceUseCase {
|
||||
Response execute(
|
||||
CorrespondenceRequest request
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.banesco.module.correspondence.application.usecase;
|
||||
|
||||
import com.banesco.common.domain.model.ApiResponse;
|
||||
import com.banesco.module.correspondence.domain.dto.request.CorrespondenceRequest;
|
||||
|
||||
public interface DomainUseCase {
|
||||
<T> ApiResponse<T> execute(
|
||||
CorrespondenceRequest params,
|
||||
Class<T> responseType
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
package com.banesco.module.correspondence.domain.dto.request;
|
||||
|
||||
import com.banesco.common.domain.model.Device;
|
||||
import com.banesco.common.infrastructure.context.RequestContext;
|
||||
import com.banesco.module.instruction.domain.model.Instruction;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class CorrespondenceRequest {
|
||||
@NonNull
|
||||
private String customerReferenceFintechId;
|
||||
@NonNull
|
||||
private String appId;
|
||||
@NonNull
|
||||
private Instruction procedureRequest;
|
||||
@NonNull
|
||||
private Device device;
|
||||
|
||||
@JsonIgnore
|
||||
public String getId() {
|
||||
return procedureRequest
|
||||
.getInstructionIdentifier()
|
||||
.getIdentification()
|
||||
.getIdentifierValue();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public String getChannelCode() {
|
||||
return procedureRequest
|
||||
.getInstructionPurposeType();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public Map<String, String> toParams() {
|
||||
return Map.ofEntries(
|
||||
entry("securityNotificationId", Objects.toString(getId(), "")),
|
||||
entry("channelCode", Objects.toString(getChannelCode(), ""))
|
||||
);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public Map<String, String> toQueryString() {
|
||||
return Map.ofEntries(
|
||||
entry("appId", Objects.toString(getAppId(), "")),
|
||||
entry("customerReferenceFintechId", Objects.toString(getCustomerReferenceFintechId(), "")),
|
||||
entry("deviceType", Objects.toString(getDevice().getDeviceType(), "")),
|
||||
entry("deviceDescription", Objects.toString(getDevice().getDeviceDescription(), "")),
|
||||
entry("deviceIp", Objects.toString(getDevice().getDeviceIp(), "")),
|
||||
entry("deviceSessionReference", (!StringUtil.isNullOrEmpty(getDevice().getDeviceSessionReference()))
|
||||
? getDevice().getDeviceSessionReference()
|
||||
: RequestContext.getRequestId()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.banesco.module.correspondence.domain.dto.response;
|
||||
|
||||
import com.banesco.module.correspondence.domain.model.Correspondence;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
@Schema(description = "Respuesta de la notificación al cliente")
|
||||
public class CorrespondenceResponse {
|
||||
@Schema(description = "Instancia de la informacion de la notificacion")
|
||||
private List<Correspondence> correspondence;
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.banesco.module.correspondence.domain.model;
|
||||
|
||||
import com.banesco.module.banking_product.domain.model.BankingProduct;
|
||||
import com.banesco.module.instruction.domain.model.Instruction;
|
||||
import com.banesco.module.party.domain.model.Party;
|
||||
import com.banesco.module.transaction.domain.model.Transaction;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class Correspondence {
|
||||
private Instruction instructionReference; // id
|
||||
private String sourceReference; // idTypeAlert
|
||||
private BankingProduct bankingProduct; // idDiffusion, codeTypeAlert
|
||||
private Party customerReference; // identityRecipient
|
||||
private Transaction transaction; // amount, currency, idStatusAlert, name, nameStatusAlert, codeStatusAlert, reasonReject,
|
||||
// dateExpired, timeExpired, dateCreate, dateUpdate, typeAuthorization, uuidPasskey
|
||||
// dataAlertJason, pageNumber, pageSize,
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
package com.banesco.module.correspondence.infrastructure.client;
|
||||
|
||||
import com.banesco.common.application.usecase.HttpClientUseCase;
|
||||
import com.banesco.common.domain.exception.HttpApiResponseException;
|
||||
import com.banesco.common.domain.exception.HttpStatusCodeException;
|
||||
import com.banesco.common.domain.model.ApiResponse;
|
||||
import com.banesco.common.domain.model.DomainConfig;
|
||||
import com.banesco.common.domain.model.HttpRequest;
|
||||
import com.banesco.common.infrastructure.config.RestClientConfig;
|
||||
import com.banesco.module.correspondence.application.usecase.DomainUseCase;
|
||||
import com.banesco.module.correspondence.domain.dto.request.CorrespondenceRequest;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@ApplicationScoped
|
||||
public class DomCorrespondenceClient implements DomainUseCase {
|
||||
private final HttpClientUseCase httpClientUseCase;
|
||||
private final DomainConfig domainConfig;
|
||||
|
||||
@Inject
|
||||
public DomCorrespondenceClient(
|
||||
HttpClientUseCase httpClientUseCase,
|
||||
RestClientConfig restClientConfig
|
||||
) {
|
||||
this.httpClientUseCase = httpClientUseCase;
|
||||
this.domainConfig = restClientConfig.getDomServiceIssueConfig();
|
||||
log.info("Configuracion cargada para bus-retrieve-security-notification: {}", domainConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ApiResponse<T> execute(
|
||||
CorrespondenceRequest params,
|
||||
Class<T> responseType
|
||||
) {
|
||||
String securityNotificationId = params.getId();
|
||||
HttpRequest request = HttpRequest.forApiResponse(
|
||||
domainConfig.getUrl(),
|
||||
HttpRequest.HttpMethod.GET,
|
||||
responseType
|
||||
)
|
||||
.withPathParams(params.toParams())
|
||||
.withQueryParams(params.toQueryString())
|
||||
.withTimeout(
|
||||
domainConfig.getTimeout().getConnect(),
|
||||
domainConfig.getTimeout().getResponse()
|
||||
);
|
||||
|
||||
try {
|
||||
ApiResponse<T> response = httpClientUseCase.executeApiResponse(request);
|
||||
|
||||
log.info(
|
||||
"Solicitud del api de dominio exitoso: {}",
|
||||
response.getStatusResponse()
|
||||
);
|
||||
|
||||
return response;
|
||||
} catch (HttpApiResponseException e) {
|
||||
log.error(
|
||||
"Error HTTP con ApiResponse consultando transaccion {}: {}",
|
||||
securityNotificationId,
|
||||
e.getApiResponse()
|
||||
);
|
||||
|
||||
throw new HttpStatusCodeException(
|
||||
e.getStatusCode(),
|
||||
e.getApiResponse().getStatusResponse().getStatusCode()
|
||||
);
|
||||
} catch (HttpStatusCodeException e) {
|
||||
log.error(
|
||||
"Error HTTP consultando transaccion {}: {} - {}",
|
||||
securityNotificationId,
|
||||
e.getStatusCode(),
|
||||
e.getMessage()
|
||||
);
|
||||
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("Error consultando transaccion {}: {}", securityNotificationId, e.getMessage());
|
||||
throw HttpStatusCodeException.serviceUnavailable("503");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,335 @@
|
||||
package com.banesco.module.correspondence.infrastructure.resource;
|
||||
|
||||
import com.banesco.common.domain.model.ApiResponse;
|
||||
import com.banesco.common.domain.model.Device;
|
||||
import com.banesco.common.domain.model.StatusResponse;
|
||||
import com.banesco.module.instruction.domain.model.Instruction;
|
||||
import com.banesco.module.correspondence.application.usecase.CorrespondenceUseCase;
|
||||
import com.banesco.module.correspondence.domain.dto.request.CorrespondenceRequest;
|
||||
import com.banesco.module.correspondence.domain.dto.response.CorrespondenceResponse;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.Content;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.ExampleObject;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.SchemaProperty;
|
||||
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
|
||||
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
|
||||
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
@Path("/correspondence")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public class CorrespondenceResource {
|
||||
|
||||
private final CorrespondenceUseCase useCase;
|
||||
|
||||
@Inject
|
||||
public CorrespondenceResource(
|
||||
CorrespondenceUseCase useCase
|
||||
) {
|
||||
this.useCase = useCase;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/retrieve/{securityNotificationId}/{channelCode}")
|
||||
@Operation(
|
||||
summary = "Recuperar informacion de la transaccion",
|
||||
description = "Consulta de una trasanccion de pago por id de la notificacion"
|
||||
)
|
||||
@APIResponses(value = {
|
||||
@APIResponse(
|
||||
responseCode = "200",
|
||||
description = "Operacion exitosa",
|
||||
content = @Content(
|
||||
mediaType = MediaType.APPLICATION_JSON,
|
||||
schema = @Schema(
|
||||
implementation = ApiResponse.class,
|
||||
properties = {
|
||||
@SchemaProperty(
|
||||
name = "data",
|
||||
oneOf = {CorrespondenceResponse.class}
|
||||
),
|
||||
@SchemaProperty(
|
||||
name = "statusResponse",
|
||||
implementation = StatusResponse.class
|
||||
)
|
||||
}
|
||||
),
|
||||
examples = @ExampleObject(
|
||||
name = "Ejemplo exitoso",
|
||||
value = """
|
||||
{
|
||||
"data": {
|
||||
"correspondence": [
|
||||
{
|
||||
"instructionReference": {
|
||||
"instructionIdentifier": {
|
||||
"identification": {
|
||||
"identifierValue": "10053"
|
||||
},
|
||||
"identificationType": "INSTRUCTION_NUMBER"
|
||||
}
|
||||
},
|
||||
"sourceReference": "1",
|
||||
"bankingProduct": {
|
||||
"productType": "TRANSATIP",
|
||||
"productDescription": "TRANSFERENCIA MONTO ATIPICO"
|
||||
},
|
||||
"customerReference": {
|
||||
"partyIdentification": [
|
||||
{
|
||||
"partyIdentification": {
|
||||
"identifierValue": "v20132859"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"transaction": {
|
||||
"financialTransaction": {
|
||||
"amount": 1000.0,
|
||||
"currencyCode": "VES"
|
||||
},
|
||||
"transactionStatus": {
|
||||
"identification": {
|
||||
"identifierValue": "59"
|
||||
},
|
||||
"statusType": "EXPIRED",
|
||||
"statusName": "EXPIRADA",
|
||||
"statusDescription": "1",
|
||||
"statusRejectedCause": null
|
||||
},
|
||||
"transactionDate": [
|
||||
{
|
||||
"dateType": "INITIATED_DATE",
|
||||
"date": null,
|
||||
"time": null
|
||||
},
|
||||
{
|
||||
"dateType": "EXECUTED_DATE",
|
||||
"date": "2026-01-23 16:28:01.2219947",
|
||||
"time": null
|
||||
},
|
||||
{
|
||||
"dateType": "EXPIRY_DATE",
|
||||
"date": "2025-12-31 00:00:00.0000000",
|
||||
"time": null
|
||||
},
|
||||
{
|
||||
"dateType": "EXPIRY_TIME",
|
||||
"date": null,
|
||||
"time": 0
|
||||
}
|
||||
],
|
||||
"transactionAuthorization": {
|
||||
"identification": {
|
||||
"identifierValue": null
|
||||
},
|
||||
"authorizationType": null
|
||||
},
|
||||
"transactionDetails": {
|
||||
"transactionDataJson": "{\\"amount\\":\\"1000.00\\",\\"currency\\":\\"VES\\"}",
|
||||
"transactionPage": null,
|
||||
"transactionPageSize": null
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"statusResponse": {
|
||||
"statusCode": "200",
|
||||
"message": "Operacion exitosa"
|
||||
}
|
||||
}
|
||||
"""
|
||||
)
|
||||
)
|
||||
),
|
||||
@APIResponse(
|
||||
responseCode = "400",
|
||||
description = "Error en formato o campo requerido",
|
||||
content = @Content(
|
||||
mediaType = MediaType.APPLICATION_JSON,
|
||||
schema = @Schema(
|
||||
implementation = ApiResponse.class,
|
||||
properties = {
|
||||
@SchemaProperty(
|
||||
name = "data",
|
||||
oneOf = {CorrespondenceResponse.class}
|
||||
),
|
||||
@SchemaProperty(
|
||||
name = "statusResponse",
|
||||
implementation = StatusResponse.class
|
||||
)
|
||||
}
|
||||
),
|
||||
examples = {
|
||||
@ExampleObject(
|
||||
name = "Error VDE01 - Campo obligatorio",
|
||||
value = """
|
||||
{
|
||||
"data": null,
|
||||
"statusResponse": {
|
||||
"statusCode": "VDE01",
|
||||
"message": "El campo securityNotificationId es obligatorio"
|
||||
}
|
||||
}
|
||||
"""
|
||||
),
|
||||
@ExampleObject(
|
||||
name = "Error VDE02 - Valor no permitido",
|
||||
value = """
|
||||
{
|
||||
"data": null,
|
||||
"statusResponse": {
|
||||
"statusCode": "VDE02",
|
||||
"message": "El valor 'XYZ' no es permitido para el campo channelCode. Valores permitidos: BOL, BOLE"
|
||||
}
|
||||
}
|
||||
"""
|
||||
)
|
||||
}
|
||||
)
|
||||
),
|
||||
@APIResponse(
|
||||
responseCode = "401",
|
||||
description = "No autorizado",
|
||||
content = @Content(
|
||||
mediaType = MediaType.APPLICATION_JSON,
|
||||
schema = @Schema(
|
||||
implementation = ApiResponse.class,
|
||||
properties = {
|
||||
@SchemaProperty(
|
||||
name = "data",
|
||||
oneOf = {CorrespondenceResponse.class}
|
||||
),
|
||||
@SchemaProperty(
|
||||
name = "statusResponse",
|
||||
implementation = StatusResponse.class
|
||||
)
|
||||
}
|
||||
),
|
||||
examples = {
|
||||
@ExampleObject(
|
||||
name = "Error VRN08 - Identificacion del fintechId no coincide",
|
||||
value = """
|
||||
{
|
||||
"data": null,
|
||||
"statusResponse": {
|
||||
"statusCode": "VRN08",
|
||||
"message": "El fintechId proporcionado no coincide con el registrado para este cliente"
|
||||
}
|
||||
}
|
||||
"""
|
||||
)
|
||||
}
|
||||
)
|
||||
),
|
||||
@APIResponse(
|
||||
responseCode = "503",
|
||||
description = "Servicio no disponible",
|
||||
content = @Content(
|
||||
mediaType = MediaType.APPLICATION_JSON,
|
||||
schema = @Schema(
|
||||
implementation = ApiResponse.class,
|
||||
properties = {
|
||||
@SchemaProperty(
|
||||
name = "data",
|
||||
oneOf = {CorrespondenceResponse.class}
|
||||
),
|
||||
@SchemaProperty(
|
||||
name = "statusResponse",
|
||||
implementation = StatusResponse.class
|
||||
)
|
||||
}
|
||||
),
|
||||
examples = {
|
||||
@ExampleObject(
|
||||
name = "Error VRN04 - Fuera de horario",
|
||||
value = """
|
||||
{
|
||||
"data": null,
|
||||
"statusResponse": {
|
||||
"statusCode": "VRN04",
|
||||
"message": "El servicio no esta disponible fuera del horario operativo"
|
||||
}
|
||||
}
|
||||
"""
|
||||
),
|
||||
@ExampleObject(
|
||||
name = "Error VDR13 - OSB no disponible",
|
||||
value = """
|
||||
{
|
||||
"data": null,
|
||||
"statusResponse": {
|
||||
"statusCode": "VDR13",
|
||||
"message": "El servicio OSB no esta disponible en este momento"
|
||||
}
|
||||
}
|
||||
"""
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
})
|
||||
public Response retrieve(
|
||||
@PathParam("securityNotificationId")
|
||||
@Parameter(description = "Identificacion de la notifiacion", required = true, example = "11")
|
||||
String securityNotificationId,
|
||||
|
||||
@PathParam("channelCode")
|
||||
@Parameter(description = "Codigo del canal (ConsolaPredictiva)", required = true, example = "ConsolaPredictiva")
|
||||
String channelCode,
|
||||
|
||||
@QueryParam("customerReferenceFintechId")
|
||||
@Parameter(description = "ID de la fintech", example = "pranical-test")
|
||||
String customerReferenceFintechId,
|
||||
|
||||
@QueryParam("appId")
|
||||
@Parameter(description = "ID de la aplicacion", example = "DANIAPP")
|
||||
String appId,
|
||||
|
||||
@QueryParam("deviceType")
|
||||
@Parameter(description = "Tipo de dispositivo", example = "Mobile")
|
||||
String deviceType,
|
||||
|
||||
@QueryParam("deviceDescription")
|
||||
@Parameter(description = "Descripcion del dispositivo", example = "Xiaomi Note 11 PRO")
|
||||
String deviceDescription,
|
||||
|
||||
@QueryParam("deviceIp")
|
||||
@Parameter(description = "Direccion IP del dispositivo", example = "127.0.0.1")
|
||||
String deviceIp,
|
||||
|
||||
@QueryParam("deviceSessionReference")
|
||||
@Parameter(description = "Referencia de la peticion del dispositivo", example = "12345678901304")
|
||||
String deviceSessionReference
|
||||
) {
|
||||
log.info("Iniciando consulta para instruccion de la notificacion id: {}", securityNotificationId);
|
||||
|
||||
return useCase.execute(
|
||||
CorrespondenceRequest.builder()
|
||||
.customerReferenceFintechId(Objects.toString(customerReferenceFintechId, ""))
|
||||
.appId(Objects.toString(appId, ""))
|
||||
.procedureRequest(Instruction.fromResource(
|
||||
securityNotificationId, channelCode
|
||||
))
|
||||
.device(
|
||||
Device.builder()
|
||||
.deviceType(deviceType)
|
||||
.deviceDescription(deviceDescription)
|
||||
.deviceIp(deviceIp)
|
||||
.deviceSessionReference(deviceSessionReference)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package com.banesco.module.instruction.domain.model;
|
||||
|
||||
import com.banesco.common.domain.model.Identifier;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class Instruction {
|
||||
private InstructionIdentification instructionIdentifier; // Request JSON: "id"
|
||||
private String instructionPurposeType; // Request JSON: "channelOrigin" (BOLE)
|
||||
|
||||
public static Instruction fromResource(
|
||||
String securityNotificationId,
|
||||
String channelCode
|
||||
) {
|
||||
return Instruction.builder()
|
||||
.instructionIdentifier(
|
||||
InstructionIdentification.builder()
|
||||
.identification(
|
||||
Identifier.builder()
|
||||
.identifierValue(securityNotificationId)
|
||||
.build()
|
||||
)
|
||||
.identificationType(InstructionIdentificationType.INSTRUCTION_NUMBER)
|
||||
.build()
|
||||
)
|
||||
.instructionPurposeType(channelCode)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.banesco.module.instruction.domain.model;
|
||||
|
||||
import com.banesco.common.domain.model.Identifier;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class InstructionIdentification {
|
||||
private Identifier identification;
|
||||
private InstructionIdentificationType identificationType;
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
package com.banesco.module.instruction.domain.model;
|
||||
|
||||
public enum InstructionIdentificationType {
|
||||
ORDER_NUMBER,
|
||||
INSTRUCTION_NUMBER
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.banesco.module.party.domain.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class Party {
|
||||
private List<PartyIdentification> partyIdentification;
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.banesco.module.party.domain.model;
|
||||
|
||||
import com.banesco.common.domain.model.Identifier;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class PartyIdentification {
|
||||
private Identifier partyIdentification;
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.banesco.module.security_trace.application.usecase;
|
||||
|
||||
import com.banesco.module.correspondence.domain.dto.request.CorrespondenceRequest;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
public interface SecurityTraceUseCase {
|
||||
<T> T execute(
|
||||
CorrespondenceRequest apiRequest,
|
||||
Response apiResponse,
|
||||
long startTime,
|
||||
long endTime,
|
||||
Class<T> responseType
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,134 @@
|
||||
package com.banesco.module.security_trace.domain.dto.request;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class SecurityTraceRequest {
|
||||
private String codBan;
|
||||
private String codMon;
|
||||
private String codEve;
|
||||
private String codEve2;
|
||||
private String login;
|
||||
private Date fecHor;
|
||||
private String nacCli;
|
||||
private Integer cedRifCli;
|
||||
private String tipoProductoCli;
|
||||
private String tipoProductoBen;
|
||||
private String productoCli;
|
||||
private String codEmpresa;
|
||||
private String nacBen;
|
||||
private Integer cedBen;
|
||||
private String nombreBen;
|
||||
private String productoBen;
|
||||
private BigDecimal monto;
|
||||
private String referencia;
|
||||
private String nroDePago;
|
||||
private String desPago;
|
||||
private String objeto;
|
||||
private Integer tipoRespuesta;
|
||||
private String msgRespuesta;
|
||||
private Long tiempoRespuesta;
|
||||
private String codFintech;
|
||||
private String cedRifFintech;
|
||||
private String nombreFintech;
|
||||
private String tipoDispositivo;
|
||||
private String desDispositivo;
|
||||
private String ipCli;
|
||||
private String refInternacional;
|
||||
private BigDecimal montoReceptor;
|
||||
private String refBanco;
|
||||
private String stsTransaccion;
|
||||
private String tipoMonedaEmi;
|
||||
private String tipoMonedaRec;
|
||||
private String paisEmisor;
|
||||
private String paisReceptor;
|
||||
private BigDecimal montoEmisor;
|
||||
private String numeroCuentaEmi;
|
||||
private String numeroCuentaRec;
|
||||
private String numeroTelefonoRec;
|
||||
private String propositoTransaccion;
|
||||
private BigDecimal montoComision;
|
||||
private String tipoIdEmisor;
|
||||
private String idEmisor;
|
||||
private BigDecimal numeroTarjeta;
|
||||
private Integer codigoAutoriza;
|
||||
private String refUniversal;
|
||||
private String fechaAprobacion;
|
||||
private String refBanesco;
|
||||
private String fecHorCarga;
|
||||
private String tipoProductoEmisor;
|
||||
private String ctaEmisor;
|
||||
private String tipoProductoReceptor;
|
||||
private String ctaReceptor;
|
||||
private String idReceptor;
|
||||
private String nombreReceptor;
|
||||
private String refExterna;
|
||||
private String origenFondos;
|
||||
private String destinoFondos;
|
||||
private String fecHorTransaccion;
|
||||
private String metodoPagoEmisor;
|
||||
private String valorMetodoPagoEmisor;
|
||||
private String entFinancieraEmisor;
|
||||
private String nombreEmisor;
|
||||
private String monedaEmisor;
|
||||
private String metodoPagoReceptor;
|
||||
private String valorMetodoPagoReceptor;
|
||||
private String entFinancieraReceptor;
|
||||
private String monedaReceptor;
|
||||
private String descPago;
|
||||
private String descTransaccion;
|
||||
private BigDecimal tasaComision;
|
||||
private BigDecimal numTarjeta;
|
||||
private String codAutorizacion;
|
||||
private String fecHorAprobacion;
|
||||
private BigDecimal montoIgtf;
|
||||
private BigDecimal montoLbtr;
|
||||
private BigDecimal tasaCambio;
|
||||
private BigDecimal montoTotalBs;
|
||||
private String sp;
|
||||
private String cn;
|
||||
private String OU;
|
||||
private String distinguishedName;
|
||||
private String userPassword;
|
||||
private Integer Enabled;
|
||||
private String givenName;
|
||||
private String sn;
|
||||
private String mail;
|
||||
private String employeeNumber;
|
||||
private String employeeID;
|
||||
private String mobile;
|
||||
private String homePhone;
|
||||
private String company;
|
||||
private String personalTitle;
|
||||
private String title;
|
||||
private String description;
|
||||
private String departament;
|
||||
private String otherMobile;
|
||||
private String otherHomePhone;
|
||||
private String telephoneNumber;
|
||||
private String facsimileTelephoneNumber;
|
||||
private String postalAddress;
|
||||
private String postalCode;
|
||||
private String st;
|
||||
private String owner;
|
||||
private String serialNumber;
|
||||
private String usuarioMaster;
|
||||
private Integer lockoutTime;
|
||||
private Integer lockoutDuration;
|
||||
private Integer lockoutThreshold;
|
||||
private Integer badPwdCount;
|
||||
private String badPasswordTime;
|
||||
private String oU;
|
||||
private Integer enabled;
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.banesco.module.security_trace.domain.dto.response;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class SecurityTraceResponse {
|
||||
private String msg;
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.banesco.module.security_trace.domain.model;
|
||||
|
||||
import com.banesco.common.domain.model.TimeoutConfig;
|
||||
import com.banesco.module.security_trace.domain.dto.request.SecurityTraceRequest;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@RegisterForReflection
|
||||
public class SecurityTraceConfig {
|
||||
private String url;
|
||||
private TimeoutConfig timeout;
|
||||
private SecurityTraceRequest request;
|
||||
}
|
||||
@ -0,0 +1,138 @@
|
||||
package com.banesco.module.security_trace.infrastructure.client;
|
||||
|
||||
import com.banesco.common.application.usecase.HttpClientUseCase;
|
||||
import com.banesco.common.domain.exception.HttpStatusCodeException;
|
||||
import com.banesco.common.domain.model.ApiResponse;
|
||||
import com.banesco.common.domain.model.HttpRequest;
|
||||
import com.banesco.common.infrastructure.config.RestClientConfig;
|
||||
import com.banesco.module.correspondence.domain.dto.request.CorrespondenceRequest;
|
||||
import com.banesco.module.security_trace.application.usecase.SecurityTraceUseCase;
|
||||
import com.banesco.module.security_trace.domain.dto.request.SecurityTraceRequest;
|
||||
import com.banesco.module.security_trace.domain.model.SecurityTraceConfig;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Slf4j
|
||||
@ApplicationScoped
|
||||
public class SecurityTraceClient implements SecurityTraceUseCase {
|
||||
private final HttpClientUseCase httpClientUseCase;
|
||||
private final RestClientConfig restClientConfig;
|
||||
private final SecurityTraceConfig securityTraceConfig;
|
||||
|
||||
@Inject
|
||||
public SecurityTraceClient(
|
||||
HttpClientUseCase httpClientUseCase,
|
||||
RestClientConfig restClientConfig
|
||||
) {
|
||||
this.httpClientUseCase = httpClientUseCase;
|
||||
this.restClientConfig = restClientConfig;
|
||||
this.securityTraceConfig = restClientConfig.getSecurityTraceConfig();
|
||||
log.info("Configuracion cargada para security-trace: {}", securityTraceConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T execute(
|
||||
CorrespondenceRequest apiRequest,
|
||||
Response apiResponse,
|
||||
long startTime,
|
||||
long endTime,
|
||||
Class<T> responseType
|
||||
) {
|
||||
SecurityTraceRequest body = getRequest(
|
||||
apiRequest, apiResponse,
|
||||
startTime, endTime
|
||||
);
|
||||
HttpRequest request = HttpRequest.forDirectResponse(
|
||||
securityTraceConfig.getUrl(),
|
||||
HttpRequest.HttpMethod.POST,
|
||||
responseType
|
||||
)
|
||||
.withBody(body)
|
||||
.withTimeout(
|
||||
securityTraceConfig.getTimeout().getConnect(),
|
||||
securityTraceConfig.getTimeout().getResponse()
|
||||
);
|
||||
|
||||
try {
|
||||
T response = httpClientUseCase.execute(request);
|
||||
|
||||
log.info(
|
||||
"Solicitud de traza de seguridad exitosa: {}",
|
||||
response.toString().contains("msg=Message sende")
|
||||
);
|
||||
|
||||
return response;
|
||||
} catch (HttpStatusCodeException e) {
|
||||
log.error(
|
||||
"Error HTTP ejecutando traza de seguridad: {} - {}",
|
||||
e.getStatusCode(),
|
||||
e.getMessage()
|
||||
);
|
||||
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("Error ejecutando traza de seguridad: {}", e.getMessage());
|
||||
throw HttpStatusCodeException.serviceUnavailable("503");
|
||||
}
|
||||
}
|
||||
|
||||
private SecurityTraceRequest getRequest(
|
||||
CorrespondenceRequest apiRequest,
|
||||
Response apiResponse,
|
||||
long startTime,
|
||||
long endTime
|
||||
) {
|
||||
long executedTime = (endTime - startTime);
|
||||
int statusHttp = apiResponse.getStatus();
|
||||
ApiResponse<?> apiResponseData = (ApiResponse<?>) apiResponse.getEntity();
|
||||
|
||||
return SecurityTraceRequest.builder()
|
||||
.sp(securityTraceConfig.getRequest().getSp())
|
||||
.codBan(securityTraceConfig.getRequest().getCodBan())
|
||||
.codMon(securityTraceConfig.getRequest().getCodMon())
|
||||
.codEve(securityTraceConfig.getRequest().getCodEve())
|
||||
.codEve2(securityTraceConfig.getRequest().getCodEve2())
|
||||
.login(apiRequest.getChannelCode())
|
||||
.fecHor(new Date())
|
||||
.nacCli("")
|
||||
.cedRifCli(0)
|
||||
.objeto(
|
||||
restClientConfig.toJsonString(SecurityTraceObject.builder()
|
||||
.RQ(apiRequest)
|
||||
.RS(apiResponseData)
|
||||
.build())
|
||||
)
|
||||
.tipoRespuesta(statusHttp)
|
||||
.msgRespuesta(getStatusMessage(apiResponseData, statusHttp))
|
||||
.tiempoRespuesta(executedTime)
|
||||
.codFintech(apiRequest.getCustomerReferenceFintechId())
|
||||
.nombreFintech(apiRequest.getChannelCode())
|
||||
.tipoDispositivo(apiRequest.getDevice().getDeviceType())
|
||||
.desDispositivo(apiRequest.getDevice().getDeviceDescription())
|
||||
.ipCli(apiRequest.getDevice().getDeviceIp())
|
||||
.build();
|
||||
}
|
||||
|
||||
private String getStatusMessage(
|
||||
ApiResponse<?> apiResponseData,
|
||||
int statusHttp
|
||||
) {
|
||||
if (apiResponseData != null && apiResponseData.getStatusResponse() != null) {
|
||||
String statusCode = apiResponseData.getStatusResponse().getStatusCode();
|
||||
String message = apiResponseData.getStatusResponse().getMessage();
|
||||
|
||||
if(StringUtil.isNullOrEmpty(statusCode)) {
|
||||
statusCode = String.valueOf(statusHttp);
|
||||
}
|
||||
|
||||
return statusCode + "-" + message;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.banesco.module.security_trace.infrastructure.client;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonNaming;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
@JsonPropertyOrder({"RQ", "RS"})
|
||||
@JsonNaming(PropertyNamingStrategies.UpperSnakeCaseStrategy.class)
|
||||
public class SecurityTraceObject {
|
||||
private Object RQ;
|
||||
private Object RS;
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.banesco.module.service_status.application.usecase;
|
||||
|
||||
import com.banesco.module.service_status.domain.dto.request.ServiceStatusRequest;
|
||||
|
||||
public interface ServiceStatusUseCase {
|
||||
<T> T execute(
|
||||
ServiceStatusRequest params,
|
||||
Class<T> responseType
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.banesco.module.service_status.domain.dto.request;
|
||||
|
||||
import com.banesco.common.domain.model.BankService;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class ServiceStatusRequest {
|
||||
private String applicationId;
|
||||
private String transactionId;
|
||||
private BankService bankService;
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.banesco.module.service_status.domain.dto.response;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class ServiceStatusResponse {
|
||||
private String status;
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.banesco.module.service_status.domain.model;
|
||||
|
||||
import com.banesco.common.domain.model.TimeoutConfig;
|
||||
import com.banesco.module.service_status.domain.dto.request.ServiceStatusRequest;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@RegisterForReflection
|
||||
public class ServiceStatusConfig {
|
||||
private String url;
|
||||
private TimeoutConfig timeout;
|
||||
private ServiceStatusRequest request;
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
package com.banesco.module.service_status.infrastructure.client;
|
||||
|
||||
import com.banesco.common.application.usecase.HttpClientUseCase;
|
||||
import com.banesco.common.domain.exception.HttpStatusCodeException;
|
||||
import com.banesco.common.domain.model.HttpRequest;
|
||||
import com.banesco.common.infrastructure.config.RestClientConfig;
|
||||
import com.banesco.module.service_status.application.usecase.ServiceStatusUseCase;
|
||||
import com.banesco.module.service_status.domain.dto.request.ServiceStatusRequest;
|
||||
import com.banesco.module.service_status.domain.model.ServiceStatusConfig;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@ApplicationScoped
|
||||
public class ServiceStatusClient implements ServiceStatusUseCase {
|
||||
private final HttpClientUseCase httpClientUseCase;
|
||||
private final ServiceStatusConfig serviceStatusConfig;
|
||||
|
||||
@Inject
|
||||
public ServiceStatusClient(
|
||||
HttpClientUseCase httpClientUseCase,
|
||||
RestClientConfig restClientConfig
|
||||
) {
|
||||
this.httpClientUseCase = httpClientUseCase;
|
||||
this.serviceStatusConfig = restClientConfig.getServiceStatusConfig();
|
||||
log.info("Configuracion cargada para service-status: {}", serviceStatusConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T execute(
|
||||
ServiceStatusRequest params,
|
||||
Class<T> responseType
|
||||
) {
|
||||
ServiceStatusRequest body = ServiceStatusRequest.builder()
|
||||
.applicationId(params.getApplicationId())
|
||||
.transactionId(params.getTransactionId())
|
||||
.bankService(serviceStatusConfig.getRequest().getBankService())
|
||||
.build();
|
||||
HttpRequest request = HttpRequest.forDirectResponse(
|
||||
serviceStatusConfig.getUrl(),
|
||||
HttpRequest.HttpMethod.POST,
|
||||
responseType
|
||||
)
|
||||
.withBody(body)
|
||||
.withTimeout(
|
||||
serviceStatusConfig.getTimeout().getConnect(),
|
||||
serviceStatusConfig.getTimeout().getResponse()
|
||||
);
|
||||
|
||||
try {
|
||||
T response = httpClientUseCase.execute(request);
|
||||
|
||||
log.info(
|
||||
"Solicitud de estado del servicio exitosa: {}",
|
||||
response.toString().contains("status=")
|
||||
);
|
||||
|
||||
return response;
|
||||
} catch (HttpStatusCodeException e) {
|
||||
log.error(
|
||||
"Error HTTP ejecutando verificacion de estado del servicio: {} - {}",
|
||||
e.getStatusCode(),
|
||||
e.getMessage()
|
||||
);
|
||||
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("Error ejecutando verificacion de estado del servicio: {}", e.getMessage());
|
||||
throw HttpStatusCodeException.serviceUnavailable("503");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.banesco.module.transaction.domain.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class FinancialTransaction {
|
||||
private BigDecimal amount; // amount
|
||||
private String currencyCode; // currency
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.banesco.module.transaction.domain.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class Transaction {
|
||||
private FinancialTransaction financialTransaction; // amount, currency
|
||||
private TransactionStatus transactionStatus; // idStatusAlert, name, nameStatusAlert, codeStatusAlert, reasonReject
|
||||
private List<TransactionDateTime> transactionDate; // dateExpired, timeExpired, dateCreate, dateUpdate
|
||||
private TransactionAuthorization transactionAuthorization; // typeAuthorization, uuidPasskey
|
||||
private TransactionDetails transactionDetails; // dataAlertJason, pageNumber, pageSize
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.banesco.module.transaction.domain.model;
|
||||
|
||||
import com.banesco.common.domain.model.Identifier;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class TransactionAuthorization {
|
||||
private Identifier identification; // uuidPasskey
|
||||
private String authorizationType; // typeAuthorization
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.banesco.module.transaction.domain.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class TransactionDateTime {
|
||||
private TransactionDateTimeType dateType;
|
||||
private String date;
|
||||
private Long time;
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.banesco.module.transaction.domain.model;
|
||||
|
||||
public enum TransactionDateTimeType {
|
||||
EXECUTED_DATE,
|
||||
FULFILLMENT_DATE,
|
||||
INITIATED_DATE,
|
||||
CANCELLED_DATE,
|
||||
APPROVED_DATE,
|
||||
VALUE_DATE,
|
||||
BOOKING_DATE,
|
||||
AVAILABLE_DATE,
|
||||
EXPIRY_DATE,
|
||||
EXPIRY_TIME,
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.banesco.module.transaction.domain.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class TransactionDetails {
|
||||
private String transactionDataJson; // dataAlertJason
|
||||
private String transactionPage; // pageNumber
|
||||
private String transactionPageSize; // pageSize
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.banesco.module.transaction.domain.model;
|
||||
|
||||
import com.banesco.common.domain.model.Identifier;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@RegisterForReflection
|
||||
public class TransactionStatus {
|
||||
private Identifier identification; // idStatusAlert
|
||||
private TransactionStatusType statusType; // name
|
||||
private String statusName; // nameStatusAlert
|
||||
private String statusDescription; // codeStatusAlert
|
||||
private String statusRejectedCause; // reasonReject
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.banesco.module.transaction.domain.model;
|
||||
|
||||
public enum TransactionStatusType {
|
||||
DEFAULT,
|
||||
INITIATED,
|
||||
IN_PROGRESS,
|
||||
EXECUTED,
|
||||
CANCELLED,
|
||||
CONFIRMED,
|
||||
APPROVED,
|
||||
SUSPENDED,
|
||||
PENDING,
|
||||
COMPLETED,
|
||||
NOTIFIED,
|
||||
BOOKED,
|
||||
REJECTED,
|
||||
EXPIRED,
|
||||
SENT,
|
||||
RECEIVED,
|
||||
ACTIVE,
|
||||
READ,
|
||||
PROGRAMED,
|
||||
ATYPICAL_TRANSACTION,
|
||||
}
|
||||
20
src/main/resources/application-dev.yml
Normal file
20
src/main/resources/application-dev.yml
Normal file
@ -0,0 +1,20 @@
|
||||
quarkus:
|
||||
http:
|
||||
port: 8082
|
||||
idle-timeout: 30s
|
||||
thread-pool:
|
||||
max-threads: 100
|
||||
core-threads: 1
|
||||
|
||||
api:
|
||||
source-id: BRSN
|
||||
read-messages:
|
||||
from-props: true
|
||||
bus-retrieve-security-notification:
|
||||
messages:
|
||||
key: 'bus-retrieve-security-notification'
|
||||
content: '[{"backendCode":"200","httpCode":200,"statusCode":"200","description":"Operacion exitosa"},{"backendCode":"R404","httpCode":404,"statusCode":"404","description":"Datos de validacion no encontrado."},{"backendCode":"503","httpCode":503,"statusCode":"503","description":"Uso interno"},{"backendCode":"422","httpCode":422,"statusCode":"422","description":"Uso interno"},{"backendCode":"500","httpCode":500,"statusCode":"500","description":"Uso interno"},{"backendCode":"100","httpCode":503,"statusCode":"503","description":"VDR13 - OSB Disponible"},{"backendCode":"OSB-382505","httpCode":503,"statusCode":"503","description":"VDR13 - OSB Disponible"},{"backendCode":"OSB-380002","httpCode":503,"statusCode":"503","description":"VDR13 - OSB Disponible"},{"backendCode":"ERROR","httpCode":400,"statusCode":"400","description":"Uso interno"},{"backendCode":"400","httpCode":400,"statusCode":"400","description":"Uso interno"},{"backendCode":"401","httpCode":401,"statusCode":"401","description":"Uso interno"},{"backendCode":"403","httpCode":403,"statusCode":"403","description":"Uso interno"},{"backendCode":"404","httpCode":404,"statusCode":"404","description":"Uso interno"},{"backendCode":"default","httpCode":409,"statusCode":"409","description":"Conflicto"},{"backendCode":"424","httpCode":424,"statusCode":"424","description":"Error de dependencia"},{"backendCode":"VDE01","httpCode":400,"statusCode":"VDE01","description":"VDE01 - Error en dato de entrada obligatorio: %s"},{"backendCode":"VDE02","httpCode":400,"statusCode":"VDE02","description":"VDE02 - Error en valor permitido para campo: %s"},{"backendCode":"VRN04","httpCode":"503","statusCode":"VRN04","description":"Servicio en horario de mantenimiento","status":"error"},{"backendCode":"VRN02","httpCode":"204","statusCode":"VRN02","description":"Cliente sin productos"}]'
|
||||
rest-client:
|
||||
dom-retrieve-security-notification: '{"url":"http://localhost:8083/correspondence/retrieve/{securityNotificationId}/{channelCode}","timeout":{"connect":10000,"response":10000}}'
|
||||
security-trace: '{"url":"http://api-register-security-route-apis-banesco-dev.apps.desplakur3.desintra.banesco.com/register-security/save","timeout":{"connect":10000,"response":10000},"request":{"sp":"spAPI_Traza","codEve":"CONSALERTS","codEve2":"CONSALERTS","codBan":"01","codMon":"BS"}}'
|
||||
service-status: '{"url":"http://api-get-service-status-route-apis-banesco-dev.apps.desplakur3.desintra.banesco.com/service/status","timeout":{"connect":10000,"response":10000},"request":{"applicationId": "","transactionId": "","bankService": {"bankCode": "01","serviceCode": "APIFI","eventCode": "P2PVUEL"}}}'
|
||||
41
src/main/resources/application.yml
Normal file
41
src/main/resources/application.yml
Normal file
@ -0,0 +1,41 @@
|
||||
quarkus:
|
||||
application:
|
||||
name: bus-retrieve-security-notification
|
||||
version: 1.0.0
|
||||
## Profile
|
||||
profile: dev
|
||||
http:
|
||||
non-application-root-path: actuator
|
||||
native:
|
||||
file-encoding: UTF-8
|
||||
container-build: true
|
||||
builder-image: quay.io/quarkus/ubi-quarkus-mandrel-builder-image:23.0.5.0-Final-java17
|
||||
container-runtime: docker
|
||||
additional-build-args:
|
||||
- -H:InitialCollectionPolicy=com.oracle.svm.core.genscavenge.CollectionPolicy\$BySpaceAndTime
|
||||
native-image-xmx: 6G
|
||||
resources:
|
||||
excludes: resources/*.yaml
|
||||
## OpenApi
|
||||
smallrye-openapi:
|
||||
path: /openapi
|
||||
enable: 'true'
|
||||
## Swagger IU
|
||||
swagger-ui:
|
||||
path: /swagger-ui
|
||||
always-include: 'true'
|
||||
## Logs
|
||||
log:
|
||||
level: INFO
|
||||
console:
|
||||
enable: true
|
||||
format: "%d{HH:mm:ss.SSS} %-5p [%t] [%X{requestId}] %c{1} - %s%e%n"
|
||||
smallrye-health:
|
||||
root-path: /actuator/health
|
||||
liveness-path: /actuator/health/live
|
||||
readiness-path: /actuator/health/ready
|
||||
ui:
|
||||
enable: false
|
||||
debug:
|
||||
print-startup-times: true
|
||||
reflection: false
|
||||
Loading…
x
Reference in New Issue
Block a user