diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index cb28b0e..0000000 Binary files a/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index b27a13f..0000000 --- a/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,2 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.2/apache-maven-3.9.2-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/README.md b/README.md index 5634272..7204794 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,18 @@ kubectl get deployments mvn spring-boot:build-image ``` +## Menggunakan mode kubernetes auth +```shell +# start minikube +minikube start + +# export ENV +export VAULT_ADDR='http://[::]:8200' +export VAULT_TOKEN='root' + +# create service account +kubectl create serviceaccount sa-contact-management +``` ## install ke pakcage kubernet ```shell helm install vault hashicorp/vault \ @@ -136,14 +148,13 @@ kubectl port-forward service/vault-ui 8200:8200 # http://localhost:8200 ``` -lalu Jalankan terraform script yang ada di folder tf-provisioner seperti langkah di atas. + ## Masuk ke pod vault ```shell kubectl exec -it vault-0 -- /bin/sh export VAULT_ADDR='http://[::]:8200' - export VAULT_TOKEN='root' vault auth enable kubernetes @@ -157,6 +168,11 @@ vault write auth/kubernetes/role/database \ bound_service_account_namespaces=default \ policies=applikasi-contact-management-readonly \ ttl=20m + + +exit +``` +```shell ``` ## Install the secrets store CSI driver @@ -178,7 +194,18 @@ eval $(minikube docker-env) ## Lanjut build spring boot jadi docker image, kalau udah ada jangan lupa yang lama dihapus dulu mvn spring-boot:build-image -Dmaven.test.skip -## Deploy back-end aplikasi +# init terra dan jalankan teraform ke vult +cd tf-provisioner +terraform init +terraform apply + +# create service account +kubectl create serviceaccount sa-contact-management + +## Deploy +kubectl apply -f k8s/00-configmap.yml +kubectl apply -f k8s/00-secret-vault-store.yml +kubectl apply -f k8s/01-database.yml kubectl apply -f k8s/02-aplikasi.yml ``` diff --git a/compose.yaml b/compose.yaml index f8d0c14..5c04185 100644 --- a/compose.yaml +++ b/compose.yaml @@ -29,4 +29,6 @@ services: environment: VAULT_DEV_ROOT_TOKEN_ID: 'root-token-for-dev-purpose-only' ports: - - '8288:8288' \ No newline at end of file + - '8288:8288' + expose: + - '8288' \ No newline at end of file diff --git a/jmeter.log b/jmeter.log new file mode 100644 index 0000000..f4baa58 --- /dev/null +++ b/jmeter.log @@ -0,0 +1,22 @@ +2024-10-22 22:03:00,912 INFO o.a.j.u.JMeterUtils: Setting Locale to en_EN +2024-10-22 22:03:00,951 INFO o.a.j.JMeter: Loading user properties from: /home/dnl/.sdkman/candidates/jmeter/5.6/bin/user.properties +2024-10-22 22:03:00,953 INFO o.a.j.JMeter: Loading system properties from: /home/dnl/.sdkman/candidates/jmeter/5.6/bin/system.properties +2024-10-22 22:03:00,962 INFO o.a.j.JMeter: Copyright (c) 1998-2023 The Apache Software Foundation +2024-10-22 22:03:00,963 INFO o.a.j.JMeter: Version 5.6 +2024-10-22 22:03:00,963 INFO o.a.j.JMeter: java.version=21.0.4 +2024-10-22 22:03:00,963 INFO o.a.j.JMeter: java.vm.name=Java HotSpot(TM) 64-Bit Server VM +2024-10-22 22:03:00,963 INFO o.a.j.JMeter: os.name=Linux +2024-10-22 22:03:00,963 INFO o.a.j.JMeter: os.arch=amd64 +2024-10-22 22:03:00,964 INFO o.a.j.JMeter: os.version=6.10.6-200.fc40.x86_64 +2024-10-22 22:03:00,964 INFO o.a.j.JMeter: file.encoding=UTF-8 +2024-10-22 22:03:00,964 INFO o.a.j.JMeter: java.awt.headless=null +2024-10-22 22:03:00,964 INFO o.a.j.JMeter: Max memory =1073741824 +2024-10-22 22:03:00,964 INFO o.a.j.JMeter: Available Processors =8 +2024-10-22 22:03:00,987 INFO o.a.j.JMeter: Default Locale=English (EN) +2024-10-22 22:03:00,987 INFO o.a.j.JMeter: JMeter Locale=English (EN) +2024-10-22 22:03:00,988 INFO o.a.j.JMeter: JMeterHome=/home/dnl/.sdkman/candidates/jmeter/5.6 +2024-10-22 22:03:00,988 INFO o.a.j.JMeter: user.dir =/home/dnl/IdeaProjects/contact-management +2024-10-22 22:03:00,988 INFO o.a.j.JMeter: PWD =/home/dnl/IdeaProjects/contact-management +2024-10-22 22:03:00,989 INFO o.a.j.JMeter: IP: 192.168.1.17 Name: fedora FullName: fedora +2024-10-22 22:03:01,029 INFO o.a.j.JMeter: Loaded icon properties from org/apache/jmeter/images/icon.properties +2024-10-22 22:03:01,938 INFO o.a.j.JMeterGuiLauncher: Setting LAF to: com.github.weisj.darklaf.DarkLaf:com.github.weisj.darklaf.theme.DarculaTheme diff --git a/k8s/01-database.yml b/k8s/01-database.yml index 0f2f7ff..da5e200 100644 --- a/k8s/01-database.yml +++ b/k8s/01-database.yml @@ -110,4 +110,4 @@ spec: app: contact-management tier: db stage: dev - ver: v2024070905 + ver: v2024070905 \ No newline at end of file diff --git a/k8s/02-aplikasi.yml b/k8s/02-aplikasi.yml index fca85d3..b7bee4a 100644 --- a/k8s/02-aplikasi.yml +++ b/k8s/02-aplikasi.yml @@ -28,6 +28,13 @@ spec: - name: container-backend-contact-management image: 2819930922/contact-management-api:latest imagePullPolicy: Never + resources: + requests: + memory: 1331Mi # Maximum memory usage is 1.3 GiB + cpu: 600m # Maximum CPU usage is 60% of 1 CPU core (600 millicores) + limits: + memory: 2Gi # Guaranteed 2 GiB of memory + cpu: 1000m # Guaranteed 1 CPU core env: - name: SPRING_DATASOURCE_URL valueFrom: @@ -55,31 +62,20 @@ spec: path: /actuator/health/liveness port: 8080 scheme: HTTP - initialDelaySeconds: 2000 - timeoutSeconds: 30 - periodSeconds: 30 - successThreshold: 1 - failureThreshold: 3 livenessProbe: httpGet: path: /actuator/health/liveness port: 8080 scheme: HTTP - initialDelaySeconds: 90 - timeoutSeconds: 30 - periodSeconds: 30 - successThreshold: 1 - failureThreshold: 3 + initialDelaySeconds: 15 + periodSeconds: 20 readinessProbe: httpGet: path: /actuator/health/readiness port: 8080 scheme: HTTP - initialDelaySeconds: 60 - timeoutSeconds: 30 - periodSeconds: 30 - successThreshold: 1 - failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 10 volumes: - name: secret-dari-vault csi: @@ -87,6 +83,7 @@ spec: readOnly: true volumeAttributes: secretProviderClass: "vault-database" + --- apiVersion: v1 kind: Service @@ -105,3 +102,18 @@ spec: tier: backend stage: dev ver: v2024070905 + +--- +# The following is responsible for the autoscaling. +apiVersion: autoscaling/v1 +kind: HorizontalPodAutoscaler +metadata: + name: deployment-backend-contact-management +spec: + scaleTargetRef: + kind: Deployment + name: deployment-backend-contact-management + apiVersion: apps/v1 + minReplicas: 2 + maxReplicas: 10 + targetCPUUtilizationPercentage: 60 \ No newline at end of file diff --git a/lb.txt b/lb.txt deleted file mode 100644 index b0e26c0..0000000 --- a/lb.txt +++ /dev/null @@ -1,13 +0,0 @@ -gcloud compute instances create nucleus-jumphost-762 --project=qwiklabs-gcp-04-f7ca0e0a6e94 --zone=europe-west4-c --machine-type=e2-medium --network-interface=network-tier=PREMIUM,stack-type=IPV4_ONLY,subnet=default --metadata=enable-oslogin=true --maintenance-policy=MIGRATE --provisioning-model=STANDARD --service-account=763801095178-compute@developer.gserviceaccount.com --scopes=https://www.googleapis.com/auth/devstorage.read_only,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly,https://www.googleapis.com/auth/trace.append --create-disk=auto-delete=yes,boot=yes,device-name=nucleus-jumphost-762,image=projects/debian-cloud/global/images/debian-12-bookworm-v20240415,mode=rw,size=10,type=projects/qwiklabs-gcp-04-f7ca0e0a6e94/zones/europe-west4-c/diskTypes/pd-balanced --no-shielded-secure-boot --shielded-vtpm --shielded-integrity-monitoring --labels=goog-ec-src=vm_add-gcloud --reservation-affinity=any - -gcloud compute instances create www1 \ - --zone=europe-west4-c \ - --tags=network-lb-tag \ - --machine-type=e2-medium \ - --image-family=debian-11 \ - --image-project=debian-cloud \ - --metadata=startup-script='#!/bin/bash - apt-get update - apt-get install -y nginx - service nginx start - sed -i -- 's/nginx/Google Cloud Platform - '"\$HOSTNAME"'/' /var/www/html/index.nginx-debian.html diff --git a/mvnw b/mvnw deleted file mode 100755 index 66df285..0000000 --- a/mvnw +++ /dev/null @@ -1,308 +0,0 @@ -#!/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 -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Apache Maven Wrapper startup batch script, version 3.2.0 -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /usr/local/etc/mavenrc ] ; then - . /usr/local/etc/mavenrc - fi - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "$(uname)" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME - else - JAVA_HOME="/Library/Java/Home"; export JAVA_HOME - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=$(java-config --jre-home) - fi -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$JAVA_HOME" ] && - JAVA_HOME=$(cygpath --unix "$JAVA_HOME") - [ -n "$CLASSPATH" ] && - CLASSPATH=$(cygpath --path --unix "$CLASSPATH") -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && - JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="$(which javac)" - if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=$(which readlink) - if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then - if $darwin ; then - javaHome="$(dirname "\"$javaExecutable\"")" - javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" - else - javaExecutable="$(readlink -f "\"$javaExecutable\"")" - fi - javaHome="$(dirname "\"$javaExecutable\"")" - javaHome=$(expr "$javaHome" : '\(.*\)/bin') - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=$(cd "$wdir/.." || exit 1; pwd) - fi - # end of workaround - done - printf '%s' "$(cd "$basedir" || exit 1; pwd)" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - # Remove \r in case we run on Windows within Git Bash - # and check out the repository with auto CRLF management - # enabled. Otherwise, we may read lines that are delimited with - # \r\n and produce $'-Xarg\r' rather than -Xarg due to word - # splitting rules. - tr -s '\r\n' ' ' < "$1" - fi -} - -log() { - if [ "$MVNW_VERBOSE" = true ]; then - printf '%s\n' "$1" - fi -} - -BASE_DIR=$(find_maven_basedir "$(dirname "$0")") -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR -log "$MAVEN_PROJECTBASEDIR" - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" -if [ -r "$wrapperJarPath" ]; then - log "Found $wrapperJarPath" -else - log "Couldn't find $wrapperJarPath, downloading it ..." - - if [ -n "$MVNW_REPOURL" ]; then - wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - else - wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - fi - while IFS="=" read -r key value; do - # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) - safeValue=$(echo "$value" | tr -d '\r') - case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; - esac - done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" - log "Downloading from: $wrapperUrl" - - if $cygwin; then - wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") - fi - - if command -v wget > /dev/null; then - log "Found wget ... using wget" - [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" - else - wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - log "Found curl ... using curl" - [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" - else - curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" - fi - else - log "Falling back to using Java to download" - javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" - javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaSource=$(cygpath --path --windows "$javaSource") - javaClass=$(cygpath --path --windows "$javaClass") - fi - if [ -e "$javaSource" ]; then - if [ ! -e "$javaClass" ]; then - log " - Compiling MavenWrapperDownloader.java ..." - ("$JAVA_HOME/bin/javac" "$javaSource") - fi - if [ -e "$javaClass" ]; then - log " - Running MavenWrapperDownloader.java ..." - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -# If specified, validate the SHA-256 sum of the Maven wrapper jar file -wrapperSha256Sum="" -while IFS="=" read -r key value; do - case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; - esac -done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" -if [ -n "$wrapperSha256Sum" ]; then - wrapperSha256Result=false - if command -v sha256sum > /dev/null; then - if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then - wrapperSha256Result=true - fi - elif command -v shasum > /dev/null; then - if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then - wrapperSha256Result=true - fi - else - echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." - echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." - exit 1 - fi - if [ $wrapperSha256Result = false ]; then - echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 - echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 - echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 - exit 1 - fi -fi - -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$JAVA_HOME" ] && - JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") - [ -n "$CLASSPATH" ] && - CLASSPATH=$(cygpath --path --windows "$CLASSPATH") - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -# shellcheck disable=SC2086 # safe args -exec "$JAVACMD" \ - $MAVEN_OPTS \ - $MAVEN_DEBUG_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd deleted file mode 100644 index 95ba6f5..0000000 --- a/mvnw.cmd +++ /dev/null @@ -1,205 +0,0 @@ -@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 https://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.2.0 -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* -if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - -FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %WRAPPER_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file -SET WRAPPER_SHA_256_SUM="" -FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B -) -IF NOT %WRAPPER_SHA_256_SUM%=="" ( - powershell -Command "&{"^ - "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ - "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ - " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ - " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ - " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ - " exit 1;"^ - "}"^ - "}" - if ERRORLEVEL 1 goto error -) - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% ^ - %JVM_CONFIG_MAVEN_PROPS% ^ - %MAVEN_OPTS% ^ - %MAVEN_DEBUG_OPTS% ^ - -classpath %WRAPPER_JAR% ^ - "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ - %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" -if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%"=="on" pause - -if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% - -cmd /C exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml index d84932e..a4e1eb5 100644 --- a/pom.xml +++ b/pom.xml @@ -33,6 +33,10 @@ 1.17.0 + + org.springframework.boot + spring-boot-starter-actuator + org.springframework.cloud spring-cloud-starter-vault-config @@ -204,6 +208,13 @@ org.graalvm.buildtools native-maven-plugin + + + + build + + + org.springframework.boot diff --git a/src/main/java/com/yeahbutstill/restful/entity/Address.java b/src/main/java/com/yeahbutstill/restful/entity/Address.java index 7fb2771..22135f5 100644 --- a/src/main/java/com/yeahbutstill/restful/entity/Address.java +++ b/src/main/java/com/yeahbutstill/restful/entity/Address.java @@ -1,8 +1,6 @@ package com.yeahbutstill.restful.entity; import jakarta.persistence.*; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Getter; @@ -18,6 +16,7 @@ public class Address { @Id + @Size(max = 100) private String id; @Size(max = 200) @@ -29,8 +28,6 @@ public class Address { @Size(max = 100) private String province; - @NotBlank - @NotEmpty @Size(max = 100) private String country; diff --git a/src/main/java/com/yeahbutstill/restful/entity/Contact.java b/src/main/java/com/yeahbutstill/restful/entity/Contact.java index d3a0d80..a11c15c 100644 --- a/src/main/java/com/yeahbutstill/restful/entity/Contact.java +++ b/src/main/java/com/yeahbutstill/restful/entity/Contact.java @@ -1,7 +1,8 @@ package com.yeahbutstill.restful.entity; import jakarta.persistence.*; -import jakarta.validation.constraints.*; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -18,12 +19,11 @@ public class Contact { @Id + @Size(max = 100) private String id; @Column(name = "first_name") @Size(max = 100) - @NotEmpty - @NotBlank private String firstName; @Column(name = "last_name") diff --git a/src/main/java/com/yeahbutstill/restful/entity/User.java b/src/main/java/com/yeahbutstill/restful/entity/User.java index 871b22e..393a617 100644 --- a/src/main/java/com/yeahbutstill/restful/entity/User.java +++ b/src/main/java/com/yeahbutstill/restful/entity/User.java @@ -1,8 +1,6 @@ package com.yeahbutstill.restful.entity; import jakarta.persistence.*; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Getter; @@ -20,15 +18,12 @@ public class User { @Id + @Size(max = 100) private String username; - @NotBlank - @NotEmpty @Size(max = 100) private String password; - @NotBlank - @NotEmpty @Size(max = 100) private String name; diff --git a/src/main/java/com/yeahbutstill/restful/resolver/UserArgumentResolver.java b/src/main/java/com/yeahbutstill/restful/resolver/UserArgumentResolver.java index 209f7b6..fcb082a 100644 --- a/src/main/java/com/yeahbutstill/restful/resolver/UserArgumentResolver.java +++ b/src/main/java/com/yeahbutstill/restful/resolver/UserArgumentResolver.java @@ -38,7 +38,7 @@ public boolean supportsParameter(MethodParameter parameter) { * Resolves a method parameter into an argument value from a given request. * A {@link ModelAndViewContainer} provides access to the model for the * request. A {@link WebDataBinderFactory} provides a way to create - * a {@link WebDataBinder} instance when needed for data binding and + * a {@link org.springframework.web.bind.WebDataBinder} instance when needed for data binding and * type conversion purposes. * * @param parameter the method parameter to resolve. This parameter must @@ -46,7 +46,7 @@ public boolean supportsParameter(MethodParameter parameter) { * have returned {@code true}. * @param mavContainer the ModelAndViewContainer for the current request * @param webRequest the current request - * @param binderFactory a factory for creating {@link WebDataBinder} instances + * @param binderFactory a factory for creating {@link org.springframework.web.bind.WebDataBinder} instances * @return the resolved argument value, or {@code null} if not resolvable * @throws Exception in case of errors with the preparation of argument values */ diff --git a/src/main/resources/META-INF/native-image/reflect-config.json b/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 0000000..2846e6e --- /dev/null +++ b/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,6 @@ +[ + { + "name": "java.util.UUID[]", + "unsafeAllocated": true + } +] diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 5190c74..607b6ff 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,23 +1,26 @@ -spring.application.name=aplikasi-contact-management -#server.port=8181 +spring.application.name=aplikasi-contact-managemen + +spring.threads.virtual.enabled=true + +server.port=8080 management.endpoints.web.exposure.include=health management.endpoint.health.show-details=always +management.endpoint.health.probes.enabled=true + management.health.livenessstate.enabled=true management.health.readinessstate.enabled=true -management.endpoint.health.probes.enabled=true spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.url=jdbc:postgresql://localhost:5432/contact_management_db spring.datasource.username=dani spring.datasource.password=dani - spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.hikari.minimum-idle=10 spring.datasource.hikari.maximum-pool-size=50 +spring.jpa.hibernate.ddl-auto=validate spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.show_sql=true -spring.jpa.hibernate.ddl-auto=create-drop spring.cloud.vault.enabled=false \ No newline at end of file diff --git a/src/main/resources/db/migration/V1.0.0.2024101404__Table event_publication.sql b/src/main/resources/db/migration/V1.0.0.2024101404__Table event_publication.sql new file mode 100644 index 0000000..85dc5e5 --- /dev/null +++ b/src/main/resources/db/migration/V1.0.0.2024101404__Table event_publication.sql @@ -0,0 +1,9 @@ +create table event_publication ( + id uuid not null, + completion_date timestamp(6) with time zone, + event_type varchar(255), + listener_id varchar(255), + publication_date timestamp(6) with time zone, + serialized_event varchar(255), + primary key (id) +); diff --git a/src/test/java/com/yeahbutstill/restful/TestDemoApplication.java b/src/test/java/com/yeahbutstill/restful/TestDemoApplication.java index 022b425..8f03fd9 100644 --- a/src/test/java/com/yeahbutstill/restful/TestDemoApplication.java +++ b/src/test/java/com/yeahbutstill/restful/TestDemoApplication.java @@ -10,6 +10,8 @@ @TestConfiguration(proxyBeanMethods = false) public class TestDemoApplication { + public static final String TESTCONTAINER_HOST_URL = "http://host.testcontainers.internal"; + public static void main(String[] args) { SpringApplication.from(ContactManagementApiApplication::main).with(TestDemoApplication.class).run(args); } @@ -17,7 +19,7 @@ public static void main(String[] args) { @Bean @ServiceConnection PostgreSQLContainer postgresContainer() { - return new PostgreSQLContainer<>(DockerImageName.parse("postgres:15-alpine")); + return new PostgreSQLContainer<>(DockerImageName.parse("postgres:16.3-alpine3.20")); } } diff --git a/tf-provisioner/terraform.tfstate b/tf-provisioner/terraform.tfstate index 399cc7c..e353925 100644 --- a/tf-provisioner/terraform.tfstate +++ b/tf-provisioner/terraform.tfstate @@ -1,7 +1,7 @@ { "version": 4, - "terraform_version": "1.9.7", - "serial": 49, + "terraform_version": "1.9.8", + "serial": 70, "lineage": "d7c8c82c-6b30-1b62-9878-0f5f3ece87c8", "outputs": {}, "resources": [ @@ -18,7 +18,7 @@ "bind_secret_id": true, "id": "auth/approle/role/contact-management", "namespace": null, - "role_id": "e0909e3e-90d3-50a2-9fbc-3c04047d17c5", + "role_id": "4512b649-177f-6f1b-af26-c68cf106f99e", "role_name": "contact-management", "secret_id_bound_cidrs": null, "secret_id_num_uses": 0, @@ -52,7 +52,7 @@ { "schema_version": 1, "attributes": { - "accessor": "auth_approle_2f8a915c", + "accessor": "auth_approle_2f1d68a6", "description": "", "disable_remount": false, "id": "approle", @@ -95,13 +95,13 @@ [ { "type": "get_attr", - "value": "data" + "value": "data_json" } ], [ { "type": "get_attr", - "value": "data_json" + "value": "data" } ] ], diff --git a/tf-provisioner/terraform.tfstate.backup b/tf-provisioner/terraform.tfstate.backup index 07bbe8e..a241caa 100644 --- a/tf-provisioner/terraform.tfstate.backup +++ b/tf-provisioner/terraform.tfstate.backup @@ -1,7 +1,7 @@ { "version": 4, - "terraform_version": "1.9.7", - "serial": 44, + "terraform_version": "1.9.8", + "serial": 65, "lineage": "d7c8c82c-6b30-1b62-9878-0f5f3ece87c8", "outputs": {}, "resources": [ @@ -18,12 +18,12 @@ "bind_secret_id": true, "id": "auth/approle/role/contact-management", "namespace": null, - "role_id": "345dc5d9-6d5b-08ed-a9f0-355b8fd972b0", + "role_id": "79647e66-0e15-a58c-9ce4-08bc2c8e5721", "role_name": "contact-management", - "secret_id_bound_cidrs": [], + "secret_id_bound_cidrs": null, "secret_id_num_uses": 0, "secret_id_ttl": 0, - "token_bound_cidrs": [], + "token_bound_cidrs": null, "token_explicit_max_ttl": 0, "token_max_ttl": 0, "token_no_default_policy": false, @@ -52,7 +52,7 @@ { "schema_version": 1, "attributes": { - "accessor": "auth_approle_87e7e793", + "accessor": "auth_approle_65d7039d", "description": "", "disable_remount": false, "id": "approle",