SCRUM-1099: Added event message subscribers to create audit logs for catalog, event and workspace bs services
Added unit and integration tests for the catalog, event and workspace streams
This commit is contained in:
parent
b361f72b33
commit
2256eb408a
|
|
@ -0,0 +1,2 @@
|
|||
/mvnw text eol=lf
|
||||
*.cmd text eol=crlf
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/logs/
|
||||
/wp2-be-audit-bs-server/logs/
|
||||
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# 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.
|
||||
wrapperVersion=3.3.2
|
||||
distributionType=only-script
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
# Audit Changelog
|
||||
|
||||
<!--
|
||||
|
||||
## Templates for adding change log information
|
||||
|
||||
## [Version] - YYYY-MM-DD
|
||||
|
||||
### Added
|
||||
- something
|
||||
|
||||
### Changed
|
||||
- something
|
||||
|
||||
### Deprecated
|
||||
- something
|
||||
|
||||
### Removed
|
||||
- something
|
||||
|
||||
### Fixed
|
||||
- something
|
||||
|
||||
### Security
|
||||
- something
|
||||
|
||||
-->
|
||||
|
||||
# [1.0.0] - 2025-08-29
|
||||
|
||||
### [SCRUM-1099](https://itserr-wp2.atlassian.net/browse/SCRUM-1099)
|
||||
|
||||
### Added
|
||||
|
||||
- added event subscriber to create audit logs for catalog, event and workspace bs services
|
||||
- added unit and integration tests for all event subscribers
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
FROM openjdk:21-jdk-slim AS runtime
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN addgroup --system finconsgroup && \
|
||||
adduser --system --ingroup finconsgroup --disabled-login --shell /sbin/nologin --home /var/cache/finconsgroup finconsgroup
|
||||
|
||||
COPY wp2-be-audit-bs-server/target/*.jar /app/app.jar
|
||||
|
||||
RUN chown -R finconsgroup:finconsgroup /app
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
USER finconsgroup
|
||||
|
||||
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
|
||||
52
README.md
52
README.md
|
|
@ -1 +1,53 @@
|
|||
# Audit Business Service
|
||||
|
||||
Audit Business Service is a **Spring Boot** application built with **Maven**,
|
||||
providing ingest operations for all audit related events by consuming the same
|
||||
from all the relevant event streams.
|
||||
|
||||
## Features
|
||||
|
||||
- **Audit Log**
|
||||
- Create by processing events
|
||||
- Supported Streams
|
||||
- Catalog BS
|
||||
- Event BS
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Requirements
|
||||
|
||||
For building and running the application you need:
|
||||
|
||||
- GIT 2.48.1 +
|
||||
- JDK 21 +
|
||||
|
||||
### Clone the repository
|
||||
|
||||
```
|
||||
git clone https://code-repo.d4science.org/Resilience/wp2-be-audit-bs.git
|
||||
cd wp2-be-audit-bs
|
||||
```
|
||||
|
||||
### Build the project
|
||||
|
||||
```
|
||||
./mvnw clean install
|
||||
```
|
||||
|
||||
### Run the application
|
||||
|
||||
```
|
||||
java -jar wp2-be-audit-bs-server/target/<jar-file>
|
||||
```
|
||||
|
||||
### Access the API
|
||||
|
||||
- Base URL: `http://localhost:8080/api/v1/bs`
|
||||
- Swagger UI URL: `http://localhost:8080/api/v1/bs/swagger-ui/index.html`
|
||||
|
||||
### Development
|
||||
|
||||
Please review this wiki page and follow the guidelines mentioned -
|
||||
[Code Management Workflow and Standards](https://itserr-wp2.atlassian.net/wiki/spaces/IW/pages/46465038/Code+Management+Workflow+and+Standards)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
## The file with defaults can be generated using command, where M2_REPO points to local maven repository folder
|
||||
## Also replace version with the value you are using, in this case it is 1.18.36
|
||||
# java -jar "%M2_REPO%\org\projectlombok\lombok\1.18.36\lombok-1.18.36.jar" config -g --verbose >> lombok.config
|
||||
|
||||
##
|
||||
## Key : lombok.copyableAnnotations
|
||||
## Type: list of type-name
|
||||
##
|
||||
## Copy these annotations to getters, setters, with methods, builder-setters, etc.
|
||||
##
|
||||
## Examples:
|
||||
#
|
||||
clear lombok.copyableAnnotations
|
||||
# lombok.copyableAnnotations += <fully.qualified.Type>
|
||||
# lombok.copyableAnnotations -= <fully.qualified.Type>
|
||||
#
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
#!/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.2
|
||||
#
|
||||
# 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:]'
|
||||
}
|
||||
|
||||
# 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 <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
|
||||
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.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${0##*/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
|
||||
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
|
||||
mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
|
||||
|
||||
clean || :
|
||||
exec_maven "$@"
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
<# : 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.2
|
||||
@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) { "/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_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
|
||||
if ($env:MAVEN_USER_HOME) {
|
||||
$MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
|
||||
}
|
||||
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::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
|
||||
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -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"
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<?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>
|
||||
|
||||
<parent>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<artifactId>wp2-be-audit-bs</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
<name>wp2-be-audit-bs</name>
|
||||
<description>Audit Bs Application</description>
|
||||
<modules>
|
||||
<module>wp2-be-audit-bs-client</module>
|
||||
<module>wp2-be-audit-bs-server</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- WP2 Audit DM Client -->
|
||||
<dependency>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>wp2-be-audit-dm-client</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- WP2 Audit BS Client -->
|
||||
<dependency>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>wp2-be-audit-bs-client</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- WP2 Audit BS Server -->
|
||||
<dependency>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>wp2-be-audit-bs-server</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="audit-bs [clean,install] skipTests" type="MavenRunConfiguration" factoryName="Maven">
|
||||
<MavenSettings>
|
||||
<option name="myGeneralSettings" />
|
||||
<option name="myRunnerSettings">
|
||||
<MavenRunnerSettings>
|
||||
<option name="delegateBuildToMaven" value="false" />
|
||||
<option name="environmentProperties">
|
||||
<map />
|
||||
</option>
|
||||
<option name="jreName" value="#USE_PROJECT_JDK" />
|
||||
<option name="mavenProperties">
|
||||
<map />
|
||||
</option>
|
||||
<option name="passParentEnv" value="true" />
|
||||
<option name="runMavenInBackground" value="true" />
|
||||
<option name="skipTests" value="true" />
|
||||
<option name="vmOptions" value="" />
|
||||
</MavenRunnerSettings>
|
||||
</option>
|
||||
<option name="myRunnerParameters">
|
||||
<MavenRunnerParameters>
|
||||
<option name="cmdOptions" />
|
||||
<option name="profiles">
|
||||
<set />
|
||||
</option>
|
||||
<option name="goals">
|
||||
<list>
|
||||
<option value="clean" />
|
||||
<option value="install" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="multimoduleDir" />
|
||||
<option name="pomFileName" />
|
||||
<option name="profilesMap">
|
||||
<map />
|
||||
</option>
|
||||
<option name="projectsCmdOptionValues">
|
||||
<list />
|
||||
</option>
|
||||
<option name="resolveToWorkspace" value="false" />
|
||||
<option name="workingDirPath" value="$PROJECT_DIR$/../wp2-be-audit-bs" />
|
||||
</MavenRunnerParameters>
|
||||
</option>
|
||||
</MavenSettings>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="audit-bs [clean,install]" type="MavenRunConfiguration" factoryName="Maven">
|
||||
<MavenSettings>
|
||||
<option name="myGeneralSettings" />
|
||||
<option name="myRunnerSettings" />
|
||||
<option name="myRunnerParameters">
|
||||
<MavenRunnerParameters>
|
||||
<option name="cmdOptions" />
|
||||
<option name="profiles">
|
||||
<set />
|
||||
</option>
|
||||
<option name="goals">
|
||||
<list>
|
||||
<option value="clean" />
|
||||
<option value="install" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="multimoduleDir" />
|
||||
<option name="pomFileName" />
|
||||
<option name="profilesMap">
|
||||
<map />
|
||||
</option>
|
||||
<option name="projectsCmdOptionValues">
|
||||
<list />
|
||||
</option>
|
||||
<option name="resolveToWorkspace" value="false" />
|
||||
<option name="workingDirPath" value="$PROJECT_DIR$/../wp2-be-audit-bs" />
|
||||
</MavenRunnerParameters>
|
||||
</option>
|
||||
</MavenSettings>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="audit-bs all test" type="JUnit" factoryName="JUnit">
|
||||
<module name="wp2-be-audit-bs-server" />
|
||||
<option name="PACKAGE_NAME" value="com.finconsgroup.itserr.marketplace.audit.bs" />
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="package" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Xshare:off" />
|
||||
<option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="audit-bs run develop" type="Application" factoryName="Application">
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="21" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||
<envs>
|
||||
<env name="spring.profiles.active" value="develop" />
|
||||
<env name="audit_bs_swagger_api_server_url" value="http://localhost:8080/api/v1/bs" />
|
||||
<env name="audit_dm_client_url" value="https://apisix-itserr.d4science.org/api/dm" />
|
||||
<env name="audit_bs_messaging_enabled" value="false" />
|
||||
</envs>
|
||||
<option name="MAIN_CLASS_NAME" value="com.finconsgroup.itserr.marketplace.audit.bs.AuditBsApplication" />
|
||||
<module name="wp2-be-audit-bs-server" />
|
||||
<option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="audit-bs run local port per ms" type="Application" factoryName="Application">
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="21" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||
<envs>
|
||||
<env name="spring.profiles.active" value="local" />
|
||||
<env name="server.port" value="8098" />
|
||||
<env name="audit_bs_swagger_api_server_url" value="http://localhost:8098/api/v1/bs" />
|
||||
<env name="audit_dm_client_url" value="http://localhost:8097/api/v1/dm" />
|
||||
</envs>
|
||||
<option name="MAIN_CLASS_NAME" value="com.finconsgroup.itserr.marketplace.audit.bs.AuditBsApplication" />
|
||||
<module name="wp2-be-audit-bs-server" />
|
||||
<option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="audit-bs run local" type="Application" factoryName="Application">
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="21" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||
<envs>
|
||||
<env name="spring.profiles.active" value="local" />
|
||||
</envs>
|
||||
<option name="MAIN_CLASS_NAME" value="com.finconsgroup.itserr.marketplace.audit.bs.AuditBsApplication" />
|
||||
<module name="wp2-be-audit-bs-server" />
|
||||
<option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>wp2-be-audit-bs</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>wp2-be-audit-bs-client</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>wp2-be-audit-bs-client</name>
|
||||
<description>Audit Bs Client Library</description>
|
||||
|
||||
<properties>
|
||||
<!-- Skip repackage as it does not have a main class -->
|
||||
<spring-boot.repackage.skip>true</spring-boot.repackage.skip>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- WP2 Core Library Web -->
|
||||
<dependency>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>core-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- WP2 Audit DM Client -->
|
||||
<dependency>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>wp2-be-audit-dm-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<!-- Maven Compiler Plugin -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* Input DTO for creating AuditLog.
|
||||
*/
|
||||
@Schema(name = "InputCreateAuditLogDto", description = "DTO for creating AuditLog")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@SuperBuilder
|
||||
@AllArgsConstructor
|
||||
public class InputCreateAuditLogDto extends com.finconsgroup.itserr.marketplace.audit.dm.dto.InputCreateAuditLogDto {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* Output DTO representing a created AuditLog.
|
||||
*/
|
||||
@Schema(name = "OutputAuditLogDto", description = "DTO representing a AuditLog in responses")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@SuperBuilder
|
||||
@AllArgsConstructor
|
||||
public class OutputAuditLogDto extends com.finconsgroup.itserr.marketplace.audit.dm.dto.OutputAuditLogDto {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>wp2-be-audit-bs</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>wp2-be-audit-bs-server</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>wp2-be-audit-bs-server</name>
|
||||
<description>Audit Bs Application</description>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- WP2 Core Library Logging -->
|
||||
<dependency>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>core-logging</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- WP2 Core Library Web -->
|
||||
<dependency>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>core-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- WP2 Core Library Metrics -->
|
||||
<dependency>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>core-metrics</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- WP2 Core Library i18n -->
|
||||
<dependency>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>core-i18n</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- WP2 Core Library messaging -->
|
||||
<dependency>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>core-messaging</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- WP2 Audit BS Client -->
|
||||
<dependency>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>wp2-be-audit-bs-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Open Api SpringDoc -->
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Mapstruct -->
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Rest Assured -->
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- WP2 Core Library Web Test -->
|
||||
<dependency>
|
||||
<groupId>com.finconsgroup.itserr.marketplace</groupId>
|
||||
<artifactId>core-web-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Test Containers -->
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>testcontainers</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Test Containers RabbitMq -->
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>rabbitmq</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<!-- Maven Compiler Plugin -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok-mapstruct-binding</artifactId>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<compilerArgs>
|
||||
-Amapstruct.unmappedTargetPolicy=ERROR
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Surefire Plugin -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<!--
|
||||
-javaagent:...
|
||||
Added to fix java agent warning while running tests
|
||||
Dynamic loading of agents will be disallowed by default in a future release
|
||||
https://stackoverflow.com/a/79213258/9714611
|
||||
-->
|
||||
<!--
|
||||
-Xshare:off
|
||||
Disable Class Data Sharing (CDS) during test execution to avoid JVM warnings like:
|
||||
"Sharing is only supported for boot loader classes because bootstrap classpath has been appended".
|
||||
This setting applies only to tests run by the Maven Surefire Plugin.
|
||||
-->
|
||||
<argLine>-javaagent:${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar -Xshare:off @{argLine}</argLine>
|
||||
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
<include>**/*IT.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Jacoco Plugin -->
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>${jacoco-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare-agent</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>report</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs;
|
||||
|
||||
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
|
||||
import io.swagger.v3.oas.annotations.info.Info;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
|
||||
@SpringBootApplication
|
||||
@OpenAPIDefinition(info = @Info(
|
||||
title = "Audit BS API",
|
||||
description = "API definition of the Audit Microservice",
|
||||
version = "1.0.1"
|
||||
))
|
||||
@EnableConfigurationProperties({com.finconsgroup.itserr.marketplace.audit.bs.configuration.properties.AuditBsConfigurationProperties.class})
|
||||
public class AuditBsApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AuditBsApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.api;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
/**
|
||||
* This interface defines the contract for REST API endpoints used for system testing and debugging.
|
||||
*
|
||||
* <p>
|
||||
* These endpoints are intended for internal use only and
|
||||
* provide endpoints used for debugging and runtime analysis.
|
||||
* </p>
|
||||
*
|
||||
* <p>Example usage:
|
||||
* <pre>
|
||||
* GET /api/v1/bs/diagnostics/download-logs - Download application log for analysis
|
||||
* </pre>
|
||||
* </p>
|
||||
*/
|
||||
@Tag(
|
||||
name = "Diagnostics",
|
||||
description = "Diagnostics API: provides endpoints used for " +
|
||||
"debugging and runtime analysis."
|
||||
)
|
||||
@SecurityRequirement(name = "BearerAuth")
|
||||
public interface DiagnosticsApi {
|
||||
|
||||
@Operation(
|
||||
summary = "Download log file",
|
||||
responses = {@ApiResponse(responseCode = "200", description = "OK"),}
|
||||
)
|
||||
@GetMapping(path = "/audit/diagnostics/download-logs", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
||||
ResponseEntity<Resource> downloadLogs();
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.configuration.properties;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
/**
|
||||
* Configuration properties for the AuditLog bs service.
|
||||
* <p>
|
||||
* These properties are mapped from the {@code audit.bs} prefix in the application configuration.
|
||||
*/
|
||||
@Data
|
||||
@Validated
|
||||
@ConfigurationProperties(prefix = "audit.bs")
|
||||
public class AuditBsConfigurationProperties {
|
||||
|
||||
/**
|
||||
* Base URL used by Swagger/OpenAPI documentation.
|
||||
* Example: {@code http://localhost:8080}
|
||||
*/
|
||||
@NotBlank
|
||||
private String swaggerApiServerUrl;
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.controller;
|
||||
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.api.DiagnosticsApi;
|
||||
import com.finconsgroup.itserr.marketplace.core.web.exception.WP2ResourceNotFoundException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.core.LoggerContext;
|
||||
import org.apache.logging.log4j.core.appender.RollingFileAppender;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* REST controller class for handling debugging/analysis related API requests.
|
||||
*
|
||||
* <p>Implements the {@link DiagnosticsApi} interface.</p>
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
public class DiagnosticsController implements DiagnosticsApi {
|
||||
|
||||
// The name of the RollingFile Log4j2 component
|
||||
// It is not the name of the log file
|
||||
// We use this to dynamically retrieve the name of the log file.
|
||||
@Value("${log.log4j2-rolling-file-name}")
|
||||
private String log4j2RollingFileName;
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Resource> downloadLogs() {
|
||||
log.debug("call to DiagnosticsController - downloadLogs");
|
||||
Path filePath = Paths.get(getLogFilePathFromLog4j2());
|
||||
log.debug("Trying to retrieve log file from: {}", filePath);
|
||||
File logFile = filePath.toFile();
|
||||
if (!logFile.exists() || !logFile.isFile()) {
|
||||
throw new WP2ResourceNotFoundException("Log file not found: %s".formatted(logFile.getAbsolutePath()));
|
||||
}
|
||||
Resource resource = new FileSystemResource(logFile);
|
||||
return ResponseEntity.ok()
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, getContentDispositionHeaderValue(logFile.getName()))
|
||||
.contentType(MediaType.APPLICATION_OCTET_STREAM)
|
||||
.body(resource);
|
||||
}
|
||||
|
||||
// private
|
||||
|
||||
public String getLogFilePathFromLog4j2() {
|
||||
LoggerContext context = (LoggerContext) LogManager.getContext(false);
|
||||
RollingFileAppender appender = context.getConfiguration().getAppender(log4j2RollingFileName);
|
||||
return appender.getFileName();
|
||||
}
|
||||
|
||||
private static String getContentDispositionHeaderValue(String fileName) {
|
||||
return "attachment; filename=\"%s\"".formatted(fileName);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.mapper;
|
||||
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.dto.InputCreateAuditLogDto;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.dto.OutputAuditLogDto;
|
||||
import com.finconsgroup.itserr.messaging.dto.UntypedMessagingEventDto;
|
||||
import io.cloudevents.CloudEvent;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Named;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Optional;
|
||||
|
||||
@Mapper(config = MapperConfiguration.class)
|
||||
public interface AuditLogMapper {
|
||||
|
||||
String NAME_CLOUD_EVENT_SOURCE_TO_STRING = "cloudEventSourceToString";
|
||||
|
||||
@Mapping(target = "eventSource", source = "cloudEvent.source", qualifiedByName = NAME_CLOUD_EVENT_SOURCE_TO_STRING)
|
||||
@Mapping(target = "eventType", source = "cloudEvent.type")
|
||||
@Mapping(target = "user", source = "messagingEventDto.user")
|
||||
@Mapping(target = "resource.id", source = "messagingEventDto.id")
|
||||
@Mapping(target = "resource.name", source = "messagingEventDto.name")
|
||||
@Mapping(target = "resource.title", source = "messagingEventDto.title")
|
||||
@Mapping(target = "resource.status", source = "messagingEventDto.status")
|
||||
@Mapping(target = "resource.category", source = "messagingEventDto.category")
|
||||
@Mapping(target = "eventMessage", source = "messagingEventDto.message")
|
||||
@Mapping(target = "eventActionTime", source = "messagingEventDto.timestamp")
|
||||
@Mapping(target = "eventAdditionalData", source = "messagingEventDto.additionalData")
|
||||
@Mapping(target = "eventCreationTime", source = "cloudEvent.time")
|
||||
InputCreateAuditLogDto messagingEventToInputCreateAuditLogDto(UntypedMessagingEventDto messagingEventDto, CloudEvent cloudEvent);
|
||||
|
||||
OutputAuditLogDto auditLogDmDtoToBsDto(com.finconsgroup.itserr.marketplace.audit.dm.dto.OutputAuditLogDto outputAuditLogDmDto);
|
||||
|
||||
@Named(NAME_CLOUD_EVENT_SOURCE_TO_STRING)
|
||||
default String cloudEventSourceToString(URI source) {
|
||||
return source != null ? source.toString() : null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
default Instant offsetDateTimeToInstant(OffsetDateTime offsetDateTime) {
|
||||
return Optional.ofNullable(offsetDateTime).map(OffsetDateTime::toInstant).orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.mapper;
|
||||
|
||||
import org.mapstruct.MapperConfig;
|
||||
import org.mapstruct.MappingConstants;
|
||||
|
||||
@MapperConfig(
|
||||
componentModel = MappingConstants.ComponentModel.SPRING
|
||||
)
|
||||
public interface MapperConfiguration {
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.messaging;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.dto.OutputAuditLogDto;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.service.AuditLogService;
|
||||
import com.finconsgroup.itserr.messaging.consumer.AbstractEventSubscriber;
|
||||
import com.finconsgroup.itserr.messaging.consumer.AbstractResourceSubscriber;
|
||||
import com.finconsgroup.itserr.messaging.dto.UntypedMessagingEventDto;
|
||||
import io.cloudevents.CloudEvent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Concrete implementation of {@link AbstractResourceSubscriber} for handling catalog-related resource events.
|
||||
*/
|
||||
@Component("messagingEventSubscriber")
|
||||
@Slf4j
|
||||
public class MessagingEventSubscriber extends AbstractEventSubscriber {
|
||||
private static final TypeReference<UntypedMessagingEventDto> TYPE_REFERENCE = new TypeReference<>() {
|
||||
};
|
||||
|
||||
private final AuditLogService auditLogService;
|
||||
|
||||
public MessagingEventSubscriber(AuditLogService auditLogService) {
|
||||
super(TYPE_REFERENCE);
|
||||
this.auditLogService = auditLogService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <V> void handleEvent(V eventData, @NonNull CloudEvent cloudEvent) {
|
||||
if (eventData instanceof UntypedMessagingEventDto untypedMessagingEventDto) {
|
||||
OutputAuditLogDto outputAuditLogDto = auditLogService.createFromMessagingEvent(untypedMessagingEventDto, cloudEvent);
|
||||
log.info("Created audit log with id: {}", outputAuditLogDto.getId());
|
||||
} else {
|
||||
log.warn("Unhandled event type: {}", cloudEvent.getType());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.openapi;
|
||||
|
||||
import io.swagger.v3.oas.models.servers.Server;
|
||||
import org.springdoc.core.customizers.OpenApiCustomizer;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
public class OpenApiConfiguration {
|
||||
|
||||
@Value("${audit.bs.swagger-api-server-url}")
|
||||
private String swaggerApiServer;
|
||||
|
||||
@Bean
|
||||
public OpenApiCustomizer customServerOpenApiCustomizer() {
|
||||
return openApi -> openApi
|
||||
.setServers(List.of(new Server().url(swaggerApiServer)));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.service;
|
||||
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.dto.InputCreateAuditLogDto;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.dto.OutputAuditLogDto;
|
||||
import com.finconsgroup.itserr.messaging.dto.UntypedMessagingEventDto;
|
||||
import io.cloudevents.CloudEvent;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
/**
|
||||
* Service for handling business logic related to AuditLog. This interface provides methods to retrieve, create, update, and delete AuditLog,
|
||||
*
|
||||
* <p>Example usage:
|
||||
* <pre>
|
||||
* Page<OutputAuditLogDto> AuditLog = AuditLogService.findAll(pageable);
|
||||
* </pre>
|
||||
* </p>
|
||||
*/
|
||||
public interface AuditLogService {
|
||||
|
||||
/**
|
||||
* Creates new AuditLog for user using the provided input data.
|
||||
*
|
||||
* @param inputCreateAuditLogDto the input DTO containing AuditLog details
|
||||
*/
|
||||
@NonNull
|
||||
OutputAuditLogDto create(@NonNull InputCreateAuditLogDto inputCreateAuditLogDto);
|
||||
|
||||
/**
|
||||
* Creates new audit log using the provided input data.
|
||||
*
|
||||
* @param messagingEventDto the input messaging event DTO containing audit log details
|
||||
*/
|
||||
@NonNull
|
||||
OutputAuditLogDto createFromMessagingEvent(@NonNull UntypedMessagingEventDto messagingEventDto,
|
||||
@NonNull CloudEvent cloudEvent);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.service.impl;
|
||||
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.dto.InputCreateAuditLogDto;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.dto.OutputAuditLogDto;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.mapper.AuditLogMapper;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.service.AuditLogService;
|
||||
import com.finconsgroup.itserr.marketplace.audit.dm.client.AuditDmClient;
|
||||
import com.finconsgroup.itserr.messaging.dto.UntypedMessagingEventDto;
|
||||
import io.cloudevents.CloudEvent;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link AuditLogService} to perform operations related to AuditLog resources
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class DefaultAuditLogService implements AuditLogService {
|
||||
|
||||
private final AuditDmClient auditDmClient;
|
||||
private final AuditLogMapper auditLogMapper;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public OutputAuditLogDto create(@NonNull InputCreateAuditLogDto inputCreateAuditLogDto) {
|
||||
com.finconsgroup.itserr.marketplace.audit.dm.dto.OutputAuditLogDto outputAuditLogDmDto =
|
||||
auditDmClient.createAuditLog(inputCreateAuditLogDto);
|
||||
return auditLogMapper.auditLogDmDtoToBsDto(outputAuditLogDmDto);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public OutputAuditLogDto createFromMessagingEvent(@NonNull UntypedMessagingEventDto messagingEventDto,
|
||||
@NonNull CloudEvent cloudEvent) {
|
||||
InputCreateAuditLogDto dto = auditLogMapper.messagingEventToInputCreateAuditLogDto(messagingEventDto, cloudEvent);
|
||||
return create(dto);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
audit_bs_server_port: 8080
|
||||
|
||||
audit_bs_zipkin_tracing_export_enabled: false
|
||||
|
||||
audit_bs_swagger_api_server_url: https://apisix-itserr.d4science.org/api/bs
|
||||
|
||||
audit_dm_client_url: http://be-audit-dm:8080/api/v1/dm
|
||||
|
||||
# Messaging
|
||||
audit_bs_messaging_enabled: true
|
||||
audit_bs_messaging_host: ${WP2_RABBITMQ_IP}
|
||||
audit_bs_messaging_port: ${WP2_RABBITMQ_PORT}
|
||||
audit_bs_messaging_vhost: ${WP2_RABBITMQ_VHOST}
|
||||
audit_bs_messaging_auth_keycloak_token_url: https://${WP2_KEYCLOAK_HOSTNAME}/auth/realms/d4science/protocol/openid-connect/token
|
||||
audit_bs_messaging_auth_client_id: ${WP2_RABBITMQ_CLIENTID}
|
||||
audit_bs_messaging_auth_client_secret: ${WP2_RABBITMQ_SECRET}
|
||||
|
||||
audit_bs_messaging_catalog_bs_event_stream_consumer_enabled: true
|
||||
audit_bs_messaging_catalog_bs_event_stream_name: itserr-stream-catalog-event
|
||||
audit_bs_messaging_catalog_bs_event_stream_consumer_dlq_name: itserr-stream-catalog-event-dlq
|
||||
audit_bs_messaging_event_bs_event_stream_consumer_enabled: true
|
||||
audit_bs_messaging_event_bs_event_stream_name: itserr-stream-event-notification
|
||||
audit_bs_messaging_event_bs_event_stream_consumer_dlq_name: itserr-stream-event-notification-dlq
|
||||
audit_bs_messaging_workspace_bs_event_stream_consumer_enabled: true
|
||||
audit_bs_messaging_workspace_bs_event_stream_name: itserr-stream-workspace-event
|
||||
audit_bs_messaging_workspace_bs_event_stream_consumer_dlq_name: itserr-stream-workspace-event-dlq
|
||||
|
||||
#diagnostics
|
||||
audit_bs_diagnostics_publish_message_enabled: true
|
||||
|
||||
# based on the current Dockerfile, the containerized application
|
||||
# only has permission to create folders inside the /app folder
|
||||
audit_bs_log_base_folder: /app/logs
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
audit_bs_server_port: 8080
|
||||
|
||||
audit_bs_zipkin_tracing_export_enabled: false
|
||||
|
||||
audit_bs_swagger_api_server_url: http://localhost:8080/api/v1/bs
|
||||
|
||||
audit_dm_client_url: http://localhost:8080/api/v1/dm
|
||||
|
||||
# Messaging
|
||||
audit_bs_messaging_enabled: false
|
||||
audit_bs_messaging_host: localhost
|
||||
audit_bs_messaging_port: 5552
|
||||
audit_bs_messaging_vhost: itserr_vhost
|
||||
audit_bs_messaging_auth_keycloak_token_url:
|
||||
audit_bs_messaging_auth_client_id: guest
|
||||
audit_bs_messaging_auth_client_secret: guest
|
||||
|
||||
audit_bs_messaging_catalog_bs_event_stream_consumer_enabled: true
|
||||
audit_bs_messaging_catalog_bs_event_stream_name: itserr-stream-catalog-event
|
||||
audit_bs_messaging_catalog_bs_event_stream_consumer_dlq_name: itserr-stream-catalog-event-dlq
|
||||
audit_bs_messaging_event_bs_event_stream_consumer_enabled: true
|
||||
audit_bs_messaging_event_bs_event_stream_name: itserr-stream-event-notification
|
||||
audit_bs_messaging_event_bs_event_stream_consumer_dlq_name: itserr-stream-event-notification-dlq
|
||||
audit_bs_messaging_workspace_bs_event_stream_consumer_enabled: true
|
||||
audit_bs_messaging_workspace_bs_event_stream_name: itserr-stream-workspace-event
|
||||
audit_bs_messaging_workspace_bs_event_stream_consumer_dlq_name: itserr-stream-workspace-event-dlq
|
||||
|
||||
audit_bs_log_base_folder: logs
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.finconsgroup.itserr.messaging.utils.CloudEventUtil: TRACE
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
server:
|
||||
port: ${audit_bs_server_port}
|
||||
servlet:
|
||||
context-path: /api/v1/bs
|
||||
forward-headers-strategy: NATIVE
|
||||
|
||||
spring:
|
||||
|
||||
profiles:
|
||||
group:
|
||||
develop:
|
||||
- develop
|
||||
- log-files
|
||||
- json-logs
|
||||
local:
|
||||
- local
|
||||
- log-files
|
||||
|
||||
application:
|
||||
name: wp2-be-audit-bs
|
||||
|
||||
config:
|
||||
import: 'optional:configserver:,optional:file:/run/secrets/wp2_services_secret.yml'
|
||||
|
||||
jackson:
|
||||
mapper:
|
||||
allow-coercion-of-scalars: false
|
||||
deserialization:
|
||||
accept-float-as-int: false
|
||||
|
||||
springdoc:
|
||||
api-docs:
|
||||
path: /audit/api-docs
|
||||
swagger-ui:
|
||||
url: /audit/api-docs
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: '*'
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
zipkin:
|
||||
tracing:
|
||||
export:
|
||||
enabled: ${audit_bs_zipkin_tracing_export_enabled}
|
||||
|
||||
web:
|
||||
exception-handler:
|
||||
method-validation-exception:
|
||||
field-name-on-field-error: true
|
||||
|
||||
api:
|
||||
client:
|
||||
enabled: true
|
||||
instances:
|
||||
audit-dm-client:
|
||||
bean-name: AuditDmClient
|
||||
client-type: FEIGN
|
||||
service-interface-class: com.finconsgroup.itserr.marketplace.audit.dm.client.AuditDmClient
|
||||
base-url: ${audit_dm_client_url}
|
||||
jwt-request-interceptor-enabled: true
|
||||
jwt-request-interceptor-lenient: true
|
||||
error-decoder-bean-name: feignCoreErrorDecoder
|
||||
|
||||
audit:
|
||||
bs:
|
||||
swagger-api-server-url: ${audit_bs_swagger_api_server_url}
|
||||
|
||||
consumer-defaults: &consumer_defaults
|
||||
enabled: true
|
||||
name: audit-bs-consumer
|
||||
handler-bean-name: messagingEventSubscriber
|
||||
concurrency: ${audit_bs_messaging_default_event_stream_consumer_concurrency:1}
|
||||
retry-attempts: ${audit_bs_messaging_default_event_stream_consumer_retry_attempts:3}
|
||||
retry-backoff-ms: ${audit_bs_messaging_default_event_stream_consumer_retry_backoff_ms:1000}
|
||||
offset-strategy: ${audit_bs_messaging_default_event_stream_consumer_offset_strategy:NEXT}
|
||||
exact-offset: ${audit_bs_messaging_default_event_stream_consumer_exact_offset:0}
|
||||
single-active-consumer: ${audit_bs_messaging_default_event_stream_consumer_single_active_consumer:false}
|
||||
|
||||
# Messaging
|
||||
messaging:
|
||||
enabled: ${audit_bs_messaging_enabled}
|
||||
clients:
|
||||
- platform: RABBITMQ
|
||||
host: ${audit_bs_messaging_host}
|
||||
port: ${audit_bs_messaging_port}
|
||||
vhost: ${audit_bs_messaging_vhost}
|
||||
enable-address-resolution: true
|
||||
refresh-delay: 20s
|
||||
refresh-period: 20s
|
||||
keycloak-token-url: ${audit_bs_messaging_auth_keycloak_token_url}
|
||||
username: ${audit_bs_messaging_auth_client_id}
|
||||
password: ${audit_bs_messaging_auth_client_secret}
|
||||
grant-type: client_credentials
|
||||
oauth-parameters:
|
||||
scope: openid profile email
|
||||
streams:
|
||||
- name: ${audit_bs_messaging_catalog_bs_event_stream_name}
|
||||
consumer:
|
||||
<<: *consumer_defaults
|
||||
enabled: ${audit_bs_messaging_catalog_bs_event_stream_consumer_enabled}
|
||||
dlq:
|
||||
name: ${audit_bs_messaging_catalog_bs_event_stream_consumer_dlq_name}
|
||||
- name: ${audit_bs_messaging_event_bs_event_stream_name}
|
||||
consumer:
|
||||
<<: *consumer_defaults
|
||||
enabled: ${audit_bs_messaging_event_bs_event_stream_consumer_enabled}
|
||||
dlq:
|
||||
name: ${audit_bs_messaging_event_bs_event_stream_consumer_dlq_name}
|
||||
- name: ${audit_bs_messaging_workspace_bs_event_stream_name}
|
||||
consumer:
|
||||
<<: *consumer_defaults
|
||||
enabled: ${audit_bs_messaging_workspace_bs_event_stream_consumer_enabled}
|
||||
dlq:
|
||||
name: ${audit_bs_messaging_workspace_bs_event_stream_consumer_dlq_name}
|
||||
|
||||
|
||||
# Logging
|
||||
log:
|
||||
log4j2-rolling-file-name: file1App
|
||||
folder: ${audit_bs_log_base_folder}
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.finconsgroup.itserr.marketplace: DEBUG
|
||||
feign: DEBUG
|
||||
com.rabbitmq: DEBUG
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.messaging.integration_tests;
|
||||
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.util.RabbitMqContainerHelper;
|
||||
import com.finconsgroup.itserr.marketplace.core.web.test.WireMockServerTest;
|
||||
import io.restassured.RestAssured;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||
import org.springframework.test.context.DynamicPropertySource;
|
||||
import org.testcontainers.containers.RabbitMQContainer;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Base class for integration tests.
|
||||
* <p>
|
||||
* This class sets up the application context with a Testcontainer
|
||||
* and configures RestAssured to communicate with the randomly assigned port
|
||||
* of the Spring Boot application.
|
||||
*/
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
@ActiveProfiles("integration-test")
|
||||
@Slf4j
|
||||
public class AbstractIntegrationTest implements WireMockServerTest {
|
||||
|
||||
public static final String SPRING_AUDIT_DM_CLIENT_URL_KEY = "audit_dm_client_url";
|
||||
private static RabbitMQContainer rabbitMQContainer;
|
||||
|
||||
@LocalServerPort
|
||||
private int localServerPort;
|
||||
|
||||
/**
|
||||
* Starts the RabbitMq container before all tests.
|
||||
*/
|
||||
@BeforeAll
|
||||
static void beforeAll() throws IOException, InterruptedException {
|
||||
rabbitMQContainer = RabbitMqContainerHelper.startRabbitMqContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers dynamic properties for the Spring context
|
||||
* using the running RabbitMq container.
|
||||
* <p>
|
||||
* These properties must be defined programmatically at runtime.
|
||||
* Setting these properties statically in {@code application-*.yml}
|
||||
* will not work, Spring will fail to connect to the container.
|
||||
* </p>
|
||||
*
|
||||
* @param registry dynamic property registry to be populated
|
||||
*/
|
||||
@DynamicPropertySource
|
||||
static void startRabbitMqContainerAndSetProperties(DynamicPropertyRegistry registry) {
|
||||
RabbitMqContainerHelper.setDynamicPropertyRegistry(registry, rabbitMQContainer);
|
||||
registry.add(SPRING_AUDIT_DM_CLIENT_URL_KEY,
|
||||
() -> getaUDITDmClientUrlValue(WireMockServerTest.getWireMockServerPort()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures RestAssured to use the port assigned by Spring Boot.
|
||||
*/
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
RestAssured.port = localServerPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the RabbitMq container after all tests are completed.
|
||||
*/
|
||||
@AfterAll
|
||||
static void afterAll() {
|
||||
RabbitMqContainerHelper.stopRabbitMqContainer(rabbitMQContainer);
|
||||
}
|
||||
|
||||
// private
|
||||
|
||||
private static String getaUDITDmClientUrlValue(int port) {
|
||||
return "http://localhost:%s/api/v1/dm".formatted(port);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.messaging.integration_tests;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.messaging.MessagingEventSubscriber;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.util.MessagingUtils;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.util.MockUtils;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.util.TestConstants;
|
||||
import com.finconsgroup.itserr.marketplace.audit.dm.dto.InputCreateAuditLogDto;
|
||||
import com.finconsgroup.itserr.messaging.dto.UntypedMessagingEventDto;
|
||||
import com.finconsgroup.itserr.messaging.utils.CloudEventUtil;
|
||||
import com.rabbitmq.stream.Environment;
|
||||
import com.rabbitmq.stream.Message;
|
||||
import com.rabbitmq.stream.Producer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.finconsgroup.itserr.marketplace.audit.bs.util.TestConstants.MAX_WAIT_TIME_MESSAGE_HANDLED;
|
||||
import static com.finconsgroup.itserr.marketplace.audit.bs.util.TestConstants.MAX_WAIT_TIME_MESSAGE_PRODUCED;
|
||||
import static com.finconsgroup.itserr.marketplace.audit.bs.util.TestConstants.MESSAGE_RETRY_COUNT;
|
||||
import static com.finconsgroup.itserr.marketplace.audit.bs.util.TestConstants.MESSAGING_STREAM_CONSUMER_DLQ_NAME_VALUE_FORMAT;
|
||||
import static com.finconsgroup.itserr.marketplace.audit.bs.util.TestConstants.MESSAGING_STREAM_NAME_VALUE_FORMAT;
|
||||
import static com.finconsgroup.itserr.marketplace.audit.bs.util.TestConstants.PRODUCER_NAME_ERROR_FORMAT;
|
||||
import static com.finconsgroup.itserr.marketplace.audit.bs.util.TestConstants.PRODUCER_NAME_FORMAT;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.containing;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.post;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MessagingEventSubscriber}
|
||||
* <p>
|
||||
* The class uses Testcontainers to run integration tests against a real rabbitmq instance.
|
||||
* <p>
|
||||
*/
|
||||
@Slf4j
|
||||
public class MessagingEventSubscriberIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
protected ObjectMapper objectMapper;
|
||||
|
||||
@Value("${audit_bs_messaging_host}")
|
||||
private String auditBsMessagingHost;
|
||||
|
||||
@Value("${audit_bs_messaging_port}")
|
||||
private String auditBsMessagingPort;
|
||||
|
||||
@Value("${audit_bs_messaging_vhost}")
|
||||
private String auditBsMessagingVhost;
|
||||
|
||||
@Value("${audit_bs_messaging_auth_client_id}")
|
||||
private String auditBsMessagingAuthClientId;
|
||||
|
||||
@Value("${audit_bs_messaging_auth_client_secret}")
|
||||
private String auditBsMessagingAuthClientSecret;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<Pair<String, UntypedMessagingEventDto>> eventMessageDlqCaptor;
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("givenEventCreated_whenSendMessageToStream_thenMessageReceivedAndSentToDmService_source")
|
||||
void givenEventCreated_whenSendMessageToStream_thenMessageReceivedAndSentToDmService(String stream) throws Exception {
|
||||
|
||||
// given
|
||||
String createdEventType = "%s-event-created".formatted(stream);
|
||||
String source = "%s-bs".formatted(stream);
|
||||
UntypedMessagingEventDto messagePayload = MockUtils.generateUntypedMessagingEventDto();
|
||||
configureCreateAuditLogOnAuditDmWireMock();
|
||||
Producer producer = createProducer(stream, PRODUCER_NAME_FORMAT.formatted(stream, createdEventType));
|
||||
Message message = MessagingUtils.createMessage(
|
||||
producer, messagePayload.getId(), messagePayload, createdEventType, source);
|
||||
InputCreateAuditLogDto expectedCreateAuditLogDto = MockUtils.generateInputCreateAuditLogDto(dto -> {
|
||||
dto.setEventSource(source);
|
||||
dto.setEventType(createdEventType);
|
||||
});
|
||||
|
||||
// when
|
||||
boolean messageSent = MessagingUtils.produceMessage(producer, message, MAX_WAIT_TIME_MESSAGE_PRODUCED);
|
||||
|
||||
// then
|
||||
assertTrue(messageSent, "Cannot publish test message");
|
||||
verifyCreateAuditLogRequestToAuditDm(expectedCreateAuditLogDto);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("givenInvalidMessage_whenSendMessageToStream_thenMessageReceivedAndSentToDlq_source")
|
||||
void givenInvalidMessage_whenSendMessageToStream_thenMessageReceivedAndSentToDlq(String stream) throws Exception {
|
||||
|
||||
// given
|
||||
String createdEventType = "%s-event-created".formatted(stream);
|
||||
Object messagePayload = Map.of("testKey", "testValue");
|
||||
configureCreateAuditLogOnAuditDmWireMockError();
|
||||
Producer producer = createProducer(stream, PRODUCER_NAME_ERROR_FORMAT.formatted(stream, createdEventType));
|
||||
Message message = MessagingUtils.createMessage(
|
||||
producer, UUID.randomUUID().toString(), messagePayload, createdEventType, "%s-bs".formatted(stream));
|
||||
|
||||
Consumer<Pair<String, UntypedMessagingEventDto>> eventMessageDlqConsumer = createMockMessageConsumer();
|
||||
TypeReference<UntypedMessagingEventDto> eventDtoTypeReference = new TypeReference<>() {
|
||||
};
|
||||
|
||||
try (
|
||||
com.rabbitmq.stream.Consumer eventMessageStreamConsumer = createEventMessageStreamDlqConsumer(stream,
|
||||
"%s-created-event".formatted(stream), eventMessageDlqConsumer, eventDtoTypeReference)
|
||||
) {
|
||||
// when
|
||||
boolean messageSent = MessagingUtils.produceMessage(producer, message, MAX_WAIT_TIME_MESSAGE_PRODUCED);
|
||||
|
||||
// then
|
||||
assertTrue(messageSent, "Cannot publish test message");
|
||||
await().atMost(MAX_WAIT_TIME_MESSAGE_HANDLED, TimeUnit.SECONDS).untilAsserted(() ->
|
||||
wireMockServer().verify(MESSAGE_RETRY_COUNT, postRequestedFor(urlEqualTo("/api/v1/dm/audit/audit-logs")))
|
||||
);
|
||||
|
||||
MessagingUtils.verifyMessageProduced(MAX_WAIT_TIME_MESSAGE_HANDLED, () -> {
|
||||
verify(eventMessageDlqConsumer).accept(eventMessageDlqCaptor.capture());
|
||||
assertThat(eventMessageDlqCaptor.getValue().getLeft()).isEqualTo(createdEventType);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// private
|
||||
|
||||
private void configureCreateAuditLogOnAuditDmWireMock() throws Exception {
|
||||
wireMockServer()
|
||||
.stubFor(post(urlEqualTo("/api/v1/dm/audit/audit-logs"))
|
||||
.withHeader("Content-Type", containing("application/json"))
|
||||
.willReturn(aResponse()
|
||||
.withStatus(201)
|
||||
.withHeader("Content-Type", "application/json")
|
||||
.withBody(mapObjectToJson(MockUtils.generateOutputAuditLogDto()))));
|
||||
}
|
||||
|
||||
private void configureCreateAuditLogOnAuditDmWireMockError() throws Exception {
|
||||
wireMockServer()
|
||||
.stubFor(post(urlEqualTo("/api/v1/dm/audit/audit-logs"))
|
||||
.withHeader("Content-Type", containing("application/json"))
|
||||
.willReturn(aResponse()
|
||||
.withStatus(400)
|
||||
.withHeader("Content-Type", "application/json")
|
||||
.withBody(mapObjectToJson(Map.of("messages", List.of("id: cannot be null"))))));
|
||||
}
|
||||
|
||||
private void verifyCreateAuditLogRequestToAuditDm(InputCreateAuditLogDto inputCreateAuditLogDto) throws JsonProcessingException {
|
||||
|
||||
// ignore eventCreationTime
|
||||
inputCreateAuditLogDto.setEventCreationTime(null);
|
||||
String expectedJson = CloudEventUtil.getObjectMapper()
|
||||
.writeValueAsString(inputCreateAuditLogDto)
|
||||
.replaceAll(",\"eventCreationTime\":null", "")
|
||||
.replaceAll("\"eventCreationTime\":null,", "");
|
||||
|
||||
await().atMost(TestConstants.MAX_WAIT_TIME_MESSAGE_HANDLED, TimeUnit.SECONDS).untilAsserted(() ->
|
||||
wireMockServer().verify(postRequestedFor(urlEqualTo("/api/v1/dm/audit/audit-logs"))
|
||||
.withRequestBody(equalToJson(expectedJson, false, true)))
|
||||
);
|
||||
}
|
||||
|
||||
private Producer createProducer(String stream, String producerName) {
|
||||
Environment environment = MessagingUtils.createEnvironment(
|
||||
auditBsMessagingHost,
|
||||
auditBsMessagingPort,
|
||||
auditBsMessagingVhost,
|
||||
auditBsMessagingAuthClientId,
|
||||
auditBsMessagingAuthClientSecret
|
||||
);
|
||||
String streamName = MESSAGING_STREAM_NAME_VALUE_FORMAT.formatted(stream);
|
||||
return MessagingUtils.createProducer(environment, producerName, streamName);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> Consumer<T> createMockMessageConsumer() {
|
||||
return (Consumer<T>) mock(Consumer.class);
|
||||
}
|
||||
|
||||
|
||||
private <T> com.rabbitmq.stream.Consumer createEventMessageStreamDlqConsumer(String stream,
|
||||
String consumerName,
|
||||
Consumer<Pair<String, T>> messageConsumer,
|
||||
TypeReference<T> typeReference) {
|
||||
String streamName = MESSAGING_STREAM_CONSUMER_DLQ_NAME_VALUE_FORMAT.formatted(stream);
|
||||
return createConsumer(consumerName, streamName, typeReference, messageConsumer);
|
||||
}
|
||||
|
||||
private <T> com.rabbitmq.stream.Consumer createConsumer(String consumerName,
|
||||
String streamName,
|
||||
TypeReference<T> typeReference,
|
||||
Consumer<Pair<String, T>> messageConsumer) {
|
||||
Environment environment = MessagingUtils.createEnvironment(
|
||||
auditBsMessagingHost,
|
||||
auditBsMessagingPort,
|
||||
auditBsMessagingVhost,
|
||||
auditBsMessagingAuthClientId,
|
||||
auditBsMessagingAuthClientSecret
|
||||
);
|
||||
return MessagingUtils.createConsumer(environment, consumerName, streamName, typeReference, messageConsumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the object to its json string representation
|
||||
*
|
||||
* @param value the object to map
|
||||
* @return json string representation of the object
|
||||
* @throws Exception in case of any errors
|
||||
*/
|
||||
private String mapObjectToJson(Object value) throws Exception {
|
||||
return objectMapper.writeValueAsString(value);
|
||||
}
|
||||
|
||||
public static Stream<Arguments> givenEventCreated_whenSendMessageToStream_thenMessageReceivedAndSentToDmService_source() {
|
||||
return supportedStreamNames_source();
|
||||
}
|
||||
|
||||
public static Stream<Arguments> givenInvalidMessage_whenSendMessageToStream_thenMessageReceivedAndSentToDlq_source() {
|
||||
return supportedStreamNames_source();
|
||||
}
|
||||
|
||||
public static Stream<Arguments> supportedStreamNames_source() {
|
||||
return TestConstants.SUPPORTED_STREAMS.stream().map(Arguments::of);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.service.impl;
|
||||
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.dto.InputCreateAuditLogDto;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.dto.OutputAuditLogDto;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.mapper.AuditLogMapper;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.util.MockUtils;
|
||||
import com.finconsgroup.itserr.marketplace.audit.dm.client.AuditDmClient;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DefaultAuditLogServiceTest}.
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class DefaultAuditLogServiceTest {
|
||||
|
||||
private AuditDmClient auditDmClient;
|
||||
private AuditLogMapper AuditLogMapper;
|
||||
|
||||
private DefaultAuditLogService service;
|
||||
|
||||
/**
|
||||
* Set up mocks before each test.
|
||||
*/
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
auditDmClient = mock(AuditDmClient.class);
|
||||
AuditLogMapper = mock(AuditLogMapper.class);
|
||||
|
||||
// And a service instance with mocked repository and mapper
|
||||
service = new DefaultAuditLogService(auditDmClient, AuditLogMapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNewAuditLog_whenCreateAuditLog_thenSaveAndReturnDto() {
|
||||
// Given
|
||||
InputCreateAuditLogDto inputDto = MockUtils.generateInputCreateAuditLogDto();
|
||||
OutputAuditLogDto expectedDto = MockUtils.generateOutputAuditLogDto();
|
||||
|
||||
doReturn(expectedDto).when(auditDmClient).createAuditLog(inputDto);
|
||||
doReturn(expectedDto).when(AuditLogMapper).auditLogDmDtoToBsDto(expectedDto);
|
||||
|
||||
// When
|
||||
OutputAuditLogDto result = service.create(inputDto);
|
||||
|
||||
// Then
|
||||
assertThat(result).isEqualTo(expectedDto);
|
||||
|
||||
verify(auditDmClient).createAuditLog(inputDto);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.util;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.finconsgroup.itserr.messaging.utils.CloudEventUtil;
|
||||
import com.rabbitmq.stream.Address;
|
||||
import com.rabbitmq.stream.Consumer;
|
||||
import com.rabbitmq.stream.ConsumerBuilder;
|
||||
import com.rabbitmq.stream.Environment;
|
||||
import com.rabbitmq.stream.Message;
|
||||
import com.rabbitmq.stream.MessageHandler;
|
||||
import com.rabbitmq.stream.OffsetSpecification;
|
||||
import com.rabbitmq.stream.Producer;
|
||||
import io.cloudevents.CloudEvent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.awaitility.core.ThrowingRunnable;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import static org.awaitility.Awaitility.await;
|
||||
|
||||
/**
|
||||
* Utility class for handling RabbitMQ stream messaging operations used in integration tests.
|
||||
* <p>
|
||||
* Provides methods to:
|
||||
* <ul>
|
||||
* <li>Create and configure a RabbitMQ {@link Environment}</li>
|
||||
* <li>Initialize a {@link Producer} with super stream and routing</li>
|
||||
* <li>Create a CloudEvent-based {@link Message}</li>
|
||||
* <li>Send a message with confirmation and timeout control</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Slf4j
|
||||
public class MessagingUtils {
|
||||
|
||||
public static Environment createEnvironment(
|
||||
String host,
|
||||
String port,
|
||||
String virtualHost,
|
||||
String authClientId,
|
||||
String authClientSecret
|
||||
) {
|
||||
Address entryPoint = new Address(host, Integer.parseInt(port));
|
||||
return Environment.builder()
|
||||
.uri(String.format("rabbitmq-stream://%s:%s", host, port))
|
||||
.virtualHost(virtualHost)
|
||||
.username(authClientId)
|
||||
.password(authClientSecret)
|
||||
.addressResolver(address -> entryPoint)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Producer createProducer(
|
||||
Environment environment,
|
||||
String producerName,
|
||||
String superStreamName
|
||||
) {
|
||||
return environment.producerBuilder()
|
||||
.name(producerName)
|
||||
.superStream(superStreamName)
|
||||
.routing(message -> message.getProperties().getMessageIdAsString())
|
||||
.producerBuilder().build();
|
||||
}
|
||||
|
||||
public static Message createMessage(
|
||||
Producer producer,
|
||||
String resourceId,
|
||||
Object resourcePayload,
|
||||
String eventType,
|
||||
String source
|
||||
) throws JsonProcessingException {
|
||||
byte[] cloudEventBytes = CloudEventUtil.createCloudEventPayload(resourcePayload, eventType, source);
|
||||
return producer.messageBuilder()
|
||||
.properties()
|
||||
.messageId(resourceId)
|
||||
.messageBuilder()
|
||||
.addData(cloudEventBytes)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static boolean produceMessage(
|
||||
Producer producer,
|
||||
Message message,
|
||||
long maxWaitTimeMessageProducedInSecond
|
||||
) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
CompletableFuture<Boolean> result = new CompletableFuture<>();
|
||||
producer.send(message, confirmationStatus -> {
|
||||
if (confirmationStatus.isConfirmed()) {
|
||||
result.complete(true);
|
||||
} else {
|
||||
result.complete(false);
|
||||
}
|
||||
});
|
||||
return result.get(maxWaitTimeMessageProducedInSecond, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public static <T> Consumer createConsumer(
|
||||
Environment environment,
|
||||
String consumerName,
|
||||
String superStreamName,
|
||||
TypeReference<T> typeReference,
|
||||
java.util.function.Consumer<Pair<String, T>> messageConsumer
|
||||
) {
|
||||
MessageHandler messageHandler = (context, message) -> {
|
||||
try {
|
||||
// Unique message ID
|
||||
String messageId = message.getProperties().getMessageId().toString();
|
||||
String jsonMessage = new String(message.getBodyAsBinary(), StandardCharsets.UTF_8);
|
||||
|
||||
CloudEvent cloudEvent = CloudEventUtil.deserializeCloudEvent(jsonMessage);
|
||||
context.storeOffset();
|
||||
T data = CloudEventUtil.extractDataWithType(cloudEvent, typeReference);
|
||||
log.info("Successfully processed and Acknowledged message [ID: {}], with data: {}", messageId, data);
|
||||
messageConsumer.accept(Pair.of(cloudEvent.getType(), data));
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ConsumerBuilder consumerBuilder = environment.consumerBuilder()
|
||||
.name(consumerName)
|
||||
.superStream(superStreamName)
|
||||
.offset(OffsetSpecification.next())
|
||||
.messageHandler(messageHandler);
|
||||
consumerBuilder.autoTrackingStrategy();
|
||||
return consumerBuilder.build();
|
||||
}
|
||||
|
||||
public static void verifyMessageProduced(long maxWaitTimeInSeconds, ThrowingRunnable runnable) {
|
||||
await().atMost(maxWaitTimeInSeconds, TimeUnit.SECONDS).untilAsserted(runnable);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.util;
|
||||
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.dto.InputCreateAuditLogDto;
|
||||
import com.finconsgroup.itserr.marketplace.audit.bs.dto.OutputAuditLogDto;
|
||||
import com.finconsgroup.itserr.marketplace.audit.dm.dto.InputAuditLogResourceDto;
|
||||
import com.finconsgroup.itserr.marketplace.audit.dm.dto.InputAuditLogUserDto;
|
||||
import com.finconsgroup.itserr.marketplace.audit.dm.dto.OutputAuditLogResourceDto;
|
||||
import com.finconsgroup.itserr.marketplace.audit.dm.dto.OutputAuditLogUserDto;
|
||||
import com.finconsgroup.itserr.messaging.dto.MessagingEventUserDto;
|
||||
import com.finconsgroup.itserr.messaging.dto.UntypedMessagingEventDto;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Utility class for generating mock DTO instances used in unit tests.
|
||||
* <p>
|
||||
* Provides methods to create fully populated DTOs, including nested objects, to simplify test setup and ensure consistent test data across test cases.
|
||||
* </p>
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
public final class MockUtils {
|
||||
|
||||
private static final Instant EVENT_ACTION_TIME = Instant.now().truncatedTo(ChronoUnit.MICROS);
|
||||
private static final Instant EVENT_CREATION_TIME = EVENT_ACTION_TIME.plus(1, ChronoUnit.HOURS).truncatedTo(ChronoUnit.MICROS);
|
||||
private static final Instant CREATION_TIME = EVENT_ACTION_TIME.plus(2, ChronoUnit.HOURS).truncatedTo(ChronoUnit.MICROS);
|
||||
|
||||
public static final UUID USER_ID = UUID.randomUUID();
|
||||
public static final UUID AUDIT_LOG_ID = UUID.randomUUID();
|
||||
public static final UUID RESOURCE_ID = UUID.randomUUID();
|
||||
|
||||
public static InputCreateAuditLogDto generateInputCreateAuditLogDto() {
|
||||
return InputCreateAuditLogDto.builder()
|
||||
.eventSource("catalog-bs")
|
||||
.eventType("catalog-item-event-created")
|
||||
.user(InputAuditLogUserDto.builder()
|
||||
.id(USER_ID)
|
||||
.username("john.doe1234")
|
||||
.name("John Doe")
|
||||
.build())
|
||||
.resource(InputAuditLogResourceDto.builder()
|
||||
.id(RESOURCE_ID.toString())
|
||||
.name("Talmud")
|
||||
.title("Test Title")
|
||||
.category("dataset")
|
||||
.status("approved")
|
||||
.build())
|
||||
.eventAdditionalData(Map.of("key1", "value1", "key2", "value2"))
|
||||
.eventActionTime(EVENT_ACTION_TIME)
|
||||
.eventCreationTime(EVENT_CREATION_TIME)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static InputCreateAuditLogDto generateInputCreateAuditLogDto(Consumer<InputCreateAuditLogDto> postProcessor) {
|
||||
InputCreateAuditLogDto inputCreateAuditLogDto = MockUtils.generateInputCreateAuditLogDto();
|
||||
postProcessor.accept(inputCreateAuditLogDto);
|
||||
return inputCreateAuditLogDto;
|
||||
}
|
||||
|
||||
public static OutputAuditLogDto generateOutputAuditLogDto() {
|
||||
return OutputAuditLogDto.builder()
|
||||
.id(AUDIT_LOG_ID)
|
||||
.eventSource("catalog-bs")
|
||||
.eventType("catalog-item-event-created")
|
||||
.user(OutputAuditLogUserDto.builder()
|
||||
.id(USER_ID)
|
||||
.username("john.doe1234")
|
||||
.name("John Doe")
|
||||
.build())
|
||||
.resource(OutputAuditLogResourceDto.builder()
|
||||
.id(RESOURCE_ID.toString())
|
||||
.name("Talmud")
|
||||
.title("Test Title")
|
||||
.category("dataset")
|
||||
.status("approved")
|
||||
.build())
|
||||
.eventAdditionalData(Map.of("key1", "value1", "key2", "value2"))
|
||||
.eventActionTime(EVENT_ACTION_TIME)
|
||||
.eventCreationTime(EVENT_CREATION_TIME)
|
||||
.creationTime(CREATION_TIME)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static UntypedMessagingEventDto generateUntypedMessagingEventDto() {
|
||||
return UntypedMessagingEventDto.builder()
|
||||
.id(RESOURCE_ID.toString())
|
||||
.user(MessagingEventUserDto.builder()
|
||||
.id(USER_ID)
|
||||
.username("john.doe1234")
|
||||
.name("John Doe")
|
||||
.build())
|
||||
.name("Talmud")
|
||||
.title("Test Title")
|
||||
.category("dataset")
|
||||
.status("approved")
|
||||
.additionalData(Map.of("key1", "value1", "key2", "value2"))
|
||||
.timestamp(EVENT_ACTION_TIME)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||
import org.testcontainers.containers.RabbitMQContainer;
|
||||
import org.testcontainers.utility.MountableFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.finconsgroup.itserr.marketplace.audit.bs.util.TestConstants.MESSAGING_STREAM_CONSUMER_DLQ_NAME_VALUE_FORMAT;
|
||||
import static com.finconsgroup.itserr.marketplace.audit.bs.util.TestConstants.MESSAGING_STREAM_NAME_VALUE_FORMAT;
|
||||
import static com.finconsgroup.itserr.marketplace.audit.bs.util.TestConstants.SUPPORTED_STREAMS;
|
||||
|
||||
/**
|
||||
* Utility class for managing the lifecycle and configuration
|
||||
* of RabbitMq Testcontainers.
|
||||
*/
|
||||
@Slf4j
|
||||
public class RabbitMqContainerHelper {
|
||||
|
||||
/**
|
||||
* Docker container RabbitMq image name
|
||||
*/
|
||||
private static final String RABBITMQ_IMAGE_NAME = "rabbitmq:3.13.7-management";
|
||||
|
||||
/**
|
||||
* RabbitMq configuration file
|
||||
*/
|
||||
private static final String RABBITMQ_MESSAGING_CONF = "rabbitmq/rabbitmq.conf";
|
||||
|
||||
/**
|
||||
* RabbitMq Container configuration property values.
|
||||
* <p>
|
||||
* These values define messaging settings such as ports, credentials, and stream names,
|
||||
* and are used to configure the RabbitMq container.
|
||||
* </p>
|
||||
*/
|
||||
private static final int MESSAGING_STREAM_PORT_VALUE = 5552;
|
||||
private static final int MESSAGING_UI_MANAGEMENT_PORT_VALUE = 15672;
|
||||
private static final String MESSAGING_USERNAME_VALUE = "test_user";
|
||||
private static final String MESSAGING_PASSWORD_VALUE = "test_password";
|
||||
private static final String MESSAGING_VIRTUAL_HOST_VALUE = "itserr_vhost";
|
||||
|
||||
/**
|
||||
* Messaging property keys.
|
||||
* <p>
|
||||
* These keys are used to dynamically inject container-generated messaging properties
|
||||
* (such as port, virtual host, stream name) at runtime into the Spring context.
|
||||
* Static configuration in {@code application-*.yml} will not work when using Testcontainers.
|
||||
* </p>
|
||||
*/
|
||||
private static final String SPRING_MESSAGING_HOST_KEY = "audit_bs_messaging_host";
|
||||
private static final String SPRING_MESSAGING_PORT_KEY = "audit_bs_messaging_port";
|
||||
private static final String SPRING_MESSAGING_USERNAME_KEY = "audit_bs_messaging_auth_client_id";
|
||||
private static final String SPRING_MESSAGING_PASSWORD_KEY = "audit_bs_messaging_auth_client_secret";
|
||||
private static final String SPRING_MESSAGING_VIRTUAL_HOST_KEY = "audit_bs_messaging_vhost";
|
||||
private static final String SPRING_MESSAGING_STREAM_NAME_KEY_FORMAT = "audit_bs_messaging_%s_bs_event_stream_name";
|
||||
private static final String SPRING_MESSAGING_STREAM_CONSUMER_DLQ_NAME_KEY_FORMAT = "audit_bs_messaging_%s_bs_event_stream_consumer_dlq_name";
|
||||
private static final String SPRING_MESSAGING_STREAM_CONSUMER_ENABLED_KEY_FORMAT = "audit_bs_messaging_%s_bs_event_stream_consumer_enabled";
|
||||
|
||||
/**
|
||||
* Starts a new RabbitMqContainer instance
|
||||
* using predefined configuration constants.
|
||||
*
|
||||
* @return a running instance of RabbitMqContainer
|
||||
*/
|
||||
public static RabbitMQContainer startRabbitMqContainer() throws IOException, InterruptedException {
|
||||
RabbitMQContainer rabbitMqContainer = new RabbitMQContainer(RABBITMQ_IMAGE_NAME)
|
||||
.withExposedPorts(MESSAGING_STREAM_PORT_VALUE, MESSAGING_UI_MANAGEMENT_PORT_VALUE)
|
||||
.withAdminUser(MESSAGING_USERNAME_VALUE)
|
||||
.withAdminPassword(MESSAGING_PASSWORD_VALUE)
|
||||
.withRabbitMQConfig(MountableFile.forClasspathResource(RABBITMQ_MESSAGING_CONF))
|
||||
.withReuse(true);
|
||||
rabbitMqContainer.start();
|
||||
configureRabbitMq(rabbitMqContainer);
|
||||
return rabbitMqContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure RabbitMqContainer instance
|
||||
* Enable plugins, Create virtual host, Create streams
|
||||
*/
|
||||
private static void configureRabbitMq(RabbitMQContainer rabbitMQContainer) throws IOException, InterruptedException {
|
||||
List<String[]> commands = new ArrayList<>();
|
||||
// Enable plugins
|
||||
commands.add(new String[]{"rabbitmq-plugins", "enable", "rabbitmq_management", "rabbitmq_stream"});
|
||||
// Add vhost
|
||||
commands.add(new String[]{"rabbitmqctl", "add_vhost", MESSAGING_VIRTUAL_HOST_VALUE});
|
||||
// Set guest permissions on vhost
|
||||
commands.add(new String[]{"rabbitmqctl", "set_permissions", "-p", MESSAGING_VIRTUAL_HOST_VALUE, MESSAGING_USERNAME_VALUE, ".*", ".*", ".*"});
|
||||
|
||||
for (String stream : SUPPORTED_STREAMS) {
|
||||
// Create event super stream
|
||||
commands.add(new String[]{
|
||||
"rabbitmq-streams", "add_super_stream", MESSAGING_STREAM_NAME_VALUE_FORMAT.formatted(stream),
|
||||
"--vhost", MESSAGING_VIRTUAL_HOST_VALUE, "--partitions", "3"
|
||||
});
|
||||
// Create event dlq super stream
|
||||
commands.add(new String[]{
|
||||
"rabbitmq-streams", "add_super_stream", MESSAGING_STREAM_CONSUMER_DLQ_NAME_VALUE_FORMAT.formatted(stream),
|
||||
"--vhost", MESSAGING_VIRTUAL_HOST_VALUE, "--partitions", "3"
|
||||
});
|
||||
}
|
||||
|
||||
for (String[] command : commands) {
|
||||
rabbitMQContainer.execInContainer(command);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the provided RabbitMqContainer instance.
|
||||
*
|
||||
* @param rabbitMqContainer the container to stop
|
||||
*/
|
||||
public static void stopRabbitMqContainer(RabbitMQContainer rabbitMqContainer) {
|
||||
if (rabbitMqContainer != null && rabbitMqContainer.isRunning()) {
|
||||
rabbitMqContainer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers dynamic properties for the
|
||||
* Spring test context using the given container.
|
||||
* <p>
|
||||
* These properties must be defined programmatically at runtime.
|
||||
* Setting these properties statically in {@code application-*.yml}
|
||||
* will not work, Spring will fail to connect to the container.
|
||||
* </p>
|
||||
*
|
||||
* @param registry the dynamic property registry to populate
|
||||
* @param rabbitMqContainer the RabbitMq container instance
|
||||
*/
|
||||
public static void setDynamicPropertyRegistry(DynamicPropertyRegistry registry, RabbitMQContainer rabbitMqContainer) {
|
||||
|
||||
String host = rabbitMqContainer.getHost();
|
||||
int streamPort = rabbitMqContainer.getMappedPort(MESSAGING_STREAM_PORT_VALUE);
|
||||
int uiManagementPort = rabbitMqContainer.getMappedPort(MESSAGING_UI_MANAGEMENT_PORT_VALUE);
|
||||
String username = rabbitMqContainer.getAdminUsername();
|
||||
String password = rabbitMqContainer.getAdminPassword();
|
||||
|
||||
registry.add(SPRING_MESSAGING_HOST_KEY, () -> host);
|
||||
registry.add(SPRING_MESSAGING_PORT_KEY, () -> streamPort);
|
||||
registry.add(SPRING_MESSAGING_USERNAME_KEY, () -> username);
|
||||
registry.add(SPRING_MESSAGING_PASSWORD_KEY, () -> password);
|
||||
registry.add(SPRING_MESSAGING_VIRTUAL_HOST_KEY, () -> MESSAGING_VIRTUAL_HOST_VALUE);
|
||||
|
||||
for (String stream : SUPPORTED_STREAMS) {
|
||||
registry.add(SPRING_MESSAGING_STREAM_NAME_KEY_FORMAT.formatted(stream), () -> MESSAGING_STREAM_NAME_VALUE_FORMAT.formatted(stream));
|
||||
registry.add(SPRING_MESSAGING_STREAM_CONSUMER_DLQ_NAME_KEY_FORMAT.formatted(stream), () -> MESSAGING_STREAM_CONSUMER_DLQ_NAME_VALUE_FORMAT.formatted(stream));
|
||||
registry.add(SPRING_MESSAGING_STREAM_CONSUMER_ENABLED_KEY_FORMAT.formatted(stream), () -> true);
|
||||
}
|
||||
|
||||
log.info("TestContainer RabbitMq started — " +
|
||||
"host: {}, username: {}, password: {}, stream port: {}, ui management port: {}",
|
||||
host, username, password, streamPort, uiManagementPort);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.finconsgroup.itserr.marketplace.audit.bs.util;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class TestConstants {
|
||||
public static final Set<String> SUPPORTED_STREAMS = Set.of("catalog", "event", "workspace");
|
||||
public static final String PRODUCER_NAME_FORMAT = "test-producer-%s-%s";
|
||||
public static final String PRODUCER_NAME_ERROR_FORMAT = "test-producer-error-%s-%s";
|
||||
public static final String MESSAGING_STREAM_NAME_VALUE_FORMAT = "itserr-stream-%s-event";
|
||||
public static final String MESSAGING_STREAM_CONSUMER_DLQ_NAME_VALUE_FORMAT = "itserr-stream-%s-event-dlq";
|
||||
|
||||
public static final int MAX_WAIT_TIME_MESSAGE_PRODUCED = 3;
|
||||
public static final int MAX_WAIT_TIME_MESSAGE_HANDLED = 7;
|
||||
public static final int MESSAGE_RETRY_COUNT = 2;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
audit_bs_server_port: 8080
|
||||
|
||||
audit_bs_zipkin_tracing_export_enabled: false
|
||||
|
||||
audit_bs_swagger_api_server_url: http://localhost:8080/api/v1/bs
|
||||
|
||||
audit_dm_client_url: http://localhost:8080/api/v1/dm
|
||||
|
||||
audit_bs_log_base_folder: logs
|
||||
|
||||
# reduce the number of retries and backoff ms for integration tests
|
||||
audit_bs_messaging_default_event_stream_consumer_retry_attempts: 2
|
||||
audit_bs_messaging_default_event_stream_consumer_retry_backoff_ms: 300
|
||||
|
||||
# Messaging
|
||||
audit_bs_messaging_enabled: true
|
||||
audit_bs_messaging_host: ignored
|
||||
audit_bs_messaging_port: ignored
|
||||
audit_bs_messaging_vhost: ignored
|
||||
audit_bs_messaging_auth_keycloak_token_url:
|
||||
audit_bs_messaging_auth_client_id: ignored
|
||||
audit_bs_messaging_auth_client_secret: ignored
|
||||
|
||||
audit_bs_messaging_catalog_bs_event_stream_consumer_enabled: true
|
||||
audit_bs_messaging_catalog_bs_event_stream_name: ignored
|
||||
audit_bs_messaging_catalog_bs_event_stream_consumer_dlq_name: ignored
|
||||
audit_bs_messaging_event_bs_event_stream_consumer_enabled: true
|
||||
audit_bs_messaging_event_bs_event_stream_name: ignored
|
||||
audit_bs_messaging_event_bs_event_stream_consumer_dlq_name: ignored
|
||||
audit_bs_messaging_workspace_bs_event_stream_consumer_enabled: true
|
||||
audit_bs_messaging_workspace_bs_event_stream_name: ignored
|
||||
audit_bs_messaging_workspace_bs_event_stream_consumer_dlq_name: ignored
|
||||
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.finconsgroup.itserr.messaging.utils.CloudEventUtil: TRACE
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
audit_bs_server_port: 8080
|
||||
|
||||
audit_bs_zipkin_tracing_export_enabled: false
|
||||
|
||||
audit_bs_swagger_api_server_url: http://localhost:8080/api/v1/bs
|
||||
|
||||
audit_dm_client_url: http://localhost:8080/api/v1/dm
|
||||
|
||||
|
||||
audit_bs_log_base_folder: logs
|
||||
audit_bs_messaging_enabled: false
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
auth_backends.1 = rabbit_auth_backend_internal
|
||||
stream.listeners.tcp.1 = 5552
|
||||
|
||||
log.file.level = debug
|
||||
log.default.level = debug
|
||||
log.console.level = debug
|
||||
Loading…
Reference in New Issue