From 50aa3878d2877c1e3ed4dc73d2bf6556cc213e7e Mon Sep 17 00:00:00 2001 From: asia Date: Wed, 18 Aug 2021 12:18:17 +0200 Subject: [PATCH 001/249] Init --- hexagonal/mvnw | 310 ++++++++++++++++++ hexagonal/mvnw.cmd | 182 ++++++++++ hexagonal/pom.xml | 70 ++++ .../com/baeldung/hexagonal/Application.java | 12 + .../adapter/in/ItemTransportObject.java | 10 + .../adapter/in/ShoppingCartController.java | 22 ++ .../adapter/in/ShoppingCartFacade.java | 21 ++ .../hexagonal/adapter/out/Product.java | 26 ++ .../adapter/out/ProductCrudRepository.java | 12 + .../baeldung/hexagonal/domain/CartItem.java | 13 + .../hexagonal/domain/ShoppingCart.java | 22 ++ .../hexagonal/domain/ShoppingCartService.java | 31 ++ .../domain/ports/ProductRepository.java | 8 + .../src/main/resources/application.properties | 5 + .../hexagonal/domain/ShoppingCartTest.java | 29 ++ 15 files changed, 773 insertions(+) create mode 100755 hexagonal/mvnw create mode 100644 hexagonal/mvnw.cmd create mode 100644 hexagonal/pom.xml create mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/Application.java create mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ItemTransportObject.java create mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java create mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartFacade.java create mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/Product.java create mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/ProductCrudRepository.java create mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/domain/CartItem.java create mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCart.java create mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java create mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/domain/ports/ProductRepository.java create mode 100644 hexagonal/src/main/resources/application.properties create mode 100644 hexagonal/src/test/java/com/baeldung/hexagonal/domain/ShoppingCartTest.java diff --git a/hexagonal/mvnw b/hexagonal/mvnw new file mode 100755 index 0000000000..a16b5431b4 --- /dev/null +++ b/hexagonal/mvnw @@ -0,0 +1,310 @@ +#!/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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# 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 /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 + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -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 "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; 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="`which 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 + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# 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/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# 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. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +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 "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -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 + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/hexagonal/mvnw.cmd b/hexagonal/mvnw.cmd new file mode 100644 index 0000000000..c8d43372c9 --- /dev/null +++ b/hexagonal/mvnw.cmd @@ -0,0 +1,182 @@ +@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 Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@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 "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\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 DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_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 DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_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('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@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 "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\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% + +exit /B %ERROR_CODE% diff --git a/hexagonal/pom.xml b/hexagonal/pom.xml new file mode 100644 index 0000000000..020a48ce58 --- /dev/null +++ b/hexagonal/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.5.3 + + + com.example + demo + 0.0.1-SNAPSHOT + demo + Demo project for Spring Boot + + 11 + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + runtime + + + org.springframework.boot + spring-boot-starter-web + + + + org.projectlombok + lombok + true + + + javax.xml.bind + jaxb-api + 2.3.0 + + + org.junit.jupiter + junit-jupiter-engine + 5.7.2 + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/Application.java b/hexagonal/src/main/java/com/baeldung/hexagonal/Application.java new file mode 100644 index 0000000000..d9dcc1d8b0 --- /dev/null +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/Application.java @@ -0,0 +1,12 @@ +package com.baeldung.hexagonal; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ItemTransportObject.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ItemTransportObject.java new file mode 100644 index 0000000000..4c2eded0ec --- /dev/null +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ItemTransportObject.java @@ -0,0 +1,10 @@ +package com.baeldung.hexagonal.adapter.in; + +import lombok.Data; + +@Data +class ItemTransportObject { + private String name; + private Integer quantity; + private String category; +} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java new file mode 100644 index 0000000000..b1c0fabe2e --- /dev/null +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java @@ -0,0 +1,22 @@ +package com.baeldung.hexagonal.adapter.in; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/shopping-cart") +public class ShoppingCartController { + + @Autowired + ShoppingCartFacade apiAdapter; + + @GetMapping + public Float getTotalCartValue() { + return apiAdapter.getTotalCartValue(); + } + + @PostMapping() + public void addItem(@RequestBody ItemTransportObject item) { + apiAdapter.addItem(item); + } +} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartFacade.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartFacade.java new file mode 100644 index 0000000000..a162368135 --- /dev/null +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartFacade.java @@ -0,0 +1,21 @@ +package com.baeldung.hexagonal.adapter.in; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.baeldung.hexagonal.domain.ShoppingCartService; + +@Component +class ShoppingCartFacade { + + @Autowired + ShoppingCartService shoppingCartService; + + void addItem(ItemTransportObject item) { + shoppingCartService.addItem(item.getName(), item.getQuantity()); + } + + Float getTotalCartValue() { + return shoppingCartService.getTotalCartValue(); + } +} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/Product.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/Product.java new file mode 100644 index 0000000000..8be0944af8 --- /dev/null +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/Product.java @@ -0,0 +1,26 @@ +package com.baeldung.hexagonal.adapter.out; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; + +import com.baeldung.hexagonal.domain.CartItem; + +import lombok.Data; + +@Entity +@Data +public class Product { + + @Id + public final Integer id; + @Column + public final String name; + @Column + public final Float price; + + public CartItem toItem() { + return new CartItem(name, price); + } + +} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/ProductCrudRepository.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/ProductCrudRepository.java new file mode 100644 index 0000000000..eae7edf722 --- /dev/null +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/ProductCrudRepository.java @@ -0,0 +1,12 @@ +package com.baeldung.hexagonal.adapter.out; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import com.baeldung.hexagonal.domain.ports.ProductRepository; + +@Repository +public interface ProductCrudRepository extends CrudRepository, ProductRepository { + + Product findByName(String name); +} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/CartItem.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/CartItem.java new file mode 100644 index 0000000000..43100ae3ef --- /dev/null +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/CartItem.java @@ -0,0 +1,13 @@ +package com.baeldung.hexagonal.domain; + +import lombok.Data; +import lombok.NonNull; + +@Data +public class CartItem { + + @NonNull + private final String name; + private final Float price; + +} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCart.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCart.java new file mode 100644 index 0000000000..7eecf94021 --- /dev/null +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCart.java @@ -0,0 +1,22 @@ +package com.baeldung.hexagonal.domain; + +import java.util.Map; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +class ShoppingCart { + + private final Map itemToQuantity; + + Float getTotalCartValue() { + return itemToQuantity.entrySet().stream() + .map(item -> item.getKey().getPrice() * item.getValue()).reduce(0f, Float::sum); + } + + void addItem(CartItem cartItem, Integer quantity) { + if (quantity < 0) + throw new IllegalArgumentException("Quantity should not be negative."); + itemToQuantity.put(cartItem, itemToQuantity.getOrDefault(cartItem, 0) + quantity); + } +} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java new file mode 100644 index 0000000000..bc2cbab66a --- /dev/null +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java @@ -0,0 +1,31 @@ +package com.baeldung.hexagonal.domain; + +import java.util.HashMap; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baeldung.hexagonal.adapter.out.Product; +import com.baeldung.hexagonal.domain.ports.ProductRepository; + +@Service +public class ShoppingCartService { + + private final ShoppingCart shoppingCart; + + @Autowired + ProductRepository productRepository; + + public ShoppingCartService() { + this.shoppingCart = new ShoppingCart(new HashMap<>()); + } + + public Float getTotalCartValue() { + return shoppingCart.getTotalCartValue(); + } + + public void addItem(String name, Integer quantity) { + Product product = productRepository.findByName(name); + shoppingCart.addItem(product.toItem(), quantity); + } +} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ports/ProductRepository.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ports/ProductRepository.java new file mode 100644 index 0000000000..21ad050bc1 --- /dev/null +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ports/ProductRepository.java @@ -0,0 +1,8 @@ +package com.baeldung.hexagonal.domain.ports; + +import com.baeldung.hexagonal.adapter.out.Product; + +public interface ProductRepository { + + Product findByName(String name); +} diff --git a/hexagonal/src/main/resources/application.properties b/hexagonal/src/main/resources/application.properties new file mode 100644 index 0000000000..730dded1b7 --- /dev/null +++ b/hexagonal/src/main/resources/application.properties @@ -0,0 +1,5 @@ +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password=password +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect \ No newline at end of file diff --git a/hexagonal/src/test/java/com/baeldung/hexagonal/domain/ShoppingCartTest.java b/hexagonal/src/test/java/com/baeldung/hexagonal/domain/ShoppingCartTest.java new file mode 100644 index 0000000000..c3af6f0e29 --- /dev/null +++ b/hexagonal/src/test/java/com/baeldung/hexagonal/domain/ShoppingCartTest.java @@ -0,0 +1,29 @@ +package com.baeldung.hexagonal.domain; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + + +class ShoppingCartTest { + + @Test + void givenNonemptyShoppingCart_whenGetTotalCartValueCalled_thenShouldCalculateCorrectly() { + + // given + Map items = new HashMap<>(); + items.put(new CartItem("Cheese", 1.5f), 2); + items.put(new CartItem("Lemon", 2f), 5); + + ShoppingCart cart = new ShoppingCart(items); + + // when + Float totalCartValue = cart.getTotalCartValue(); + + // then + assertEquals(totalCartValue, 13f, 0); + } +} From 48d18665ed104f878b0ccca9880e72333279b0a4 Mon Sep 17 00:00:00 2001 From: asia Date: Sat, 21 Aug 2021 15:17:14 +0200 Subject: [PATCH 002/249] Removing mvnw files --- hexagonal/mvnw | 310 --------------------------------------------- hexagonal/mvnw.cmd | 182 -------------------------- 2 files changed, 492 deletions(-) delete mode 100755 hexagonal/mvnw delete mode 100644 hexagonal/mvnw.cmd diff --git a/hexagonal/mvnw b/hexagonal/mvnw deleted file mode 100755 index a16b5431b4..0000000000 --- a/hexagonal/mvnw +++ /dev/null @@ -1,310 +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. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# 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 /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 - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -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 "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; 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="`which 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 - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# 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/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# 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. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -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 "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -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 - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/hexagonal/mvnw.cmd b/hexagonal/mvnw.cmd deleted file mode 100644 index c8d43372c9..0000000000 --- a/hexagonal/mvnw.cmd +++ /dev/null @@ -1,182 +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 Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@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 "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\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 DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_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 DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_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('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@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 "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\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% - -exit /B %ERROR_CODE% From c1b36b3bb0d8434793e12382b5d296e81198872b Mon Sep 17 00:00:00 2001 From: asia Date: Sat, 21 Aug 2021 15:41:56 +0200 Subject: [PATCH 003/249] Apply eclipse code format --- .../com/baeldung/hexagonal/Application.java | 6 ++--- .../adapter/in/ItemTransportObject.java | 6 ++--- .../hexagonal/adapter/out/Product.java | 18 ++++++------- .../adapter/out/ProductCrudRepository.java | 2 +- .../baeldung/hexagonal/domain/CartItem.java | 6 ++--- .../hexagonal/domain/ShoppingCart.java | 23 +++++++++-------- .../domain/ports/ProductRepository.java | 2 +- .../hexagonal/domain/ShoppingCartTest.java | 25 +++++++++---------- 8 files changed, 45 insertions(+), 43 deletions(-) diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/Application.java b/hexagonal/src/main/java/com/baeldung/hexagonal/Application.java index d9dcc1d8b0..eb762f615d 100644 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/Application.java +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/Application.java @@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } } diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ItemTransportObject.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ItemTransportObject.java index 4c2eded0ec..bcf38e99a0 100644 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ItemTransportObject.java +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ItemTransportObject.java @@ -4,7 +4,7 @@ import lombok.Data; @Data class ItemTransportObject { - private String name; - private Integer quantity; - private String category; + private String name; + private Integer quantity; + private String category; } diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/Product.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/Product.java index 8be0944af8..00a330b50a 100644 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/Product.java +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/Product.java @@ -12,15 +12,15 @@ import lombok.Data; @Data public class Product { - @Id - public final Integer id; - @Column - public final String name; - @Column - public final Float price; + @Id + public final Integer id; + @Column + public final String name; + @Column + public final Float price; - public CartItem toItem() { - return new CartItem(name, price); - } + public CartItem toItem() { + return new CartItem(name, price); + } } diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/ProductCrudRepository.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/ProductCrudRepository.java index eae7edf722..3708a1a19d 100644 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/ProductCrudRepository.java +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/ProductCrudRepository.java @@ -8,5 +8,5 @@ import com.baeldung.hexagonal.domain.ports.ProductRepository; @Repository public interface ProductCrudRepository extends CrudRepository, ProductRepository { - Product findByName(String name); + Product findByName(String name); } diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/CartItem.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/CartItem.java index 43100ae3ef..1e0fcfb50e 100644 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/CartItem.java +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/CartItem.java @@ -6,8 +6,8 @@ import lombok.NonNull; @Data public class CartItem { - @NonNull - private final String name; - private final Float price; + @NonNull + private final String name; + private final Float price; } diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCart.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCart.java index 7eecf94021..949090eb80 100644 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCart.java +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCart.java @@ -7,16 +7,19 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor class ShoppingCart { - private final Map itemToQuantity; + private final Map itemToQuantity; - Float getTotalCartValue() { - return itemToQuantity.entrySet().stream() - .map(item -> item.getKey().getPrice() * item.getValue()).reduce(0f, Float::sum); - } + Float getTotalCartValue() { + return itemToQuantity.entrySet() + .stream() + .map(item -> item.getKey() + .getPrice() * item.getValue()) + .reduce(0f, Float::sum); + } - void addItem(CartItem cartItem, Integer quantity) { - if (quantity < 0) - throw new IllegalArgumentException("Quantity should not be negative."); - itemToQuantity.put(cartItem, itemToQuantity.getOrDefault(cartItem, 0) + quantity); - } + void addItem(CartItem cartItem, Integer quantity) { + if (quantity < 0) + throw new IllegalArgumentException("Quantity should not be negative."); + itemToQuantity.put(cartItem, itemToQuantity.getOrDefault(cartItem, 0) + quantity); + } } diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ports/ProductRepository.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ports/ProductRepository.java index 21ad050bc1..b4f53beb1e 100644 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ports/ProductRepository.java +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ports/ProductRepository.java @@ -4,5 +4,5 @@ import com.baeldung.hexagonal.adapter.out.Product; public interface ProductRepository { - Product findByName(String name); + Product findByName(String name); } diff --git a/hexagonal/src/test/java/com/baeldung/hexagonal/domain/ShoppingCartTest.java b/hexagonal/src/test/java/com/baeldung/hexagonal/domain/ShoppingCartTest.java index c3af6f0e29..c39892a8fa 100644 --- a/hexagonal/src/test/java/com/baeldung/hexagonal/domain/ShoppingCartTest.java +++ b/hexagonal/src/test/java/com/baeldung/hexagonal/domain/ShoppingCartTest.java @@ -7,23 +7,22 @@ import java.util.Map; import org.junit.jupiter.api.Test; - class ShoppingCartTest { - @Test - void givenNonemptyShoppingCart_whenGetTotalCartValueCalled_thenShouldCalculateCorrectly() { + @Test + void givenNonemptyShoppingCart_whenGetTotalCartValueCalled_thenShouldCalculateCorrectly() { - // given - Map items = new HashMap<>(); - items.put(new CartItem("Cheese", 1.5f), 2); - items.put(new CartItem("Lemon", 2f), 5); + // given + Map items = new HashMap<>(); + items.put(new CartItem("Cheese", 1.5f), 2); + items.put(new CartItem("Lemon", 2f), 5); - ShoppingCart cart = new ShoppingCart(items); + ShoppingCart cart = new ShoppingCart(items); - // when - Float totalCartValue = cart.getTotalCartValue(); + // when + Float totalCartValue = cart.getTotalCartValue(); - // then - assertEquals(totalCartValue, 13f, 0); - } + // then + assertEquals(totalCartValue, 13f, 0); + } } From 154b23203e37aae250a193f3d0aabd0106ca1844 Mon Sep 17 00:00:00 2001 From: asia Date: Sat, 21 Aug 2021 15:42:18 +0200 Subject: [PATCH 004/249] Refactoring --- .../hexagonal/ShoppingCartService.java | 8 +++++ .../adapter/in/ShoppingCartController.java | 22 +++++++------ .../adapter/in/ShoppingCartFacade.java | 21 ------------ .../hexagonal/domain/ShoppingCartService.java | 31 ------------------ .../domain/SimpleShoppingCartService.java | 32 +++++++++++++++++++ 5 files changed, 52 insertions(+), 62 deletions(-) create mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/ShoppingCartService.java delete mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartFacade.java delete mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java create mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/domain/SimpleShoppingCartService.java diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/ShoppingCartService.java b/hexagonal/src/main/java/com/baeldung/hexagonal/ShoppingCartService.java new file mode 100644 index 0000000000..25613ed556 --- /dev/null +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/ShoppingCartService.java @@ -0,0 +1,8 @@ +package com.baeldung.hexagonal; + +public interface ShoppingCartService { + + Float getTotalCartValue(); + + void addItem(String name, Integer quantity); +} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java index b1c0fabe2e..d92f186c84 100644 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java @@ -3,20 +3,22 @@ package com.baeldung.hexagonal.adapter.in; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import com.baeldung.hexagonal.ShoppingCartService; + @RestController @RequestMapping("/shopping-cart") public class ShoppingCartController { - @Autowired - ShoppingCartFacade apiAdapter; + @Autowired + ShoppingCartService shoppingCartService; - @GetMapping - public Float getTotalCartValue() { - return apiAdapter.getTotalCartValue(); - } + @GetMapping + public Float getTotalCartValue() { + return shoppingCartService.getTotalCartValue(); + } - @PostMapping() - public void addItem(@RequestBody ItemTransportObject item) { - apiAdapter.addItem(item); - } + @PostMapping() + public void addItem(@RequestBody ItemTransportObject item) { + shoppingCartService.addItem(item.getName(), item.getQuantity()); + } } diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartFacade.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartFacade.java deleted file mode 100644 index a162368135..0000000000 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartFacade.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.hexagonal.adapter.in; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.baeldung.hexagonal.domain.ShoppingCartService; - -@Component -class ShoppingCartFacade { - - @Autowired - ShoppingCartService shoppingCartService; - - void addItem(ItemTransportObject item) { - shoppingCartService.addItem(item.getName(), item.getQuantity()); - } - - Float getTotalCartValue() { - return shoppingCartService.getTotalCartValue(); - } -} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java deleted file mode 100644 index bc2cbab66a..0000000000 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.baeldung.hexagonal.domain; - -import java.util.HashMap; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.baeldung.hexagonal.adapter.out.Product; -import com.baeldung.hexagonal.domain.ports.ProductRepository; - -@Service -public class ShoppingCartService { - - private final ShoppingCart shoppingCart; - - @Autowired - ProductRepository productRepository; - - public ShoppingCartService() { - this.shoppingCart = new ShoppingCart(new HashMap<>()); - } - - public Float getTotalCartValue() { - return shoppingCart.getTotalCartValue(); - } - - public void addItem(String name, Integer quantity) { - Product product = productRepository.findByName(name); - shoppingCart.addItem(product.toItem(), quantity); - } -} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/SimpleShoppingCartService.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/SimpleShoppingCartService.java new file mode 100644 index 0000000000..471ab37941 --- /dev/null +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/SimpleShoppingCartService.java @@ -0,0 +1,32 @@ +package com.baeldung.hexagonal.domain; + +import java.util.HashMap; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baeldung.hexagonal.ShoppingCartService; +import com.baeldung.hexagonal.adapter.out.Product; +import com.baeldung.hexagonal.domain.ports.ProductRepository; + +@Service +public class SimpleShoppingCartService implements ShoppingCartService { + + private final ShoppingCart shoppingCart; + + @Autowired + ProductRepository productRepository; + + public SimpleShoppingCartService() { + this.shoppingCart = new ShoppingCart(new HashMap<>()); + } + + public Float getTotalCartValue() { + return shoppingCart.getTotalCartValue(); + } + + public void addItem(String name, Integer quantity) { + Product product = productRepository.findByName(name); + shoppingCart.addItem(product.toItem(), quantity); + } +} From 8ffc0d36a20363a9730f69217c3f99a2eceb3815 Mon Sep 17 00:00:00 2001 From: asia Date: Sat, 21 Aug 2021 15:42:18 +0200 Subject: [PATCH 005/249] Refactoring --- .../baeldung/hexagonal/adapter/in/ShoppingCartController.java | 2 +- .../baeldung/hexagonal/{ => domain}/ShoppingCartService.java | 2 +- .../baeldung/hexagonal/domain/SimpleShoppingCartService.java | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) rename hexagonal/src/main/java/com/baeldung/hexagonal/{ => domain}/ShoppingCartService.java (76%) diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java index d92f186c84..ffaa1a1a08 100644 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java @@ -3,7 +3,7 @@ package com.baeldung.hexagonal.adapter.in; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import com.baeldung.hexagonal.ShoppingCartService; +import com.baeldung.hexagonal.domain.ShoppingCartService; @RestController @RequestMapping("/shopping-cart") diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/ShoppingCartService.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java similarity index 76% rename from hexagonal/src/main/java/com/baeldung/hexagonal/ShoppingCartService.java rename to hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java index 25613ed556..022020e298 100644 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/ShoppingCartService.java +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java @@ -1,4 +1,4 @@ -package com.baeldung.hexagonal; +package com.baeldung.hexagonal.domain; public interface ShoppingCartService { diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/SimpleShoppingCartService.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/SimpleShoppingCartService.java index 471ab37941..9bced883a5 100644 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/SimpleShoppingCartService.java +++ b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/SimpleShoppingCartService.java @@ -5,7 +5,6 @@ import java.util.HashMap; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.baeldung.hexagonal.ShoppingCartService; import com.baeldung.hexagonal.adapter.out.Product; import com.baeldung.hexagonal.domain.ports.ProductRepository; From bdef2f248df6d03c45530683a4efcae700f4126b Mon Sep 17 00:00:00 2001 From: asia Date: Thu, 2 Sep 2021 14:26:36 +0200 Subject: [PATCH 006/249] BAEL-4211 Add benchmarks --- .../pom.xml | 112 +++++++++++++----- .../com/baeldung/jmh/BenchmarkRunner.java | 10 ++ .../baeldung/jmh/ObjectsCopyBenchmark.java | 42 +++++++ .../baeldung/jmh/PrimitivesCopyBenchmark.java | 42 +++++++ 4 files changed, 179 insertions(+), 27 deletions(-) create mode 100644 core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/BenchmarkRunner.java create mode 100644 core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/ObjectsCopyBenchmark.java create mode 100644 core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/PrimitivesCopyBenchmark.java diff --git a/core-java-modules/core-java-arrays-operations-advanced/pom.xml b/core-java-modules/core-java-arrays-operations-advanced/pom.xml index 5663a7d1ca..57574de4a3 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/pom.xml +++ b/core-java-modules/core-java-arrays-operations-advanced/pom.xml @@ -1,35 +1,93 @@ - 4.0.0 - core-java-arrays-operations-advanced - core-java-arrays-operations-advanced - jar + 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"> + 4.0.0 + core-java-arrays-operations-advanced + core-java-arrays-operations-advanced + jar - - core-java-modules - com.baeldung.core-java-modules - 0.0.1-SNAPSHOT - + + core-java-modules + com.baeldung.core-java-modules + 0.0.1-SNAPSHOT + - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + - - org.assertj - assertj-core - ${assertj-core.version} - test - - + + org.assertj + assertj-core + ${assertj-core.version} + test + - - 3.10.0 - + + org.openjdk.jmh + jmh-core + ${jmh.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + + + + + 3.10.0 + 1.22 + UTF-8 + 1.33 + 3.0.2 + 0.10 + 3.2.0 + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven-jar-plugin.version} + + + + com.baeldung.BenchmarkRunner + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven-assembly-plugin.version} + + + jar-with-dependencies + + + + com.baeldung.jmh.BenchmarkRunner + + + + + + make-assembly + package + + single + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/BenchmarkRunner.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/BenchmarkRunner.java new file mode 100644 index 0000000000..96e2a8833e --- /dev/null +++ b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/BenchmarkRunner.java @@ -0,0 +1,10 @@ +package com.baeldung.jmh; + +public class BenchmarkRunner { + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/ObjectsCopyBenchmark.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/ObjectsCopyBenchmark.java new file mode 100644 index 0000000000..2cfa00b0e8 --- /dev/null +++ b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/ObjectsCopyBenchmark.java @@ -0,0 +1,42 @@ +package com.baeldung.jmh; + +import org.openjdk.jmh.annotations.*; + +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@State(Scope.Thread) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 10) +@Fork(1) +@Measurement(iterations = 100) +public class ObjectsCopyBenchmark { + + @Param({ "10", "1000000" }) + public int SIZE; + Integer[] src; + + @Setup + public void setup() { + Random r = new Random(); + src = new Integer[SIZE]; + + for (int i = 0; i < SIZE; i++) { + src[i] = r.nextInt(); + } + } + + @Benchmark + public Integer[] systemArrayCopyBenchmark() { + Integer[] target = new Integer[SIZE]; + System.arraycopy(src, 0, target, 0, SIZE); + return target; + } + + @Benchmark + public Integer[] arraysCopyOfBenchmark() { + return Arrays.copyOf(src, SIZE); + } +} diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/PrimitivesCopyBenchmark.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/PrimitivesCopyBenchmark.java new file mode 100644 index 0000000000..f51ceadf2a --- /dev/null +++ b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/PrimitivesCopyBenchmark.java @@ -0,0 +1,42 @@ +package com.baeldung.jmh; + +import org.openjdk.jmh.annotations.*; + +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@State(Scope.Thread) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 10) +@Fork(1) +@Measurement(iterations = 100) +public class PrimitivesCopyBenchmark { + + @Param({ "10", "1000000" }) + public int SIZE; + int[] src; + + @Setup + public void setup() { + Random r = new Random(); + src = new int[SIZE]; + + for (int i = 0; i < SIZE; i++) { + src[i] = r.nextInt(); + } + } + + @Benchmark + public int[] systemArrayCopyBenchmark() { + int[] target = new int[SIZE]; + System.arraycopy(src, 0, target, 0, SIZE); + return target; + } + + @Benchmark + public int[] arraysCopyOfBenchmark() { + return Arrays.copyOf(src, SIZE); + } +} From 5afba3476d85767a1dc22ce5979006ed9ccaf893 Mon Sep 17 00:00:00 2001 From: JoannaaKL <67866556+JoannaaKL@users.noreply.github.com> Date: Thu, 2 Sep 2021 15:57:03 +0200 Subject: [PATCH 007/249] Delete hexagonal directory --- hexagonal/pom.xml | 70 ------------------- .../com/baeldung/hexagonal/Application.java | 12 ---- .../adapter/in/ItemTransportObject.java | 10 --- .../adapter/in/ShoppingCartController.java | 24 ------- .../hexagonal/adapter/out/Product.java | 26 ------- .../adapter/out/ProductCrudRepository.java | 12 ---- .../baeldung/hexagonal/domain/CartItem.java | 13 ---- .../hexagonal/domain/ShoppingCart.java | 25 ------- .../hexagonal/domain/ShoppingCartService.java | 8 --- .../domain/SimpleShoppingCartService.java | 31 -------- .../domain/ports/ProductRepository.java | 8 --- .../src/main/resources/application.properties | 5 -- .../hexagonal/domain/ShoppingCartTest.java | 28 -------- 13 files changed, 272 deletions(-) delete mode 100644 hexagonal/pom.xml delete mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/Application.java delete mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ItemTransportObject.java delete mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java delete mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/Product.java delete mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/ProductCrudRepository.java delete mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/domain/CartItem.java delete mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCart.java delete mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java delete mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/domain/SimpleShoppingCartService.java delete mode 100644 hexagonal/src/main/java/com/baeldung/hexagonal/domain/ports/ProductRepository.java delete mode 100644 hexagonal/src/main/resources/application.properties delete mode 100644 hexagonal/src/test/java/com/baeldung/hexagonal/domain/ShoppingCartTest.java diff --git a/hexagonal/pom.xml b/hexagonal/pom.xml deleted file mode 100644 index 020a48ce58..0000000000 --- a/hexagonal/pom.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.5.3 - - - com.example - demo - 0.0.1-SNAPSHOT - demo - Demo project for Spring Boot - - 11 - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - com.h2database - h2 - runtime - - - org.springframework.boot - spring-boot-starter-web - - - - org.projectlombok - lombok - true - - - javax.xml.bind - jaxb-api - 2.3.0 - - - org.junit.jupiter - junit-jupiter-engine - 5.7.2 - test - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.projectlombok - lombok - - - - - - - - diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/Application.java b/hexagonal/src/main/java/com/baeldung/hexagonal/Application.java deleted file mode 100644 index eb762f615d..0000000000 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/Application.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung.hexagonal; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ItemTransportObject.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ItemTransportObject.java deleted file mode 100644 index bcf38e99a0..0000000000 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ItemTransportObject.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.baeldung.hexagonal.adapter.in; - -import lombok.Data; - -@Data -class ItemTransportObject { - private String name; - private Integer quantity; - private String category; -} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java deleted file mode 100644 index ffaa1a1a08..0000000000 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/in/ShoppingCartController.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.baeldung.hexagonal.adapter.in; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import com.baeldung.hexagonal.domain.ShoppingCartService; - -@RestController -@RequestMapping("/shopping-cart") -public class ShoppingCartController { - - @Autowired - ShoppingCartService shoppingCartService; - - @GetMapping - public Float getTotalCartValue() { - return shoppingCartService.getTotalCartValue(); - } - - @PostMapping() - public void addItem(@RequestBody ItemTransportObject item) { - shoppingCartService.addItem(item.getName(), item.getQuantity()); - } -} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/Product.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/Product.java deleted file mode 100644 index 00a330b50a..0000000000 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/Product.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.baeldung.hexagonal.adapter.out; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; - -import com.baeldung.hexagonal.domain.CartItem; - -import lombok.Data; - -@Entity -@Data -public class Product { - - @Id - public final Integer id; - @Column - public final String name; - @Column - public final Float price; - - public CartItem toItem() { - return new CartItem(name, price); - } - -} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/ProductCrudRepository.java b/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/ProductCrudRepository.java deleted file mode 100644 index 3708a1a19d..0000000000 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/adapter/out/ProductCrudRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung.hexagonal.adapter.out; - -import org.springframework.data.repository.CrudRepository; -import org.springframework.stereotype.Repository; - -import com.baeldung.hexagonal.domain.ports.ProductRepository; - -@Repository -public interface ProductCrudRepository extends CrudRepository, ProductRepository { - - Product findByName(String name); -} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/CartItem.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/CartItem.java deleted file mode 100644 index 1e0fcfb50e..0000000000 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/CartItem.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.baeldung.hexagonal.domain; - -import lombok.Data; -import lombok.NonNull; - -@Data -public class CartItem { - - @NonNull - private final String name; - private final Float price; - -} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCart.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCart.java deleted file mode 100644 index 949090eb80..0000000000 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCart.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.baeldung.hexagonal.domain; - -import java.util.Map; - -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -class ShoppingCart { - - private final Map itemToQuantity; - - Float getTotalCartValue() { - return itemToQuantity.entrySet() - .stream() - .map(item -> item.getKey() - .getPrice() * item.getValue()) - .reduce(0f, Float::sum); - } - - void addItem(CartItem cartItem, Integer quantity) { - if (quantity < 0) - throw new IllegalArgumentException("Quantity should not be negative."); - itemToQuantity.put(cartItem, itemToQuantity.getOrDefault(cartItem, 0) + quantity); - } -} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java deleted file mode 100644 index 022020e298..0000000000 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ShoppingCartService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.hexagonal.domain; - -public interface ShoppingCartService { - - Float getTotalCartValue(); - - void addItem(String name, Integer quantity); -} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/SimpleShoppingCartService.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/SimpleShoppingCartService.java deleted file mode 100644 index 9bced883a5..0000000000 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/SimpleShoppingCartService.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.baeldung.hexagonal.domain; - -import java.util.HashMap; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.baeldung.hexagonal.adapter.out.Product; -import com.baeldung.hexagonal.domain.ports.ProductRepository; - -@Service -public class SimpleShoppingCartService implements ShoppingCartService { - - private final ShoppingCart shoppingCart; - - @Autowired - ProductRepository productRepository; - - public SimpleShoppingCartService() { - this.shoppingCart = new ShoppingCart(new HashMap<>()); - } - - public Float getTotalCartValue() { - return shoppingCart.getTotalCartValue(); - } - - public void addItem(String name, Integer quantity) { - Product product = productRepository.findByName(name); - shoppingCart.addItem(product.toItem(), quantity); - } -} diff --git a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ports/ProductRepository.java b/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ports/ProductRepository.java deleted file mode 100644 index b4f53beb1e..0000000000 --- a/hexagonal/src/main/java/com/baeldung/hexagonal/domain/ports/ProductRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.hexagonal.domain.ports; - -import com.baeldung.hexagonal.adapter.out.Product; - -public interface ProductRepository { - - Product findByName(String name); -} diff --git a/hexagonal/src/main/resources/application.properties b/hexagonal/src/main/resources/application.properties deleted file mode 100644 index 730dded1b7..0000000000 --- a/hexagonal/src/main/resources/application.properties +++ /dev/null @@ -1,5 +0,0 @@ -spring.datasource.url=jdbc:h2:mem:testdb -spring.datasource.driverClassName=org.h2.Driver -spring.datasource.username=sa -spring.datasource.password=password -spring.jpa.database-platform=org.hibernate.dialect.H2Dialect \ No newline at end of file diff --git a/hexagonal/src/test/java/com/baeldung/hexagonal/domain/ShoppingCartTest.java b/hexagonal/src/test/java/com/baeldung/hexagonal/domain/ShoppingCartTest.java deleted file mode 100644 index c39892a8fa..0000000000 --- a/hexagonal/src/test/java/com/baeldung/hexagonal/domain/ShoppingCartTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.baeldung.hexagonal.domain; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -class ShoppingCartTest { - - @Test - void givenNonemptyShoppingCart_whenGetTotalCartValueCalled_thenShouldCalculateCorrectly() { - - // given - Map items = new HashMap<>(); - items.put(new CartItem("Cheese", 1.5f), 2); - items.put(new CartItem("Lemon", 2f), 5); - - ShoppingCart cart = new ShoppingCart(items); - - // when - Float totalCartValue = cart.getTotalCartValue(); - - // then - assertEquals(totalCartValue, 13f, 0); - } -} From 80f9c20edf3a25d5e92682c3ada354b4fdaac022 Mon Sep 17 00:00:00 2001 From: asia Date: Sun, 5 Sep 2021 11:16:30 +0200 Subject: [PATCH 008/249] Refactoring based on the feedback --- .../pom.xml | 148 ++++++++---------- .../BenchmarkRunner.java | 3 +- .../ObjectsCopyBenchmark.java | 2 +- .../PrimitivesCopyBenchmark.java | 3 +- 4 files changed, 70 insertions(+), 86 deletions(-) rename core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/{jmh => copyArrayMethodsPerformance}/BenchmarkRunner.java (73%) rename core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/{jmh => copyArrayMethodsPerformance}/ObjectsCopyBenchmark.java (94%) rename core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/{jmh => copyArrayMethodsPerformance}/PrimitivesCopyBenchmark.java (94%) diff --git a/core-java-modules/core-java-arrays-operations-advanced/pom.xml b/core-java-modules/core-java-arrays-operations-advanced/pom.xml index 57574de4a3..f690b4d17d 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/pom.xml +++ b/core-java-modules/core-java-arrays-operations-advanced/pom.xml @@ -1,93 +1,75 @@ - 4.0.0 - core-java-arrays-operations-advanced - core-java-arrays-operations-advanced - jar + 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"> + 4.0.0 + core-java-arrays-operations-advanced + core-java-arrays-operations-advanced + jar - - core-java-modules - com.baeldung.core-java-modules - 0.0.1-SNAPSHOT - + + core-java-modules + com.baeldung.core-java-modules + 0.0.1-SNAPSHOT + - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + - - org.assertj - assertj-core - ${assertj-core.version} - test - + + org.assertj + assertj-core + ${assertj-core.version} + test + - - org.openjdk.jmh - jmh-core - ${jmh.version} - - - org.openjdk.jmh - jmh-generator-annprocess - ${jmh.version} - - + + org.openjdk.jmh + jmh-core + ${jmh.version} + - - 3.10.0 - 1.22 - UTF-8 - 1.33 - 3.0.2 - 0.10 - 3.2.0 - + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + + - - - - org.apache.maven.plugins - maven-jar-plugin - ${maven-jar-plugin.version} - - - - com.baeldung.BenchmarkRunner - - - - - - org.apache.maven.plugins - maven-assembly-plugin - ${maven-assembly-plugin.version} - - - jar-with-dependencies - - - - com.baeldung.jmh.BenchmarkRunner - - - - - - make-assembly - package - - single - - - - - - + + 3.10.0 + 1.33 + + + + + + maven-assembly-plugin + + + jar-with-dependencies + + + + com.baeldung.copyArrayMethodsPerformance.BenchmarkRunner + + + + + + make-assembly + package + + single + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/BenchmarkRunner.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/BenchmarkRunner.java similarity index 73% rename from core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/BenchmarkRunner.java rename to core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/BenchmarkRunner.java index 96e2a8833e..b34b121e1a 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/BenchmarkRunner.java +++ b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/BenchmarkRunner.java @@ -1,8 +1,9 @@ -package com.baeldung.jmh; +package com.baeldung.copyArrayMethodsPerformance; public class BenchmarkRunner { public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); } diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/ObjectsCopyBenchmark.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/ObjectsCopyBenchmark.java similarity index 94% rename from core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/ObjectsCopyBenchmark.java rename to core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/ObjectsCopyBenchmark.java index 2cfa00b0e8..4c9992a38d 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/ObjectsCopyBenchmark.java +++ b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/ObjectsCopyBenchmark.java @@ -1,4 +1,4 @@ -package com.baeldung.jmh; +package com.baeldung.copyArrayMethodsPerformance; import org.openjdk.jmh.annotations.*; diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/PrimitivesCopyBenchmark.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/PrimitivesCopyBenchmark.java similarity index 94% rename from core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/PrimitivesCopyBenchmark.java rename to core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/PrimitivesCopyBenchmark.java index f51ceadf2a..e3fcc8568f 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/jmh/PrimitivesCopyBenchmark.java +++ b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/PrimitivesCopyBenchmark.java @@ -1,4 +1,4 @@ -package com.baeldung.jmh; +package com.baeldung.copyArrayMethodsPerformance; import org.openjdk.jmh.annotations.*; @@ -16,6 +16,7 @@ public class PrimitivesCopyBenchmark { @Param({ "10", "1000000" }) public int SIZE; + int[] src; @Setup From 52581b66722af0d70cfc6088a5d3538e7ffc3ae1 Mon Sep 17 00:00:00 2001 From: asia Date: Tue, 7 Sep 2021 10:12:09 +0200 Subject: [PATCH 009/249] Refactoring based on feedback - package rename --- core-java-modules/core-java-arrays-operations-advanced/pom.xml | 2 +- .../baeldung/copyArrayMethodsPerformance/BenchmarkRunner.java | 2 +- .../copyArrayMethodsPerformance/ObjectsCopyBenchmark.java | 2 +- .../copyArrayMethodsPerformance/PrimitivesCopyBenchmark.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core-java-modules/core-java-arrays-operations-advanced/pom.xml b/core-java-modules/core-java-arrays-operations-advanced/pom.xml index f690b4d17d..065f1930e2 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/pom.xml +++ b/core-java-modules/core-java-arrays-operations-advanced/pom.xml @@ -55,7 +55,7 @@ - com.baeldung.copyArrayMethodsPerformance.BenchmarkRunner + com.baeldung.copyarraymethodsperformance.BenchmarkRunner diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/BenchmarkRunner.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/BenchmarkRunner.java index b34b121e1a..0adbcc1986 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/BenchmarkRunner.java +++ b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/BenchmarkRunner.java @@ -1,4 +1,4 @@ -package com.baeldung.copyArrayMethodsPerformance; +package com.baeldung.copyarraymethodsperformance; public class BenchmarkRunner { diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/ObjectsCopyBenchmark.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/ObjectsCopyBenchmark.java index 4c9992a38d..6a492bf0d1 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/ObjectsCopyBenchmark.java +++ b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/ObjectsCopyBenchmark.java @@ -1,4 +1,4 @@ -package com.baeldung.copyArrayMethodsPerformance; +package com.baeldung.copyarraymethodsperformance; import org.openjdk.jmh.annotations.*; diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/PrimitivesCopyBenchmark.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/PrimitivesCopyBenchmark.java index e3fcc8568f..767e91a350 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/PrimitivesCopyBenchmark.java +++ b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/PrimitivesCopyBenchmark.java @@ -1,4 +1,4 @@ -package com.baeldung.copyArrayMethodsPerformance; +package com.baeldung.copyarraymethodsperformance; import org.openjdk.jmh.annotations.*; From 23e4df15ff00e63e515468bdc8e61d770576fb48 Mon Sep 17 00:00:00 2001 From: asia Date: Tue, 7 Sep 2021 10:26:07 +0200 Subject: [PATCH 010/249] Directory rename --- .../BenchmarkRunner.java | 0 .../ObjectsCopyBenchmark.java | 0 .../PrimitivesCopyBenchmark.java | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/{copyArrayMethodsPerformance => copyarraymethodsperformance}/BenchmarkRunner.java (100%) rename core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/{copyArrayMethodsPerformance => copyarraymethodsperformance}/ObjectsCopyBenchmark.java (100%) rename core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/{copyArrayMethodsPerformance => copyarraymethodsperformance}/PrimitivesCopyBenchmark.java (100%) diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/BenchmarkRunner.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/BenchmarkRunner.java similarity index 100% rename from core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/BenchmarkRunner.java rename to core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/BenchmarkRunner.java diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/ObjectsCopyBenchmark.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/ObjectsCopyBenchmark.java similarity index 100% rename from core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/ObjectsCopyBenchmark.java rename to core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/ObjectsCopyBenchmark.java diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/PrimitivesCopyBenchmark.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/PrimitivesCopyBenchmark.java similarity index 100% rename from core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyArrayMethodsPerformance/PrimitivesCopyBenchmark.java rename to core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/PrimitivesCopyBenchmark.java From fa5d7221e92a7ba8f6068077961916f6c5c0c40a Mon Sep 17 00:00:00 2001 From: asia Date: Mon, 20 Sep 2021 12:32:52 +0200 Subject: [PATCH 011/249] BAEL-5149 Remove accents from String in Java --- .../StringNormalizer.java | 49 +++++++++++++++++++ .../StringNormalizerUnitTest.java | 44 +++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizer.java create mode 100644 core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizerUnitTest.java diff --git a/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizer.java b/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizer.java new file mode 100644 index 0000000000..fe02edfe5d --- /dev/null +++ b/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizer.java @@ -0,0 +1,49 @@ +package com.baeldung.accentsanddiacriticsremoval; + +import org.apache.commons.lang3.StringUtils; + +import java.text.Normalizer; +import java.util.StringJoiner; + +class StringNormalizer { + + static String removeAccentsWithApacheCommons(String input) { + return StringUtils.stripAccents(input); + } + + static String removeAccents(String input) { + return normalize(input).replaceAll("\\p{InCombiningDiacriticalMarks}+", ""); + } + + static String unicodeValueOfNormalizedString(String input) { + return toUnicode(normalize(input)); + } + + private static String normalize(String input) { + return input == null ? null : Normalizer.normalize(input, Normalizer.Form.NFD); + } + + private static String toUnicode(String input) { + if (input.length() == 1) { + return toUnicode(input.charAt(0)); + } else { + StringJoiner stringJoiner = new StringJoiner(" "); + for (char c : input.toCharArray()) { + stringJoiner.add(toUnicode(c)); + } + return stringJoiner.toString(); + } + } + + private static String toUnicode(char input) { + + String hex = Integer.toHexString(input); + StringBuilder sb = new StringBuilder(hex); + + while (sb.length() < 4) { + sb.insert(0, "0"); + } + sb.insert(0, "\\u"); + return sb.toString(); + } +} diff --git a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizerUnitTest.java b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizerUnitTest.java new file mode 100644 index 0000000000..5c132ca7e7 --- /dev/null +++ b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizerUnitTest.java @@ -0,0 +1,44 @@ +package com.baeldung.accentsanddiacriticsremoval; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +import com.baeldung.accentsanddiacriticsremoval.StringNormalizer; + +class StringNormalizerUnitTest { + + @Test + void givenStringWithDecomposableUnicodeCharacters_whenRemoveAccents_thenReturnASCIIString() { + assertEquals("aaaeiiiiggnnsssuuy", StringNormalizer.removeAccents("āăąēîïĩíĝġńñšŝśûůŷ")); + } + + @Test + void givenStringWithDecomposableUnicodeCharacters_whenRemoveAccentsWithApacheCommons_thenReturnASCIIString() { + assertEquals("aaaeiiiiggnnsssuuy", StringNormalizer.removeAccentsWithApacheCommons("āăąēîïĩíĝġńñšŝśûůŷ")); + } + + @Test + void givenStringWithNondecomposableUnicodeCharacters_whenRemoveAccents_thenReturnOriginalString() { + assertEquals("łđħœ", StringNormalizer.removeAccents("łđħœ")); + } + + @Test + void givenStringWithNondecomposableUnicodeCharacters_whenRemoveAccentsWithApacheCommons_thenReturnModifiedString() { + assertEquals("lđħœ", StringNormalizer.removeAccentsWithApacheCommons("łđħœ")); + } + + @Test + void givenStringWithDecomposableUnicodeCharacters_whenUnicodeValueOfNormalizedString_thenReturnUnicodeValue() { + assertEquals("\\u0061 \\u0304", StringNormalizer.unicodeValueOfNormalizedString("ā")); + assertEquals("\\u0069 \\u0308", StringNormalizer.unicodeValueOfNormalizedString("ï")); + assertEquals("\\u006e \\u0301", StringNormalizer.unicodeValueOfNormalizedString("ń")); + } + + @Test + void givenStringWithNonDecomposableUnicodeCharacters_whenUnicodeValueOfNormalizedString_thenReturnOriginalValue() { + assertEquals("\\u0142", StringNormalizer.unicodeValueOfNormalizedString("ł")); + assertEquals("\\u0127", StringNormalizer.unicodeValueOfNormalizedString("ħ")); + assertEquals("\\u0111", StringNormalizer.unicodeValueOfNormalizedString("đ")); + } +} \ No newline at end of file From 0771c47a87f9e049e17334e2cafb27841800763d Mon Sep 17 00:00:00 2001 From: asia Date: Mon, 20 Sep 2021 12:32:52 +0200 Subject: [PATCH 012/249] BAEL-5149 Remove accents from String in Java --- .../StringNormalizer.java | 49 +++++++++++++ .../CollatorTest.java | 70 +++++++++++++++++++ .../StringNormalizerUnitTest.java | 51 ++++++++++++++ 3 files changed, 170 insertions(+) create mode 100644 core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizer.java create mode 100644 core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/CollatorTest.java create mode 100644 core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizerUnitTest.java diff --git a/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizer.java b/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizer.java new file mode 100644 index 0000000000..d33b9178ea --- /dev/null +++ b/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizer.java @@ -0,0 +1,49 @@ +package com.baeldung.accentsanddiacriticsremoval; + +import org.apache.commons.lang3.StringUtils; + +import java.text.Normalizer; +import java.util.StringJoiner; + +class StringNormalizer { + + static String removeAccentsWithApacheCommons(String input) { + return StringUtils.stripAccents(input); + } + + static String removeAccents(String input) { + return normalize(input).replaceAll("\\p{M}", ""); + } + + static String unicodeValueOfNormalizedString(String input) { + return toUnicode(normalize(input)); + } + + private static String normalize(String input) { + return input == null ? null : Normalizer.normalize(input, Normalizer.Form.NFKD); + } + + private static String toUnicode(String input) { + if (input.length() == 1) { + return toUnicode(input.charAt(0)); + } else { + StringJoiner stringJoiner = new StringJoiner(" "); + for (char c : input.toCharArray()) { + stringJoiner.add(toUnicode(c)); + } + return stringJoiner.toString(); + } + } + + private static String toUnicode(char input) { + + String hex = Integer.toHexString(input); + StringBuilder sb = new StringBuilder(hex); + + while (sb.length() < 4) { + sb.insert(0, "0"); + } + sb.insert(0, "\\u"); + return sb.toString(); + } +} diff --git a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/CollatorTest.java b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/CollatorTest.java new file mode 100644 index 0000000000..26386982e6 --- /dev/null +++ b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/CollatorTest.java @@ -0,0 +1,70 @@ +package com.baeldung.accentsanddiacriticsremoval; + +import org.junit.Test; +import org.openjdk.jmh.annotations.Setup; + +import java.text.Collator; + +import static java.lang.Character.*; +import static java.lang.String.valueOf; +import static org.junit.Assert.assertEquals; + +public class CollatorTest { + + private final Collator collator = Collator.getInstance(); + + @Setup + public void setup() { + collator.setDecomposition(2); + } + + @Test + public void givenAccentedStringAndPrimaryCollatorStrength_whenCompareWithASCIIString_thenReturnTrue() { + Collator collator = Collator.getInstance(); + collator.setDecomposition(2); + collator.setStrength(0); + assertEquals(0, (collator.compare("a", "a"))); + assertEquals(0, (collator.compare("ä", "a"))); + assertEquals(0, (collator.compare("A", "a"))); + assertEquals(1, (collator.compare("b", "a"))); + assertEquals(0, (collator.compare(valueOf(toChars(0x0001)), valueOf(toChars(0x0002))))); + } + + @Test + public void givenAccentedStringAndSecondaryCollatorStrength_whenCompareWithASCIIString_thenReturnTrue() { + collator.setStrength(1); + assertEquals(1, (collator.compare("ä", "a"))); + assertEquals(1, (collator.compare("b", "a"))); + assertEquals(0, (collator.compare("A", "a"))); + assertEquals(0, (collator.compare("a", "a"))); + assertEquals(0, (collator.compare(valueOf(toChars(0x0001)), valueOf(toChars(0x0002))))); + + } + + @Test + public void givenAccentedStringAndTeriaryCollatorStrength_whenCompareWithASCIIString_thenReturnTrue() { + collator.setStrength(2); + assertEquals(1, (collator.compare("A", "a"))); + assertEquals(1, (collator.compare("ä", "a"))); + assertEquals(1, (collator.compare("b", "a"))); + assertEquals(0, (collator.compare("a", "a"))); + assertEquals(0, (collator.compare(valueOf(toChars(0x0001)), valueOf(toChars(0x0002))))); + } + + @Test + public void givenAccentedStringAndIdenticalCollatorStrength_whenCompareWithASCIIString_thenReturnTrue() { + collator.setStrength(3); + assertEquals(1, (collator.compare("A", "a"))); + assertEquals(1, (collator.compare("ä", "a"))); + assertEquals(1, (collator.compare("b", "a"))); + assertEquals(-1, (collator.compare(valueOf(toChars(0x0001)), valueOf(toChars(0x0002))))); + assertEquals(0, (collator.compare("a", "a"))); + } + + @Test + public void givenNondecomposableAccentedStringAndIdenticalCollatorStrength_whenCompareWithASCIIString_thenReturnTrue() { + collator.setStrength(0); + assertEquals(1, collator.compare("ł", "l")); + assertEquals(1, collator.compare("ø", "o")); + } +} diff --git a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizerUnitTest.java b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizerUnitTest.java new file mode 100644 index 0000000000..74359726b7 --- /dev/null +++ b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/StringNormalizerUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.accentsanddiacriticsremoval; + +import static org.junit.Assert.assertFalse; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.text.Normalizer; + +import org.junit.jupiter.api.Test; + +class StringNormalizerUnitTest { + + @Test + public void givenNotNormalizedString_whenIsNormalized_thenReturnFalse() { + assertFalse(Normalizer.isNormalized("āăąēîïĩíĝġńñšŝśûůŷ", Normalizer.Form.NFKD)); + } + + @Test + void givenStringWithDecomposableUnicodeCharacters_whenRemoveAccents_thenReturnASCIIString() { + assertEquals("aaaeiiiiggnnsssuuy", StringNormalizer.removeAccents("āăąēîïĩíĝġńñšŝśûůŷ")); + } + + @Test + void givenStringWithDecomposableUnicodeCharacters_whenRemoveAccentsWithApacheCommons_thenReturnASCIIString() { + assertEquals("aaaeiiiiggnnsssuuy", StringNormalizer.removeAccentsWithApacheCommons("āăąēîïĩíĝġńñšŝśûůŷ")); + } + + @Test + void givenStringWithNondecomposableUnicodeCharacters_whenRemoveAccents_thenReturnOriginalString() { + assertEquals("łđħœ", StringNormalizer.removeAccents("łđħœ")); + } + + @Test + void givenStringWithNondecomposableUnicodeCharacters_whenRemoveAccentsWithApacheCommons_thenReturnModifiedString() { + assertEquals("lđħœ", StringNormalizer.removeAccentsWithApacheCommons("łđħœ")); + } + + @Test + void givenStringWithDecomposableUnicodeCharacters_whenUnicodeValueOfNormalizedString_thenReturnUnicodeValue() { + assertEquals("\\u0066 \\u0069", StringNormalizer.unicodeValueOfNormalizedString("fi")); + assertEquals("\\u0061 \\u0304", StringNormalizer.unicodeValueOfNormalizedString("ā")); + assertEquals("\\u0069 \\u0308", StringNormalizer.unicodeValueOfNormalizedString("ï")); + assertEquals("\\u006e \\u0301", StringNormalizer.unicodeValueOfNormalizedString("ń")); + } + + @Test + void givenStringWithNonDecomposableUnicodeCharacters_whenUnicodeValueOfNormalizedString_thenReturnOriginalValue() { + assertEquals("\\u0142", StringNormalizer.unicodeValueOfNormalizedString("ł")); + assertEquals("\\u0127", StringNormalizer.unicodeValueOfNormalizedString("ħ")); + assertEquals("\\u0111", StringNormalizer.unicodeValueOfNormalizedString("đ")); + } +} \ No newline at end of file From 3ae4d1ee7614392371d4873925944bfd971eb623 Mon Sep 17 00:00:00 2001 From: asia Date: Mon, 11 Oct 2021 10:27:17 +0200 Subject: [PATCH 013/249] Including suggestions after a review --- .../CollatorUnitTest.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/CollatorUnitTest.java b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/CollatorUnitTest.java index 04fdcb50a1..93b4f5af2e 100644 --- a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/CollatorUnitTest.java +++ b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/accentsanddiacriticsremoval/CollatorUnitTest.java @@ -23,42 +23,42 @@ public class CollatorUnitTest { Collator collator = Collator.getInstance(); collator.setDecomposition(2); collator.setStrength(0); - assertEquals(0, (collator.compare("a", "a"))); - assertEquals(0, (collator.compare("ä", "a"))); - assertEquals(0, (collator.compare("A", "a"))); - assertEquals(1, (collator.compare("b", "a"))); - assertEquals(0, (collator.compare(valueOf(toChars(0x0001)), valueOf(toChars(0x0002))))); + assertEquals(0, collator.compare("a", "a")); + assertEquals(0, collator.compare("ä", "a")); + assertEquals(0, collator.compare("A", "a")); + assertEquals(1, collator.compare("b", "a")); + assertEquals(0, collator.compare(valueOf(toChars(0x0001)), valueOf(toChars(0x0002)))); } @Test public void givenAccentedStringAndSecondaryCollatorStrength_whenCompareWithASCIIString_thenReturnTrue() { collator.setStrength(1); - assertEquals(1, (collator.compare("ä", "a"))); - assertEquals(1, (collator.compare("b", "a"))); - assertEquals(0, (collator.compare("A", "a"))); - assertEquals(0, (collator.compare("a", "a"))); - assertEquals(0, (collator.compare(valueOf(toChars(0x0001)), valueOf(toChars(0x0002))))); + assertEquals(1, collator.compare("ä", "a")); + assertEquals(1, collator.compare("b", "a")); + assertEquals(0, collator.compare("A", "a")); + assertEquals(0, collator.compare("a", "a")); + assertEquals(0, collator.compare(valueOf(toChars(0x0001)), valueOf(toChars(0x0002)))); } @Test public void givenAccentedStringAndTeriaryCollatorStrength_whenCompareWithASCIIString_thenReturnTrue() { collator.setStrength(2); - assertEquals(1, (collator.compare("A", "a"))); - assertEquals(1, (collator.compare("ä", "a"))); - assertEquals(1, (collator.compare("b", "a"))); - assertEquals(0, (collator.compare("a", "a"))); - assertEquals(0, (collator.compare(valueOf(toChars(0x0001)), valueOf(toChars(0x0002))))); + assertEquals(1, collator.compare("A", "a")); + assertEquals(1, collator.compare("ä", "a")); + assertEquals(1, collator.compare("b", "a")); + assertEquals(0, collator.compare("a", "a")); + assertEquals(0, collator.compare(valueOf(toChars(0x0001)), valueOf(toChars(0x0002)))); } @Test public void givenAccentedStringAndIdenticalCollatorStrength_whenCompareWithASCIIString_thenReturnTrue() { collator.setStrength(3); - assertEquals(1, (collator.compare("A", "a"))); - assertEquals(1, (collator.compare("ä", "a"))); - assertEquals(1, (collator.compare("b", "a"))); - assertEquals(-1, (collator.compare(valueOf(toChars(0x0001)), valueOf(toChars(0x0002))))); - assertEquals(0, (collator.compare("a", "a"))); + assertEquals(1, collator.compare("A", "a")); + assertEquals(1, collator.compare("ä", "a")); + assertEquals(1, collator.compare("b", "a")); + assertEquals(-1, collator.compare(valueOf(toChars(0x0001)), valueOf(toChars(0x0002)))); + assertEquals(0, collator.compare("a", "a")); } @Test From 39cc6be1ab910520c843a03f704ca183e7edfd84 Mon Sep 17 00:00:00 2001 From: asia Date: Sun, 30 Jan 2022 21:19:39 +0100 Subject: [PATCH 014/249] Add SPQR project. --- .../spring-boot-libraries-2/pom.xml | 5 ++ .../src/main/java/com/baeldung/sprq/Book.java | 57 ++++++++++++++++++ .../java/com/baeldung/sprq/BookResolver.java | 42 +++++++++++++ .../java/com/baeldung/sprq/BookService.java | 48 +++++++++++++++ .../com/baeldung/sprq/GraphqlController.java | 35 +++++++++++ .../java/com/baeldung/sprq/IBookService.java | 15 +++++ .../GraphqlControllerIntegrationTest.java | 60 +++++++++++++++++++ 7 files changed, 262 insertions(+) create mode 100644 spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/Book.java create mode 100644 spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/BookResolver.java create mode 100644 spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/BookService.java create mode 100644 spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/GraphqlController.java create mode 100644 spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/IBookService.java create mode 100644 spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/sprq/GraphqlControllerIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-libraries-2/pom.xml b/spring-boot-modules/spring-boot-libraries-2/pom.xml index 04c09754b4..f62a341efc 100644 --- a/spring-boot-modules/spring-boot-libraries-2/pom.xml +++ b/spring-boot-modules/spring-boot-libraries-2/pom.xml @@ -57,6 +57,11 @@ ${awaitility.version} test + + io.leangen.graphql + spqr + 0.11.2 + diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/Book.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/Book.java new file mode 100644 index 0000000000..c6ff9e515a --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/Book.java @@ -0,0 +1,57 @@ +package com.baeldung.sprq; + +import java.util.Objects; + +public class Book { + private Integer id; + private String author; + private String title; + + public Book(Integer id, String author, String title) { + this.id = id; + this.author = author; + this.title = title; + } + + public Book() { + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Book book = (Book) o; + return id.equals(book.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/BookResolver.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/BookResolver.java new file mode 100644 index 0000000000..747d52f0af --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/BookResolver.java @@ -0,0 +1,42 @@ +package com.baeldung.sprq; + +import io.leangen.graphql.annotations.GraphQLArgument; +import io.leangen.graphql.annotations.GraphQLMutation; +import io.leangen.graphql.annotations.GraphQLQuery; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class BookResolver { + + @Autowired + IBookService bookService; + + @GraphQLQuery(name = "getBookWithTitle") + public Book getBookWithTitle(@GraphQLArgument(name = "title") String title) { + return bookService.getBookWithTitle(title); + } + + @GraphQLQuery(name = "getAllBooks", description = "Get all books") + public List getAllBooks() { + return bookService.getAllBooks(); + } + + @GraphQLMutation(name = "addBook") + public Book addBook(@GraphQLArgument(name = "newBook") Book book) { + return bookService.addBook(book); + } + + @GraphQLMutation(name = "updateBook") + public Book updateBook(@GraphQLArgument(name = "modifiedBook") Book book) { + return bookService.updateBook(book); + } + + @GraphQLMutation(name = "deleteBook") + public void deleteBook(@GraphQLArgument(name = "book") Book book) { + bookService.deleteBook(book); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/BookService.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/BookService.java new file mode 100644 index 0000000000..6dbfe9c6f9 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/BookService.java @@ -0,0 +1,48 @@ +package com.baeldung.sprq; + +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +public class BookService implements IBookService { + + Set books = new HashSet<>(); + + @Override + public Book getBookWithTitle(String title) { + return books.stream() + .filter(book -> book.getTitle() + .equals(title)) + .findFirst() + .orElse(null); + } + + @Override + public List getAllBooks() { + return books.stream() + .collect(Collectors.toList()); + } + + @Override + public Book addBook(Book book) { + books.add(book); + return book; + } + + @Override + public Book updateBook(Book book) { + books.remove(book); + books.add(book); + return book; + } + + @Override + public boolean deleteBook(Book book) { + return books.remove(book); + } +} diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/GraphqlController.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/GraphqlController.java new file mode 100644 index 0000000000..b62bdbd6a8 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/GraphqlController.java @@ -0,0 +1,35 @@ +package com.baeldung.sprq; + +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.GraphQLException; +import graphql.schema.GraphQLSchema; +import io.leangen.graphql.GraphQLSchemaGenerator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +@RestController +public class GraphqlController { + + private final GraphQL graphQL; + + @Autowired + public GraphqlController(BookResolver bookResolver) { + GraphQLSchema schema = new GraphQLSchemaGenerator().withBasePackages("com.baeldung") + .withOperationsFromSingleton(bookResolver) + .generate(); + this.graphQL = new GraphQL.Builder(schema).build(); + } + + @PostMapping(value = "/graphql") + public Map execute(@RequestBody Map request, HttpServletRequest raw) throws GraphQLException { + ExecutionResult result = graphQL.execute(request.get("query")); + return result.getData(); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/IBookService.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/IBookService.java new file mode 100644 index 0000000000..1c1257c178 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/sprq/IBookService.java @@ -0,0 +1,15 @@ +package com.baeldung.sprq; + +import java.util.List; + +public interface IBookService { + Book getBookWithTitle(String title); + + List getAllBooks(); + + Book addBook(Book book); + + Book updateBook(Book book); + + boolean deleteBook(Book book); +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/sprq/GraphqlControllerIntegrationTest.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/sprq/GraphqlControllerIntegrationTest.java new file mode 100644 index 0000000000..65b6ff1e0b --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/sprq/GraphqlControllerIntegrationTest.java @@ -0,0 +1,60 @@ +package com.baeldung.sprq; + +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class GraphqlControllerIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + BookService bookService; + + private static final String GRAPHQL_PATH = "/graphql"; + + @Test + public void givenNoBooks_whenReadAll_thenStatusIsOk() throws Exception { + + String getAllBooksQuery = "{\n" + " getAllBooks {\n" + " id\n" + " author\n" + " title\n" + " }\n" + "}\n"; + + this.mockMvc.perform(post(GRAPHQL_PATH).content(toJSON(getAllBooksQuery)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.getAllBooks").isEmpty()); + } + + @Test + public void whenAddBook_thenStatusIsOk() throws Exception { + + String addBookMutation = "mutation {\n" + " addBook(newBook: {id: 123, author: \"J.R.R. Tolkien\", title: \"The Lord of the Rings\"}) {\n" + " id\n" + " author\n" + " title\n" + " }\n" + "}\n"; + + this.mockMvc.perform(post(GRAPHQL_PATH).content(toJSON(addBookMutation)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.addBook.id").value("123")) + .andExpect(jsonPath("$.addBook.author").value("J.R.R. Tolkien")) + .andExpect(jsonPath("$.addBook.title").value("The Lord of the Rings")); + } + + private String toJSON(String query) throws JSONException { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("query", query); + return jsonObject.toString(); + } +} \ No newline at end of file From 94a58e4d52d07dad1c341e9fb931fbf2b92b6a06 Mon Sep 17 00:00:00 2001 From: konanaw Date: Mon, 31 Jan 2022 01:11:43 +0300 Subject: [PATCH 015/249] Problem: file 'sample.txt' has empty content after downloading from DownloadServlet. Fix: file moved to webapps/WEB-INF --- javax-servlets/src/main/webapp/{ => WEB-INF}/sample.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename javax-servlets/src/main/webapp/{ => WEB-INF}/sample.txt (100%) diff --git a/javax-servlets/src/main/webapp/sample.txt b/javax-servlets/src/main/webapp/WEB-INF/sample.txt similarity index 100% rename from javax-servlets/src/main/webapp/sample.txt rename to javax-servlets/src/main/webapp/WEB-INF/sample.txt From fc36443ae2742d2f4565c1ebdff609b2a4c44900 Mon Sep 17 00:00:00 2001 From: Attila Uhrin Date: Sun, 30 Jan 2022 10:58:44 +0100 Subject: [PATCH 016/249] Add implementation for BAEL-5317. --- spring-sleuth/pom.xml | 2 +- .../traceid/SleuthCurrentTraceIdApp.java | 11 +++++++ .../traceid/SleuthTraceIdController.java | 32 +++++++++++++++++++ .../CurrentTraceIdAppSpringContextTest.java | 15 +++++++++ .../session}/SpringContextTest.java | 4 +-- 5 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthCurrentTraceIdApp.java create mode 100644 spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthTraceIdController.java create mode 100644 spring-sleuth/src/test/java/com/baeldung/sleuth/traceid/CurrentTraceIdAppSpringContextTest.java rename spring-sleuth/src/test/java/com/baeldung/{ => spring/session}/SpringContextTest.java (83%) diff --git a/spring-sleuth/pom.xml b/spring-sleuth/pom.xml index 5fd109e968..a6fba5ea56 100644 --- a/spring-sleuth/pom.xml +++ b/spring-sleuth/pom.xml @@ -39,7 +39,7 @@ - 2.0.2.RELEASE + 3.1.0 \ No newline at end of file diff --git a/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthCurrentTraceIdApp.java b/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthCurrentTraceIdApp.java new file mode 100644 index 0000000000..bae1d310a2 --- /dev/null +++ b/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthCurrentTraceIdApp.java @@ -0,0 +1,11 @@ +package com.baeldung.sleuth.traceid; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SleuthCurrentTraceIdApp { + public static void main(String[] args) { + SpringApplication.run(SleuthCurrentTraceIdApp.class, args); + } +} diff --git a/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthTraceIdController.java b/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthTraceIdController.java new file mode 100644 index 0000000000..fb4bf2bb1a --- /dev/null +++ b/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthTraceIdController.java @@ -0,0 +1,32 @@ +package com.baeldung.sleuth.traceid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import brave.Span; +import brave.Tracer; + +@RestController +public class SleuthTraceIdController { + + private static final Logger logger = LoggerFactory.getLogger(SleuthTraceIdController.class); + + @Autowired + private Tracer tracer; + + @GetMapping("/hello") + public String hello() { + logger.info("Hello with Sleuth"); + Span span = tracer.currentSpan(); + if (span != null) { + logger.info("Span ID hex {}", span.context().spanIdString()); + logger.info("Span ID decimal {}", span.context().spanId()); + logger.info("Trace ID hex {}", span.context().traceIdString()); + logger.info("Trace ID decimal {}", span.context().traceId()); + } + return "hello"; + } +} diff --git a/spring-sleuth/src/test/java/com/baeldung/sleuth/traceid/CurrentTraceIdAppSpringContextTest.java b/spring-sleuth/src/test/java/com/baeldung/sleuth/traceid/CurrentTraceIdAppSpringContextTest.java new file mode 100644 index 0000000000..ba181d730b --- /dev/null +++ b/spring-sleuth/src/test/java/com/baeldung/sleuth/traceid/CurrentTraceIdAppSpringContextTest.java @@ -0,0 +1,15 @@ +package com.baeldung.sleuth.traceid; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SleuthCurrentTraceIdApp.class) +public class CurrentTraceIdAppSpringContextTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-sleuth/src/test/java/com/baeldung/SpringContextTest.java b/spring-sleuth/src/test/java/com/baeldung/spring/session/SpringContextTest.java similarity index 83% rename from spring-sleuth/src/test/java/com/baeldung/SpringContextTest.java rename to spring-sleuth/src/test/java/com/baeldung/spring/session/SpringContextTest.java index 8dc2455e63..7ddd194632 100644 --- a/spring-sleuth/src/test/java/com/baeldung/SpringContextTest.java +++ b/spring-sleuth/src/test/java/com/baeldung/spring/session/SpringContextTest.java @@ -1,12 +1,10 @@ -package com.baeldung; +package com.baeldung.spring.session; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.spring.session.SleuthWebApp; - @RunWith(SpringRunner.class) @SpringBootTest(classes = SleuthWebApp.class) public class SpringContextTest { From e8d5b236cca677853a34425d8e940e1863aa96fb Mon Sep 17 00:00:00 2001 From: Attila Uhrin Date: Sun, 30 Jan 2022 11:04:38 +0100 Subject: [PATCH 017/249] Rename API endpoint. --- .../baeldung/sleuth/traceid/SleuthTraceIdController.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthTraceIdController.java b/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthTraceIdController.java index fb4bf2bb1a..07dca487d0 100644 --- a/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthTraceIdController.java +++ b/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthTraceIdController.java @@ -17,8 +17,8 @@ public class SleuthTraceIdController { @Autowired private Tracer tracer; - @GetMapping("/hello") - public String hello() { + @GetMapping("/traceid") + public String getSleuthTraceId() { logger.info("Hello with Sleuth"); Span span = tracer.currentSpan(); if (span != null) { @@ -27,6 +27,6 @@ public class SleuthTraceIdController { logger.info("Trace ID hex {}", span.context().traceIdString()); logger.info("Trace ID decimal {}", span.context().traceId()); } - return "hello"; + return "Hello from Sleuth"; } } From 6147f0b70cc105bf16b53e7a6a6accef153b374d Mon Sep 17 00:00:00 2001 From: Attila Uhrin Date: Mon, 31 Jan 2022 22:10:09 +0100 Subject: [PATCH 018/249] Remove empty test case. --- .../{spring/session => }/SpringContextTest.java | 4 +++- .../CurrentTraceIdAppSpringContextTest.java | 15 --------------- 2 files changed, 3 insertions(+), 16 deletions(-) rename spring-sleuth/src/test/java/com/baeldung/{spring/session => }/SpringContextTest.java (83%) delete mode 100644 spring-sleuth/src/test/java/com/baeldung/sleuth/traceid/CurrentTraceIdAppSpringContextTest.java diff --git a/spring-sleuth/src/test/java/com/baeldung/spring/session/SpringContextTest.java b/spring-sleuth/src/test/java/com/baeldung/SpringContextTest.java similarity index 83% rename from spring-sleuth/src/test/java/com/baeldung/spring/session/SpringContextTest.java rename to spring-sleuth/src/test/java/com/baeldung/SpringContextTest.java index 7ddd194632..8dc2455e63 100644 --- a/spring-sleuth/src/test/java/com/baeldung/spring/session/SpringContextTest.java +++ b/spring-sleuth/src/test/java/com/baeldung/SpringContextTest.java @@ -1,10 +1,12 @@ -package com.baeldung.spring.session; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import com.baeldung.spring.session.SleuthWebApp; + @RunWith(SpringRunner.class) @SpringBootTest(classes = SleuthWebApp.class) public class SpringContextTest { diff --git a/spring-sleuth/src/test/java/com/baeldung/sleuth/traceid/CurrentTraceIdAppSpringContextTest.java b/spring-sleuth/src/test/java/com/baeldung/sleuth/traceid/CurrentTraceIdAppSpringContextTest.java deleted file mode 100644 index ba181d730b..0000000000 --- a/spring-sleuth/src/test/java/com/baeldung/sleuth/traceid/CurrentTraceIdAppSpringContextTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.baeldung.sleuth.traceid; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SleuthCurrentTraceIdApp.class) -public class CurrentTraceIdAppSpringContextTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} From 9cb6ff1227750aeb25db44183ce945f6bcf9835e Mon Sep 17 00:00:00 2001 From: Graham Cox Date: Thu, 3 Feb 2022 07:47:26 +0000 Subject: [PATCH 019/249] BAEL-5229: Code for Fauna article --- persistence-modules/fauna/.gitignore | 1 + persistence-modules/fauna/pom.xml | 56 ++++++++ .../faunablog/FaunaBlogApplication.java | 13 ++ .../faunablog/FaunaConfiguration.java | 25 ++++ .../faunablog/WebSecurityConfiguration.java | 35 +++++ .../com/baeldung/faunablog/posts/Author.java | 3 + .../com/baeldung/faunablog/posts/Post.java | 5 + .../faunablog/posts/PostsController.java | 50 +++++++ .../faunablog/posts/PostsService.java | 124 ++++++++++++++++++ .../baeldung/faunablog/posts/UpdatedPost.java | 3 + .../users/FaunaUserDetailsService.java | 44 +++++++ .../src/main/resources/application.properties | 0 12 files changed, 359 insertions(+) create mode 100644 persistence-modules/fauna/.gitignore create mode 100644 persistence-modules/fauna/pom.xml create mode 100644 persistence-modules/fauna/src/main/java/com/baeldung/faunablog/FaunaBlogApplication.java create mode 100644 persistence-modules/fauna/src/main/java/com/baeldung/faunablog/FaunaConfiguration.java create mode 100644 persistence-modules/fauna/src/main/java/com/baeldung/faunablog/WebSecurityConfiguration.java create mode 100644 persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/Author.java create mode 100644 persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/Post.java create mode 100644 persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/PostsController.java create mode 100644 persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/PostsService.java create mode 100644 persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/UpdatedPost.java create mode 100644 persistence-modules/fauna/src/main/java/com/baeldung/faunablog/users/FaunaUserDetailsService.java create mode 100644 persistence-modules/fauna/src/main/resources/application.properties diff --git a/persistence-modules/fauna/.gitignore b/persistence-modules/fauna/.gitignore new file mode 100644 index 0000000000..c37fa0c4b3 --- /dev/null +++ b/persistence-modules/fauna/.gitignore @@ -0,0 +1 @@ +/application.properties diff --git a/persistence-modules/fauna/pom.xml b/persistence-modules/fauna/pom.xml new file mode 100644 index 0000000000..72c0f0a751 --- /dev/null +++ b/persistence-modules/fauna/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.6.2 + + + com.baeldung + fauna-blog + 0.0.1-SNAPSHOT + fauna-blog + Blogging Service built with FaunaDB + + 17 + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-web + + + com.faunadb + faunadb-java + 4.2.0 + compile + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/FaunaBlogApplication.java b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/FaunaBlogApplication.java new file mode 100644 index 0000000000..f0ca6881b7 --- /dev/null +++ b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/FaunaBlogApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.faunablog; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class FaunaBlogApplication { + + public static void main(String[] args) { + SpringApplication.run(FaunaBlogApplication.class, args); + } + +} diff --git a/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/FaunaConfiguration.java b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/FaunaConfiguration.java new file mode 100644 index 0000000000..9964431475 --- /dev/null +++ b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/FaunaConfiguration.java @@ -0,0 +1,25 @@ +package com.baeldung.faunablog; + +import com.faunadb.client.FaunaClient; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.net.MalformedURLException; + +@Configuration +class FaunaConfiguration { + @Value("https://db.${fauna.region}.fauna.com/") + private String faunaUrl; + + @Value("${fauna.secret}") + private String faunaSecret; + + @Bean + FaunaClient getFaunaClient() throws MalformedURLException { + return FaunaClient.builder() + .withEndpoint(faunaUrl) + .withSecret(faunaSecret) + .build(); + } +} diff --git a/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/WebSecurityConfiguration.java b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/WebSecurityConfiguration.java new file mode 100644 index 0000000000..da99b7578e --- /dev/null +++ b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/WebSecurityConfiguration.java @@ -0,0 +1,35 @@ +package com.baeldung.faunablog; + +import com.baeldung.faunablog.users.FaunaUserDetailsService; +import com.faunadb.client.FaunaClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.UserDetailsService; + +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { + + @Autowired + private FaunaClient faunaClient; + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf().disable(); + http.authorizeRequests() + .antMatchers("/**").permitAll() + .and().httpBasic(); + } + + @Bean + @Override + public UserDetailsService userDetailsService() { + return new FaunaUserDetailsService(faunaClient); + } +} diff --git a/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/Author.java b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/Author.java new file mode 100644 index 0000000000..ec4854621d --- /dev/null +++ b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/Author.java @@ -0,0 +1,3 @@ +package com.baeldung.faunablog.posts; + +public record Author(String username, String name) {} diff --git a/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/Post.java b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/Post.java new file mode 100644 index 0000000000..62b6558a37 --- /dev/null +++ b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/Post.java @@ -0,0 +1,5 @@ +package com.baeldung.faunablog.posts; + +import java.time.Instant; + +public record Post(String id, String title, String content, Author author, Instant created, Long version) {} diff --git a/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/PostsController.java b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/PostsController.java new file mode 100644 index 0000000000..e8e6316ea8 --- /dev/null +++ b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/PostsController.java @@ -0,0 +1,50 @@ +package com.baeldung.faunablog.posts; + +import com.faunadb.client.errors.NotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.server.ResponseStatusException; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +@RestController +@RequestMapping("/posts") +public class PostsController { + @Autowired + private PostsService postsService; + + @GetMapping + public List listPosts(@RequestParam(value = "author", required = false) String author) throws ExecutionException, InterruptedException { + return author == null ? postsService.getAllPosts() : postsService.getAuthorPosts("graham"); + } + + @GetMapping("/{id}") + public Post getPost(@PathVariable("id") String id, @RequestParam(value = "before", required = false) Long before) + throws ExecutionException, InterruptedException { + return postsService.getPost(id, before); + } + + @PostMapping + @ResponseStatus(HttpStatus.NO_CONTENT) + @PreAuthorize("isAuthenticated()") + public void createPost(@RequestBody UpdatedPost post) throws ExecutionException, InterruptedException { + String name = SecurityContextHolder.getContext().getAuthentication().getName(); + postsService.createPost(name, post.title(), post.content()); + } + + @PutMapping("/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @PreAuthorize("isAuthenticated()") + public void updatePost(@PathVariable("id") String id, @RequestBody UpdatedPost post) + throws ExecutionException, InterruptedException { + postsService.updatePost(id, post.title(), post.content()); + } + + @ExceptionHandler(NotFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public void postNotFound() {} +} diff --git a/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/PostsService.java b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/PostsService.java new file mode 100644 index 0000000000..5143a24b28 --- /dev/null +++ b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/PostsService.java @@ -0,0 +1,124 @@ +package com.baeldung.faunablog.posts; + +import com.faunadb.client.FaunaClient; +import com.faunadb.client.types.Value; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.Instant; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; + +import static com.faunadb.client.query.Language.*; + +@Component +public class PostsService { + @Autowired + private FaunaClient faunaClient; + + Post getPost(String id, Long before) throws ExecutionException, InterruptedException { + var query = Get(Ref(Collection("posts"), id)); + if (before != null) { + query = At(Value(before - 1), query); + } + + var postResult= faunaClient.query( + Let( + "post", query + ).in( + Obj( + "post", Var("post"), + "author", Get(Select(Arr(Value("data"), Value("authorRef")), Var("post"))) + ) + )).get(); + + return parsePost(postResult); + } + + List getAllPosts() throws ExecutionException, InterruptedException { + var postsResult = faunaClient.query(Map( + Paginate( + Join( + Documents(Collection("posts")), + Index("posts_sort_by_created_desc") + ) + ), + Lambda( + Arr(Value("extra"), Value("ref")), + Obj( + "post", Get(Var("ref")), + "author", Get(Select(Arr(Value("data"), Value("authorRef")), Get(Var("ref")))) + ) + ) + )).get(); + + var posts = postsResult.at("data").asCollectionOf(Value.class).get(); + return posts.stream().map(this::parsePost).collect(Collectors.toList()); + } + + List getAuthorPosts(String author) throws ExecutionException, InterruptedException { + var postsResult = faunaClient.query(Map( + Paginate( + Join( + Match(Index("posts_by_author"), Select(Value("ref"), Get(Match(Index("users_by_username"), Value(author))))), + Index("posts_sort_by_created_desc") + ) + ), + Lambda( + Arr(Value("extra"), Value("ref")), + Obj( + "post", Get(Var("ref")), + "author", Get(Select(Arr(Value("data"), Value("authorRef")), Get(Var("ref")))) + ) + ) + )).get(); + + var posts = postsResult.at("data").asCollectionOf(Value.class).get(); + return posts.stream().map(this::parsePost).collect(Collectors.toList()); + } + + public void createPost(String author, String title, String contents) throws ExecutionException, InterruptedException { + faunaClient.query( + Create(Collection("posts"), + Obj( + "data", Obj( + "title", Value(title), + "contents", Value(contents), + "created", Now(), + "authorRef", Select(Value("ref"), Get(Match(Index("users_by_username"), Value(author))))) + ) + ) + ).get(); + } + + public void updatePost(String id, String title, String contents) throws ExecutionException, InterruptedException { + faunaClient.query( + Update(Ref(Collection("posts"), id), + Obj( + "data", Obj( + "title", Value(title), + "contents", Value(contents)) + ) + ) + ).get(); + } + + private Post parsePost(Value entry) { + var author = entry.at("author"); + var post = entry.at("post"); + + return new Post( + post.at("ref").to(Value.RefV.class).get().getId(), + post.at("data", "title").to(String.class).get(), + post.at("data", "contents").to(String.class).get(), + new Author( + author.at("data", "username").to(String.class).get(), + author.at("data", "name").to(String.class).get() + ), + post.at("data", "created").to(Instant.class).get(), + post.at("ts").to(Long.class).get() + ); + } +} diff --git a/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/UpdatedPost.java b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/UpdatedPost.java new file mode 100644 index 0000000000..9850cd5927 --- /dev/null +++ b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/posts/UpdatedPost.java @@ -0,0 +1,3 @@ +package com.baeldung.faunablog.posts; + +public record UpdatedPost(String title, String content) {} diff --git a/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/users/FaunaUserDetailsService.java b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/users/FaunaUserDetailsService.java new file mode 100644 index 0000000000..2e88aaa477 --- /dev/null +++ b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/users/FaunaUserDetailsService.java @@ -0,0 +1,44 @@ +package com.baeldung.faunablog.users; + +import com.faunadb.client.FaunaClient; +import com.faunadb.client.types.Value; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +import java.util.concurrent.ExecutionException; + +import static com.faunadb.client.query.Language.*; + +public class FaunaUserDetailsService implements UserDetailsService { + private FaunaClient faunaClient; + + public FaunaUserDetailsService(FaunaClient faunaClient) { + this.faunaClient = faunaClient; + } + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + try { + Value user = faunaClient.query(Map( + Paginate(Match(Index("users_by_username"), Value(username))), + Lambda(Value("user"), Get(Var("user"))))) + .get(); + + Value userData = user.at("data").at(0).orNull(); + if (userData == null) { + throw new UsernameNotFoundException("User not found"); + } + + return User.withDefaultPasswordEncoder() + .username(userData.at("data", "username").to(String.class).orNull()) + .password(userData.at("data", "password").to(String.class).orNull()) + .roles("USER") + .build(); + } catch (ExecutionException | InterruptedException e) { + throw new RuntimeException(e); + } + } +} + diff --git a/persistence-modules/fauna/src/main/resources/application.properties b/persistence-modules/fauna/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 From 7a7fe1100280cc5c3311fe6dddf2b215d6059c64 Mon Sep 17 00:00:00 2001 From: Graham Cox Date: Fri, 4 Feb 2022 07:38:45 +0000 Subject: [PATCH 020/249] Added to the '*-jdk9-and-above' profiles --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index f2a230357c..c2979b9ed1 100644 --- a/pom.xml +++ b/pom.xml @@ -1345,6 +1345,7 @@ quarkus-jandex spring-boot-modules/spring-boot-cassandre testing-modules/testing-assertions + persistence-modules/fauna @@ -1402,6 +1403,7 @@ quarkus-jandex spring-boot-modules/spring-boot-cassandre testing-modules/testing-assertions + persistence-modules/fauna From eba9e9aed7e57ae0270fc6f7f3fe7745d8d25e6d Mon Sep 17 00:00:00 2001 From: asia Date: Tue, 8 Feb 2022 20:26:02 +0100 Subject: [PATCH 021/249] Remove unnecessary line breaks. --- .../baeldung/sprq/GraphqlControllerIntegrationTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/sprq/GraphqlControllerIntegrationTest.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/sprq/GraphqlControllerIntegrationTest.java index 65b6ff1e0b..b1054f09f8 100644 --- a/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/sprq/GraphqlControllerIntegrationTest.java +++ b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/sprq/GraphqlControllerIntegrationTest.java @@ -31,10 +31,11 @@ public class GraphqlControllerIntegrationTest { @Test public void givenNoBooks_whenReadAll_thenStatusIsOk() throws Exception { - String getAllBooksQuery = "{\n" + " getAllBooks {\n" + " id\n" + " author\n" + " title\n" + " }\n" + "}\n"; + String getAllBooksQuery = "{ getAllBooks {id author title } }"; this.mockMvc.perform(post(GRAPHQL_PATH).content(toJSON(getAllBooksQuery)) - .contentType(MediaType.APPLICATION_JSON)) + .contentType( + MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.getAllBooks").isEmpty()); } @@ -42,7 +43,8 @@ public class GraphqlControllerIntegrationTest { @Test public void whenAddBook_thenStatusIsOk() throws Exception { - String addBookMutation = "mutation {\n" + " addBook(newBook: {id: 123, author: \"J.R.R. Tolkien\", title: \"The Lord of the Rings\"}) {\n" + " id\n" + " author\n" + " title\n" + " }\n" + "}\n"; + String addBookMutation = "mutation { addBook(newBook: {id: 123, author: \"J.R.R. Tolkien\", " + + "title: \"The Lord of the Rings\"}) { id author title } }"; this.mockMvc.perform(post(GRAPHQL_PATH).content(toJSON(addBookMutation)) .contentType(MediaType.APPLICATION_JSON)) From 3c701c53885d101efb3ecdf4e191ed95c8eabd1a Mon Sep 17 00:00:00 2001 From: Graham Cox Date: Thu, 10 Feb 2022 07:32:33 +0000 Subject: [PATCH 022/249] Replaced tabs with spaces in auto-generated files --- persistence-modules/fauna/pom.xml | 88 +++++++++---------- .../faunablog/FaunaBlogApplication.java | 6 +- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/persistence-modules/fauna/pom.xml b/persistence-modules/fauna/pom.xml index 72c0f0a751..67aabb7501 100644 --- a/persistence-modules/fauna/pom.xml +++ b/persistence-modules/fauna/pom.xml @@ -1,30 +1,30 @@ - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.6.2 - - - com.baeldung - fauna-blog - 0.0.1-SNAPSHOT - fauna-blog - Blogging Service built with FaunaDB - - 17 - - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.boot - spring-boot-starter-web - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.6.2 + + + com.baeldung + fauna-blog + 0.0.1-SNAPSHOT + fauna-blog + Blogging Service built with FaunaDB + + 17 + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-web + com.faunadb faunadb-java @@ -32,25 +32,25 @@ compile - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.security - spring-security-test - test - - + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/FaunaBlogApplication.java b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/FaunaBlogApplication.java index f0ca6881b7..12739342bf 100644 --- a/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/FaunaBlogApplication.java +++ b/persistence-modules/fauna/src/main/java/com/baeldung/faunablog/FaunaBlogApplication.java @@ -6,8 +6,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class FaunaBlogApplication { - public static void main(String[] args) { - SpringApplication.run(FaunaBlogApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(FaunaBlogApplication.class, args); + } } From a4639b70e8ea30ff1b85e0c91175d668737050db Mon Sep 17 00:00:00 2001 From: achraftt Date: Sun, 13 Feb 2022 12:17:53 +0100 Subject: [PATCH 023/249] BAEL-5039: Add a new section on using a datepicker to submit date values --- .../thymeleaf/controller/DatesController.java | 15 +++++++ .../com/baeldung/thymeleaf/model/Student.java | 14 +++++++ .../WEB-INF/views/datePicker/displayDate.html | 12 ++++++ .../WEB-INF/views/datePicker/saveStudent.html | 42 +++++++++++++++++++ 4 files changed, 83 insertions(+) create mode 100644 spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/displayDate.html create mode 100644 spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/saveStudent.html diff --git a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/DatesController.java b/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/DatesController.java index 20f5d02fed..61443a3631 100644 --- a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/DatesController.java +++ b/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/DatesController.java @@ -5,8 +5,10 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Date; +import com.baeldung.thymeleaf.model.Student; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -22,4 +24,17 @@ public class DatesController { return "dates.html"; } + @RequestMapping(value = "/saveStudent", method = RequestMethod.GET) + public String displaySaveStudent(Model model) { + model.addAttribute("student", new Student()); + return "datePicker/saveStudent.html"; + } + + @RequestMapping(value = "/saveStudent", method = RequestMethod.POST) + public String saveStudent(Model model, @ModelAttribute("student") Student student) { + model.addAttribute("student", student); + + return "datePicker/displayDate.html"; + } + } diff --git a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Student.java b/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Student.java index 202c04358a..c08985fd61 100644 --- a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Student.java +++ b/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Student.java @@ -1,6 +1,9 @@ package com.baeldung.thymeleaf.model; +import org.springframework.format.annotation.DateTimeFormat; + import java.io.Serializable; +import java.util.Date; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; @@ -24,6 +27,9 @@ public class Student implements Serializable { @NotNull(message = "Student gender is required.") private Character gender; + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date birthDate; + private Float percentage; public Integer getId() { @@ -50,6 +56,14 @@ public class Student implements Serializable { this.gender = gender; } + public Date getBirthDate() { + return birthDate; + } + + public void setBirthDate(Date birthDate) { + this.birthDate = birthDate; + } + public Float getPercentage() { return percentage; } diff --git a/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/displayDate.html b/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/displayDate.html new file mode 100644 index 0000000000..d3409f98f3 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/displayDate.html @@ -0,0 +1,12 @@ + + + + +Baeldung - using a datepicker to submit date + + +

Student birth date

+

+ + \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/saveStudent.html b/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/saveStudent.html new file mode 100644 index 0000000000..2faaed173c --- /dev/null +++ b/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/saveStudent.html @@ -0,0 +1,42 @@ + + + + +Baeldung - using a datepicker to submit date + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ +
+
+
+ + \ No newline at end of file From a6df0b9ff9accfab245a1b0fd14d23d91c70a57a Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Sun, 13 Feb 2022 19:04:52 +0530 Subject: [PATCH 024/249] Changes to fetch the Original Message --- .../fileupload/config/ExceptionMessage.java | 55 +++++++++++++++++++ .../fileupload/config/FeignSupportConfig.java | 6 ++ .../config/RetreiveMessageErrorDecoder.java | 35 ++++++++++++ .../fileupload/controller/FileController.java | 5 ++ .../fileupload/service/UploadClient.java | 3 + .../fileupload/service/UploadService.java | 4 ++ 6 files changed, 108 insertions(+) create mode 100644 spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/ExceptionMessage.java create mode 100644 spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/RetreiveMessageErrorDecoder.java diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/ExceptionMessage.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/ExceptionMessage.java new file mode 100644 index 0000000000..45a555b2ea --- /dev/null +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/ExceptionMessage.java @@ -0,0 +1,55 @@ +package com.baeldung.cloud.openfeign.fileupload.config; + +public class ExceptionMessage { + private String timestamp; + private int status; + private String error; + private String message; + private String path; + + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + @Override + public String toString() { + return "ExceptionMessage [timestamp=" + timestamp + ", status=" + status + ", error=" + error + ", message=" + message + ", path=" + path + "]"; + } + +} diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java index 943134213a..802077a3d7 100644 --- a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java @@ -7,6 +7,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; import feign.codec.Encoder; +import feign.codec.ErrorDecoder; import feign.form.spring.SpringFormEncoder; public class FeignSupportConfig { @@ -19,4 +20,9 @@ public class FeignSupportConfig { } })); } + + @Bean + public ErrorDecoder errorDecoder() { + return new RetreiveMessageErrorDecoder(); + } } diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/RetreiveMessageErrorDecoder.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/RetreiveMessageErrorDecoder.java new file mode 100644 index 0000000000..09bf8bf54b --- /dev/null +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/RetreiveMessageErrorDecoder.java @@ -0,0 +1,35 @@ +package com.baeldung.cloud.openfeign.fileupload.config; + +import java.io.IOException; +import java.io.InputStream; + +import com.baeldung.cloud.openfeign.exception.BadRequestException; +import com.baeldung.cloud.openfeign.exception.NotFoundException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import feign.Response; +import feign.codec.ErrorDecoder; + +public class RetreiveMessageErrorDecoder implements ErrorDecoder { + private final ErrorDecoder errorDecoder = new Default(); + + @Override + public Exception decode(String methodKey, Response response) { + ExceptionMessage message = null; + try (InputStream bodyIs = response.body() + .asInputStream()) { + ObjectMapper mapper = new ObjectMapper(); + message = mapper.readValue(bodyIs, ExceptionMessage.class); + } catch (IOException e) { + return new Exception(e.getMessage()); + } + switch (response.status()) { + case 400: + return new BadRequestException(message.getMessage() != null ? message.getMessage() : "Bad Request"); + case 404: + return new NotFoundException(message.getMessage() != null ? message.getMessage() : "Not found"); + default: + return errorDecoder.decode(methodKey, response); + } + } +} diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java index ebdf7ff6c8..1ddbfcea81 100644 --- a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java @@ -25,4 +25,9 @@ public class FileController { return service.uploadFileWithManualClient(file); } + @PostMapping(value = "/upload-error") + public String handleFileUploadError(@RequestPart(value = "file") MultipartFile file) { + return service.uploadFile(file); + } + } \ No newline at end of file diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java index 63d17130e9..8f3ef7e421 100644 --- a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java @@ -12,4 +12,7 @@ import com.baeldung.cloud.openfeign.fileupload.config.FeignSupportConfig; public interface UploadClient { @PostMapping(value = "/upload-file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) String fileUpload(@RequestPart(value = "file") MultipartFile file); + + @PostMapping(value = "/upload-file-error", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + String fileUploadError(@RequestPart(value = "file") MultipartFile file); } diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadService.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadService.java index 7dd7f5a89c..742a37668b 100644 --- a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadService.java +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadService.java @@ -26,4 +26,8 @@ public class UploadService { return client.fileUpload(file); } + public String uploadFileError(MultipartFile file) { + return client.fileUpload(file); + } + } \ No newline at end of file From 185266113c7d623faa8bee79aeb8de4578719cc1 Mon Sep 17 00:00:00 2001 From: msavic Date: Sun, 13 Feb 2022 23:56:05 +0100 Subject: [PATCH 025/249] Caching Maven Dependencies with Docker --- docker/docker-caching/multi-module/Dockerfile | 21 ++++++++ .../multi-module/Dockerfile-Buildkit | 13 +++++ .../multi-module/application/pom.xml | 36 +++++++++++++ .../MavenCachingApplication.java | 15 ++++++ .../src/main/resources/application.properties | 1 + .../MavenCachingApplicationTests.java | 13 +++++ .../docker-caching/multi-module/core/pom.xml | 19 +++++++ .../com/baeldung/maven_caching/CoreClass.java | 8 +++ docker/docker-caching/multi-module/pom.xml | 38 +++++++++++++ .../docker-caching/single-module/Dockerfile | 15 ++++++ .../single-module/Dockerfile-Buildkit | 13 +++++ docker/docker-caching/single-module/pom.xml | 53 +++++++++++++++++++ .../maven_caching/MavenCachingMain.java | 11 ++++ 13 files changed, 256 insertions(+) create mode 100644 docker/docker-caching/multi-module/Dockerfile create mode 100644 docker/docker-caching/multi-module/Dockerfile-Buildkit create mode 100644 docker/docker-caching/multi-module/application/pom.xml create mode 100644 docker/docker-caching/multi-module/application/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java create mode 100644 docker/docker-caching/multi-module/application/src/main/resources/application.properties create mode 100644 docker/docker-caching/multi-module/application/src/test/java/com/baeldung/maven_caching/MavenCachingApplicationTests.java create mode 100644 docker/docker-caching/multi-module/core/pom.xml create mode 100644 docker/docker-caching/multi-module/core/src/main/java/com/baeldung/maven_caching/CoreClass.java create mode 100644 docker/docker-caching/multi-module/pom.xml create mode 100644 docker/docker-caching/single-module/Dockerfile create mode 100644 docker/docker-caching/single-module/Dockerfile-Buildkit create mode 100644 docker/docker-caching/single-module/pom.xml create mode 100644 docker/docker-caching/single-module/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java diff --git a/docker/docker-caching/multi-module/Dockerfile b/docker/docker-caching/multi-module/Dockerfile new file mode 100644 index 0000000000..1f0cc85f7c --- /dev/null +++ b/docker/docker-caching/multi-module/Dockerfile @@ -0,0 +1,21 @@ +FROM maven:alpine as build +ENV HOME=/usr/app +RUN mkdir -p $HOME +WORKDIR $HOME + +ADD pom.xml $HOME +ADD core/pom.xml $HOME/core/pom.xml +ADD application/pom.xml $HOME/application/pom.xml + +RUN mvn -pl core verify --fail-never +ADD core $HOME/core +RUN mvn -pl core install +RUN mvn -pl application verify --fail-never +ADD application $HOME/application +RUN mvn -pl core,application package + +FROM openjdk:8-jdk-alpine + +COPY --from=build /usr/app/application/target/application-0.0.1-SNAPSHOT.jar /app/runner.jar + +ENTRYPOINT java -jar /app/runner.jar \ No newline at end of file diff --git a/docker/docker-caching/multi-module/Dockerfile-Buildkit b/docker/docker-caching/multi-module/Dockerfile-Buildkit new file mode 100644 index 0000000000..f51657c9ce --- /dev/null +++ b/docker/docker-caching/multi-module/Dockerfile-Buildkit @@ -0,0 +1,13 @@ +FROM maven:alpine as build +ENV HOME=/usr/app +RUN mkdir -p $HOME +WORKDIR $HOME + +ADD . $HOME +RUN --mount=type=cache,target=/root/.m2 mvn -f $HOME/pom.xml clean package + +FROM openjdk:8-jdk-alpine + +COPY --from=build /usr/app/application/target/application-0.0.1-SNAPSHOT.jar /app/runner.jar + +ENTRYPOINT java -jar /app/runner.jar \ No newline at end of file diff --git a/docker/docker-caching/multi-module/application/pom.xml b/docker/docker-caching/multi-module/application/pom.xml new file mode 100644 index 0000000000..49611e7fbd --- /dev/null +++ b/docker/docker-caching/multi-module/application/pom.xml @@ -0,0 +1,36 @@ + + + + maven-caching + com.baeldung + 0.0.1-SNAPSHOT + + 4.0.0 + + application + + + com.baeldung + core + 0.0.1-SNAPSHOT + + + + + 8 + 8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + \ No newline at end of file diff --git a/docker/docker-caching/multi-module/application/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java b/docker/docker-caching/multi-module/application/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java new file mode 100644 index 0000000000..dec5453dc9 --- /dev/null +++ b/docker/docker-caching/multi-module/application/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.maven_caching; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MavenCachingApplication { + + public static void main(String[] args) { + SpringApplication.run(MavenCachingApplication.class, args); + CoreClass cc = new CoreClass(); + System.out.println(cc.method()); + } + +} diff --git a/docker/docker-caching/multi-module/application/src/main/resources/application.properties b/docker/docker-caching/multi-module/application/src/main/resources/application.properties new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/docker/docker-caching/multi-module/application/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/docker/docker-caching/multi-module/application/src/test/java/com/baeldung/maven_caching/MavenCachingApplicationTests.java b/docker/docker-caching/multi-module/application/src/test/java/com/baeldung/maven_caching/MavenCachingApplicationTests.java new file mode 100644 index 0000000000..ec550fb990 --- /dev/null +++ b/docker/docker-caching/multi-module/application/src/test/java/com/baeldung/maven_caching/MavenCachingApplicationTests.java @@ -0,0 +1,13 @@ +package com.baeldung.maven_caching; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class MavenCachingApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/docker/docker-caching/multi-module/core/pom.xml b/docker/docker-caching/multi-module/core/pom.xml new file mode 100644 index 0000000000..5df8ea7dde --- /dev/null +++ b/docker/docker-caching/multi-module/core/pom.xml @@ -0,0 +1,19 @@ + + + + maven-caching + com.baeldung + 0.0.1-SNAPSHOT + + 4.0.0 + + core + + + 8 + 8 + + + \ No newline at end of file diff --git a/docker/docker-caching/multi-module/core/src/main/java/com/baeldung/maven_caching/CoreClass.java b/docker/docker-caching/multi-module/core/src/main/java/com/baeldung/maven_caching/CoreClass.java new file mode 100644 index 0000000000..a33624d4e7 --- /dev/null +++ b/docker/docker-caching/multi-module/core/src/main/java/com/baeldung/maven_caching/CoreClass.java @@ -0,0 +1,8 @@ +package com.baeldung.maven_caching; + +public class CoreClass { + + public String method(){ + return "Hello from core module!!"; + } +} diff --git a/docker/docker-caching/multi-module/pom.xml b/docker/docker-caching/multi-module/pom.xml new file mode 100644 index 0000000000..0cc309e2ad --- /dev/null +++ b/docker/docker-caching/multi-module/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + pom + + application + core + + + org.springframework.boot + spring-boot-starter-parent + 2.6.3 + + + com.baeldung + maven-caching + 0.0.1-SNAPSHOT + maven-caching + maven-caching + + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/docker/docker-caching/single-module/Dockerfile b/docker/docker-caching/single-module/Dockerfile new file mode 100644 index 0000000000..309945440b --- /dev/null +++ b/docker/docker-caching/single-module/Dockerfile @@ -0,0 +1,15 @@ +FROM maven:alpine as build +ENV HOME=/usr/app +RUN mkdir -p $HOME +WORKDIR $HOME +ADD pom.xml $HOME +RUN mvn verify --fail-never + +ADD . $HOME +RUN mvn package + +FROM openjdk:8-jdk-alpine + +COPY --from=build /usr/app/target/maven-caching-1.0-SNAPSHOT-jar-with-dependencies.jar /app/runner.jar + +ENTRYPOINT java -jar /app/runner.jar \ No newline at end of file diff --git a/docker/docker-caching/single-module/Dockerfile-Buildkit b/docker/docker-caching/single-module/Dockerfile-Buildkit new file mode 100644 index 0000000000..d3d2aad90d --- /dev/null +++ b/docker/docker-caching/single-module/Dockerfile-Buildkit @@ -0,0 +1,13 @@ +FROM maven:alpine as build +ENV HOME=/usr/app +RUN mkdir -p $HOME +WORKDIR $HOME +ADD . $HOME + +RUN --mount=type=cache,target=/root/.m2 mvn -f $HOME/pom.xml clean package + +FROM openjdk:8-jdk-alpine + +COPY --from=build /usr/app/target/maven-caching-1.0-SNAPSHOT-jar-with-dependencies.jar /app/runner.jar + +ENTRYPOINT java -jar /app/runner.jar \ No newline at end of file diff --git a/docker/docker-caching/single-module/pom.xml b/docker/docker-caching/single-module/pom.xml new file mode 100644 index 0000000000..54337436c5 --- /dev/null +++ b/docker/docker-caching/single-module/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + + com.baeldung + single-maven-caching + 1.0-SNAPSHOT + + + 8 + 8 + + + + + com.google.guava + guava + 31.0.1-jre + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + + jar-with-dependencies + + + + true + com.baeldung.maven_caching.MavenCachingMain + + + + + + assemble-all + package + + single + + + + + + + \ No newline at end of file diff --git a/docker/docker-caching/single-module/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java b/docker/docker-caching/single-module/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java new file mode 100644 index 0000000000..81673fd9ac --- /dev/null +++ b/docker/docker-caching/single-module/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java @@ -0,0 +1,11 @@ +package com.baeldung.maven_caching; + +import com.google.common.io.Files; + +public class MavenCachingMain { + + public static void main(String[] args) { + System.out.println("Hello from maven_caching app!!!"); + System.out.println(Files.simplifyPath("/home/app/test")); + } +} From 895044bfa3ea6b2032ce0ef6e48637ddc6b5232b Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Mon, 14 Feb 2022 23:57:46 -0300 Subject: [PATCH 026/249] BAEL-2080 - Check if a user is logged-in with Servlets and JSP * new module: javax-servlets-2 --- javax-servlets-2/README.md | 5 + javax-servlets-2/pom.xml | 60 ++++++++++++ .../java/com/baeldung/user/check/User.java | 80 +++++++++++++++ .../baeldung/user/check/UserCheckFilter.java | 46 +++++++++ .../user/check/UserCheckLoginServlet.java | 56 +++++++++++ .../user/check/UserCheckLogoutServlet.java | 26 +++++ .../baeldung/user/check/UserCheckServlet.java | 28 ++++++ .../src/main/resources/logback.xml | 13 +++ .../main/webapp/WEB-INF/user.check/home.jsp | 31 ++++++ .../main/webapp/WEB-INF/user.check/login.jsp | 33 +++++++ .../user/check/UserCheckServletLiveTest.java | 98 +++++++++++++++++++ 11 files changed, 476 insertions(+) create mode 100644 javax-servlets-2/README.md create mode 100644 javax-servlets-2/pom.xml create mode 100644 javax-servlets-2/src/main/java/com/baeldung/user/check/User.java create mode 100644 javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java create mode 100644 javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLoginServlet.java create mode 100644 javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLogoutServlet.java create mode 100644 javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckServlet.java create mode 100644 javax-servlets-2/src/main/resources/logback.xml create mode 100644 javax-servlets-2/src/main/webapp/WEB-INF/user.check/home.jsp create mode 100644 javax-servlets-2/src/main/webapp/WEB-INF/user.check/login.jsp create mode 100644 javax-servlets-2/src/test/java/com/baeldung/user/check/UserCheckServletLiveTest.java diff --git a/javax-servlets-2/README.md b/javax-servlets-2/README.md new file mode 100644 index 0000000000..f126f17297 --- /dev/null +++ b/javax-servlets-2/README.md @@ -0,0 +1,5 @@ +## Servlets + +This module contains articles about Servlets. + +### Relevant Articles: diff --git a/javax-servlets-2/pom.xml b/javax-servlets-2/pom.xml new file mode 100644 index 0000000000..34c00c3d05 --- /dev/null +++ b/javax-servlets-2/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + com.baeldung.javax-servlets + javax-servlets-2 + 1.0-SNAPSHOT + javax-servlets-2 + war + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + commons-fileupload + commons-fileupload + ${commons-fileupload.version} + + + + javax.servlet + javax.servlet-api + ${javax.servlet-api.version} + + + javax.servlet.jsp + javax.servlet.jsp-api + ${javax.servlet.jsp-api.version} + provided + + + javax.servlet + jstl + ${jstl.version} + + + org.apache.httpcomponents + httpclient + ${org.apache.httpcomponents.version} + test + + + commons-logging + commons-logging + + + + + + + 4.5.13 + 4.0.1 + + diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/User.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/User.java new file mode 100644 index 0000000000..f61c0490bc --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/User.java @@ -0,0 +1,80 @@ +package com.baeldung.user.check; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; + +/** + * @since 6 de fev de 2022 + * @author ulisses + */ +public class User implements Serializable { + private static final long serialVersionUID = 1L; + + protected static final HashMap DB = new HashMap<>(); + static { + DB.put("admin", new User("admin", "password")); + DB.put("user", new User("user", "pass")); + } + + private String name; + private String password; + + private List logins = new ArrayList(); + + public User(String name, String password) { + this.name = name; + this.password = password; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getLogins() { + return logins; + } + + public void setLogins(List logins) { + this.logins = logins; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + User other = (User) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } +} diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java new file mode 100644 index 0000000000..2a370afe85 --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java @@ -0,0 +1,46 @@ +package com.baeldung.user.check; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebFilter("/user-check/*") +public class UserCheckFilter implements Filter { + public static void forward(HttpServletRequest request, HttpServletResponse response, String page) throws ServletException, IOException { + request.getRequestDispatcher("/WEB-INF/user.check" + page) + .forward(request, response); + } + + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { + if (!(req instanceof HttpServletRequest)) { + throw new ServletException("Can only process HttpServletRequest"); + } + + if (!(res instanceof HttpServletResponse)) { + throw new ServletException("Can only process HttpServletResponse"); + } + + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + + request.setAttribute("origin", request.getRequestURI()); + + if (!request.getRequestURI() + .contains("login") && request.getSession(false) == null) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + forward(request, response, "/login.jsp"); + // we return here so the original servlet is not processed + return; + } + + chain.doFilter(request, response); + } +} diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLoginServlet.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLoginServlet.java new file mode 100644 index 0000000000..e1a38fc7b8 --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLoginServlet.java @@ -0,0 +1,56 @@ +package com.baeldung.user.check; + +import java.io.IOException; +import java.util.Date; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +@WebServlet("/user-check/login") +public class UserCheckLoginServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + if (request.getSession(false) != null) { + response.sendRedirect(request.getContextPath() + "/user-check/home"); + return; + } + + String referer = (String) request.getAttribute("origin"); + request.setAttribute("origin", referer); + UserCheckFilter.forward(request, response, "/login.jsp"); + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + String key = request.getParameter("name"); + String pass = request.getParameter("password"); + + User user = User.DB.get(key); + if (user == null || !user.getPassword() + .equals(pass)) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + request.setAttribute("origin", request.getParameter("origin")); + request.setAttribute("error", "invalid login"); + UserCheckFilter.forward(request, response, "/login.jsp"); + return; + } + + user.getLogins() + .add(new Date()); + + HttpSession session = request.getSession(); + session.setAttribute("user", user); + + String origin = request.getParameter("origin"); + if (origin == null || origin.contains("login")) + origin = "./"; + + response.sendRedirect(origin); + } +} diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLogoutServlet.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLogoutServlet.java new file mode 100644 index 0000000000..42c0bb87ab --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLogoutServlet.java @@ -0,0 +1,26 @@ +package com.baeldung.user.check; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +@WebServlet("/user-check/logout") +public class UserCheckLogoutServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + HttpSession session = request.getSession(false); + if (session != null) { + session.invalidate(); + } + + request.setAttribute("loggedOut", true); + response.sendRedirect("./"); + } +} diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckServlet.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckServlet.java new file mode 100644 index 0000000000..d7d5d1e762 --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckServlet.java @@ -0,0 +1,28 @@ +package com.baeldung.user.check; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +@WebServlet(name = "home", urlPatterns = { "/user-check/", "/user-check", "/user-check/home" }) +public class UserCheckServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + HttpSession session = request.getSession(false); + if (session == null || session.getAttribute("user") == null) { + throw new IllegalStateException("user not logged in"); + } + + User user = (User) session.getAttribute("user"); + request.setAttribute("user", user); + + UserCheckFilter.forward(request, response, "/home.jsp"); + } +} diff --git a/javax-servlets-2/src/main/resources/logback.xml b/javax-servlets-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/javax-servlets-2/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/javax-servlets-2/src/main/webapp/WEB-INF/user.check/home.jsp b/javax-servlets-2/src/main/webapp/WEB-INF/user.check/home.jsp new file mode 100644 index 0000000000..4e17763552 --- /dev/null +++ b/javax-servlets-2/src/main/webapp/WEB-INF/user.check/home.jsp @@ -0,0 +1,31 @@ +<%@ page contentType="text/html;charset=UTF-8" session="false"%> +<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%> + + + + login success - current session info + + +
+

user info

+
+ name: ${user.name} +
+ +
+ logins: +
    + +
  • ${login}
  • +
    +
+
+ + +
+ + diff --git a/javax-servlets-2/src/main/webapp/WEB-INF/user.check/login.jsp b/javax-servlets-2/src/main/webapp/WEB-INF/user.check/login.jsp new file mode 100644 index 0000000000..19a857585d --- /dev/null +++ b/javax-servlets-2/src/main/webapp/WEB-INF/user.check/login.jsp @@ -0,0 +1,33 @@ +<%@ page contentType="text/html;charset=UTF-8" session="false"%> +<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%> + + + + login + + +
+ + +
* redirected to login from: ${origin}
+
+ + +
* error: ${error}
+
+ +
+ credentials + + + + + + + + +
+
+ + diff --git a/javax-servlets-2/src/test/java/com/baeldung/user/check/UserCheckServletLiveTest.java b/javax-servlets-2/src/test/java/com/baeldung/user/check/UserCheckServletLiveTest.java new file mode 100644 index 0000000000..42858d61e7 --- /dev/null +++ b/javax-servlets-2/src/test/java/com/baeldung/user/check/UserCheckServletLiveTest.java @@ -0,0 +1,98 @@ +package com.baeldung.user.check; + +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.LaxRedirectStrategy; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class UserCheckServletLiveTest { + private static final String BASE_URL = "http://localhost:8080/javax-servlets-2/user-check"; + + @Mock + HttpServletRequest request; + + @Mock + HttpServletResponse response; + + private CloseableHttpClient buildClient() { + return HttpClientBuilder.create() + .setRedirectStrategy(new LaxRedirectStrategy()) + .build(); + } + + @Test + public void whenCorrectCredentials_thenLoginSucceeds() throws Exception { + try (CloseableHttpClient client = buildClient()) { + HttpPost post = new HttpPost(BASE_URL + "/login"); + + List form = new ArrayList<>(); + form.add(new BasicNameValuePair("name", "admin")); + form.add(new BasicNameValuePair("password", "password")); + + post.setEntity(new UrlEncodedFormEntity(form)); + try (CloseableHttpResponse response = client.execute(post)) { + String body = EntityUtils.toString(response.getEntity()); + + assertTrue(response.getStatusLine() + .getStatusCode() == 200); + + assertTrue(body.contains("login success")); + } + } + } + + @Test + public void whenIncorrectCredentials_thenLoginFails() throws Exception { + try (CloseableHttpClient client = buildClient()) { + HttpPost post = new HttpPost(BASE_URL + "/login"); + + List form = new ArrayList<>(); + form.add(new BasicNameValuePair("name", "admin")); + form.add(new BasicNameValuePair("password", "invalid")); + + post.setEntity(new UrlEncodedFormEntity(form)); + try (CloseableHttpResponse response = client.execute(post)) { + String body = EntityUtils.toString(response.getEntity()); + + assertTrue(response.getStatusLine() + .getStatusCode() == 401); + + assertTrue(body.contains("invalid login")); + } + } + } + + @Test + public void whenNotLoggedIn_thenRedirectedToLoginPage() throws Exception { + try (CloseableHttpClient client = buildClient()) { + HttpGet get = new HttpGet(BASE_URL + "/home"); + + try (CloseableHttpResponse response = client.execute(get)) { + String body = EntityUtils.toString(response.getEntity()); + + assertTrue(response.getStatusLine() + .getStatusCode() == 401); + + assertTrue(body.contains("redirected to login")); + } + } + } +} From adca84eca2fb787d80589188088ae31ff537ea77 Mon Sep 17 00:00:00 2001 From: achraftt Date: Wed, 16 Feb 2022 14:22:45 +0100 Subject: [PATCH 027/249] BAEL-5039: edit identation --- .../WEB-INF/views/datePicker/displayDate.html | 10 +-- .../WEB-INF/views/datePicker/saveStudent.html | 66 +++++++++---------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/displayDate.html b/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/displayDate.html index d3409f98f3..7ae84e026f 100644 --- a/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/displayDate.html +++ b/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/displayDate.html @@ -1,12 +1,12 @@ + xmlns:th="http://www.thymeleaf.org"> - -Baeldung - using a datepicker to submit date + + Baeldung - using a datepicker to submit date -

Student birth date

-

+

Student birth date

+

\ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/saveStudent.html b/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/saveStudent.html index 2faaed173c..d897369326 100644 --- a/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/saveStudent.html +++ b/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/datePicker/saveStudent.html @@ -1,42 +1,42 @@ + xmlns:th="http://www.thymeleaf.org"> - -Baeldung - using a datepicker to submit date + + Baeldung - using a datepicker to submit date
-
-
- - -
-
-
- - -
-
-
- - -
-
-
- - -
-
-
- - -
-
-
- -
-
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ +
+
\ No newline at end of file From a0219c9f5c5737374cd26a6b12defdc3f26a97aa Mon Sep 17 00:00:00 2001 From: Mladen Savic Date: Sun, 20 Feb 2022 22:51:08 +0100 Subject: [PATCH 028/249] Caching Maven Dependencies with Docker - improvements --- .../multi-module-caching/Dockerfile | 21 +++++++ .../Dockerfile-Buildkit | 2 +- .../core/pom.xml | 8 ++- .../com/baeldung/maven_caching/CoreClass.java | 6 ++ .../multi-module-caching/pom.xml | 29 ++++++++++ .../multi-module-caching/runner/pom.xml | 55 +++++++++++++++++++ .../MavenCachingApplication.java | 6 +- docker/docker-caching/multi-module/Dockerfile | 21 ------- .../multi-module/application/pom.xml | 36 ------------ .../src/main/resources/application.properties | 1 - .../MavenCachingApplicationTests.java | 13 ----- docker/docker-caching/multi-module/pom.xml | 38 ------------- .../Dockerfile | 2 +- .../Dockerfile-Buildkit | 2 +- .../pom.xml | 2 +- .../maven_caching/MavenCachingMain.java | 0 16 files changed, 123 insertions(+), 119 deletions(-) create mode 100644 docker/docker-caching/multi-module-caching/Dockerfile rename docker/docker-caching/{multi-module => multi-module-caching}/Dockerfile-Buildkit (58%) rename docker/docker-caching/{multi-module => multi-module-caching}/core/pom.xml (71%) rename docker/docker-caching/{multi-module => multi-module-caching}/core/src/main/java/com/baeldung/maven_caching/CoreClass.java (51%) create mode 100644 docker/docker-caching/multi-module-caching/pom.xml create mode 100644 docker/docker-caching/multi-module-caching/runner/pom.xml rename docker/docker-caching/{multi-module/application => multi-module-caching/runner}/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java (50%) delete mode 100644 docker/docker-caching/multi-module/Dockerfile delete mode 100644 docker/docker-caching/multi-module/application/pom.xml delete mode 100644 docker/docker-caching/multi-module/application/src/main/resources/application.properties delete mode 100644 docker/docker-caching/multi-module/application/src/test/java/com/baeldung/maven_caching/MavenCachingApplicationTests.java delete mode 100644 docker/docker-caching/multi-module/pom.xml rename docker/docker-caching/{single-module => single-module-caching}/Dockerfile (55%) rename docker/docker-caching/{single-module => single-module-caching}/Dockerfile-Buildkit (57%) rename docker/docker-caching/{single-module => single-module-caching}/pom.xml (96%) rename docker/docker-caching/{single-module => single-module-caching}/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java (100%) diff --git a/docker/docker-caching/multi-module-caching/Dockerfile b/docker/docker-caching/multi-module-caching/Dockerfile new file mode 100644 index 0000000000..96ebe2a76b --- /dev/null +++ b/docker/docker-caching/multi-module-caching/Dockerfile @@ -0,0 +1,21 @@ +FROM maven:alpine as build +ENV HOME=/usr/app +RUN mkdir -p $HOME +WORKDIR $HOME + +ADD pom.xml $HOME +ADD core/pom.xml $HOME/core/pom.xml +ADD runner/pom.xml $HOME/runner/pom.xml + +RUN mvn -pl core verify --fail-never +ADD core $HOME/core +RUN mvn -pl core install +RUN mvn -pl runner verify --fail-never +ADD runner $HOME/runner +RUN mvn -pl core,runner package + +FROM openjdk:8-jdk-alpine + +COPY --from=build /usr/app/runner/target/runner-0.0.1-SNAPSHOT-jar-with-dependencies.jar /app/runner.jar + +ENTRYPOINT java -jar /app/runner.jar \ No newline at end of file diff --git a/docker/docker-caching/multi-module/Dockerfile-Buildkit b/docker/docker-caching/multi-module-caching/Dockerfile-Buildkit similarity index 58% rename from docker/docker-caching/multi-module/Dockerfile-Buildkit rename to docker/docker-caching/multi-module-caching/Dockerfile-Buildkit index f51657c9ce..e89ce38e4b 100644 --- a/docker/docker-caching/multi-module/Dockerfile-Buildkit +++ b/docker/docker-caching/multi-module-caching/Dockerfile-Buildkit @@ -8,6 +8,6 @@ RUN --mount=type=cache,target=/root/.m2 mvn -f $HOME/pom.xml clean package FROM openjdk:8-jdk-alpine -COPY --from=build /usr/app/application/target/application-0.0.1-SNAPSHOT.jar /app/runner.jar +COPY --from=build /usr/app/runner/target/runner-0.0.1-SNAPSHOT-jar-with-dependencies.jar /app/runner.jar ENTRYPOINT java -jar /app/runner.jar \ No newline at end of file diff --git a/docker/docker-caching/multi-module/core/pom.xml b/docker/docker-caching/multi-module-caching/core/pom.xml similarity index 71% rename from docker/docker-caching/multi-module/core/pom.xml rename to docker/docker-caching/multi-module-caching/core/pom.xml index 5df8ea7dde..0b79a64143 100644 --- a/docker/docker-caching/multi-module/core/pom.xml +++ b/docker/docker-caching/multi-module-caching/core/pom.xml @@ -3,7 +3,7 @@ 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"> - maven-caching + multi-module-caching com.baeldung 0.0.1-SNAPSHOT @@ -16,4 +16,10 @@ 8 + + + com.google.guava + guava + + \ No newline at end of file diff --git a/docker/docker-caching/multi-module/core/src/main/java/com/baeldung/maven_caching/CoreClass.java b/docker/docker-caching/multi-module-caching/core/src/main/java/com/baeldung/maven_caching/CoreClass.java similarity index 51% rename from docker/docker-caching/multi-module/core/src/main/java/com/baeldung/maven_caching/CoreClass.java rename to docker/docker-caching/multi-module-caching/core/src/main/java/com/baeldung/maven_caching/CoreClass.java index a33624d4e7..7d57110d72 100644 --- a/docker/docker-caching/multi-module/core/src/main/java/com/baeldung/maven_caching/CoreClass.java +++ b/docker/docker-caching/multi-module-caching/core/src/main/java/com/baeldung/maven_caching/CoreClass.java @@ -1,8 +1,14 @@ package com.baeldung.maven_caching; +import com.google.common.io.Files; + public class CoreClass { public String method(){ return "Hello from core module!!"; } + + public String dependencyMethod(){ + return Files.simplifyPath("/home/app/test"); + } } diff --git a/docker/docker-caching/multi-module-caching/pom.xml b/docker/docker-caching/multi-module-caching/pom.xml new file mode 100644 index 0000000000..42205a29de --- /dev/null +++ b/docker/docker-caching/multi-module-caching/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + pom + + runner + core + + com.baeldung + multi-module-caching + 0.0.1-SNAPSHOT + maven-caching + maven-caching + + 1.8 + + + + + + com.google.guava + guava + 31.0.1-jre + + + + + diff --git a/docker/docker-caching/multi-module-caching/runner/pom.xml b/docker/docker-caching/multi-module-caching/runner/pom.xml new file mode 100644 index 0000000000..d306baf05d --- /dev/null +++ b/docker/docker-caching/multi-module-caching/runner/pom.xml @@ -0,0 +1,55 @@ + + + + multi-module-caching + com.baeldung + 0.0.1-SNAPSHOT + + 4.0.0 + + runner + + + com.baeldung + core + 0.0.1-SNAPSHOT + + + + + 8 + 8 + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + + jar-with-dependencies + + + + true + com.baeldung.maven_caching.MavenCachingApplication + + + + + + assemble-all + package + + single + + + + + + + \ No newline at end of file diff --git a/docker/docker-caching/multi-module/application/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java b/docker/docker-caching/multi-module-caching/runner/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java similarity index 50% rename from docker/docker-caching/multi-module/application/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java rename to docker/docker-caching/multi-module-caching/runner/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java index dec5453dc9..3673dd86c1 100644 --- a/docker/docker-caching/multi-module/application/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java +++ b/docker/docker-caching/multi-module-caching/runner/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java @@ -1,15 +1,11 @@ package com.baeldung.maven_caching; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication public class MavenCachingApplication { public static void main(String[] args) { - SpringApplication.run(MavenCachingApplication.class, args); CoreClass cc = new CoreClass(); System.out.println(cc.method()); + System.out.println(cc.dependencyMethod()); } } diff --git a/docker/docker-caching/multi-module/Dockerfile b/docker/docker-caching/multi-module/Dockerfile deleted file mode 100644 index 1f0cc85f7c..0000000000 --- a/docker/docker-caching/multi-module/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -FROM maven:alpine as build -ENV HOME=/usr/app -RUN mkdir -p $HOME -WORKDIR $HOME - -ADD pom.xml $HOME -ADD core/pom.xml $HOME/core/pom.xml -ADD application/pom.xml $HOME/application/pom.xml - -RUN mvn -pl core verify --fail-never -ADD core $HOME/core -RUN mvn -pl core install -RUN mvn -pl application verify --fail-never -ADD application $HOME/application -RUN mvn -pl core,application package - -FROM openjdk:8-jdk-alpine - -COPY --from=build /usr/app/application/target/application-0.0.1-SNAPSHOT.jar /app/runner.jar - -ENTRYPOINT java -jar /app/runner.jar \ No newline at end of file diff --git a/docker/docker-caching/multi-module/application/pom.xml b/docker/docker-caching/multi-module/application/pom.xml deleted file mode 100644 index 49611e7fbd..0000000000 --- a/docker/docker-caching/multi-module/application/pom.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - maven-caching - com.baeldung - 0.0.1-SNAPSHOT - - 4.0.0 - - application - - - com.baeldung - core - 0.0.1-SNAPSHOT - - - - - 8 - 8 - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - \ No newline at end of file diff --git a/docker/docker-caching/multi-module/application/src/main/resources/application.properties b/docker/docker-caching/multi-module/application/src/main/resources/application.properties deleted file mode 100644 index 8b13789179..0000000000 --- a/docker/docker-caching/multi-module/application/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docker/docker-caching/multi-module/application/src/test/java/com/baeldung/maven_caching/MavenCachingApplicationTests.java b/docker/docker-caching/multi-module/application/src/test/java/com/baeldung/maven_caching/MavenCachingApplicationTests.java deleted file mode 100644 index ec550fb990..0000000000 --- a/docker/docker-caching/multi-module/application/src/test/java/com/baeldung/maven_caching/MavenCachingApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.baeldung.maven_caching; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class MavenCachingApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/docker/docker-caching/multi-module/pom.xml b/docker/docker-caching/multi-module/pom.xml deleted file mode 100644 index 0cc309e2ad..0000000000 --- a/docker/docker-caching/multi-module/pom.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - 4.0.0 - pom - - application - core - - - org.springframework.boot - spring-boot-starter-parent - 2.6.3 - - - com.baeldung - maven-caching - 0.0.1-SNAPSHOT - maven-caching - maven-caching - - 1.8 - - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-test - test - - - - diff --git a/docker/docker-caching/single-module/Dockerfile b/docker/docker-caching/single-module-caching/Dockerfile similarity index 55% rename from docker/docker-caching/single-module/Dockerfile rename to docker/docker-caching/single-module-caching/Dockerfile index 309945440b..02157c0dd6 100644 --- a/docker/docker-caching/single-module/Dockerfile +++ b/docker/docker-caching/single-module-caching/Dockerfile @@ -10,6 +10,6 @@ RUN mvn package FROM openjdk:8-jdk-alpine -COPY --from=build /usr/app/target/maven-caching-1.0-SNAPSHOT-jar-with-dependencies.jar /app/runner.jar +COPY --from=build /usr/app/target/single-module-caching-1.0-SNAPSHOT-jar-with-dependencies.jar /app/runner.jar ENTRYPOINT java -jar /app/runner.jar \ No newline at end of file diff --git a/docker/docker-caching/single-module/Dockerfile-Buildkit b/docker/docker-caching/single-module-caching/Dockerfile-Buildkit similarity index 57% rename from docker/docker-caching/single-module/Dockerfile-Buildkit rename to docker/docker-caching/single-module-caching/Dockerfile-Buildkit index d3d2aad90d..29384ce208 100644 --- a/docker/docker-caching/single-module/Dockerfile-Buildkit +++ b/docker/docker-caching/single-module-caching/Dockerfile-Buildkit @@ -8,6 +8,6 @@ RUN --mount=type=cache,target=/root/.m2 mvn -f $HOME/pom.xml clean package FROM openjdk:8-jdk-alpine -COPY --from=build /usr/app/target/maven-caching-1.0-SNAPSHOT-jar-with-dependencies.jar /app/runner.jar +COPY --from=build /usr/app/target/single-module-caching-1.0-SNAPSHOT-jar-with-dependencies.jar /app/runner.jar ENTRYPOINT java -jar /app/runner.jar \ No newline at end of file diff --git a/docker/docker-caching/single-module/pom.xml b/docker/docker-caching/single-module-caching/pom.xml similarity index 96% rename from docker/docker-caching/single-module/pom.xml rename to docker/docker-caching/single-module-caching/pom.xml index 54337436c5..b1abc55772 100644 --- a/docker/docker-caching/single-module/pom.xml +++ b/docker/docker-caching/single-module-caching/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.baeldung - single-maven-caching + single-module-caching 1.0-SNAPSHOT diff --git a/docker/docker-caching/single-module/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java b/docker/docker-caching/single-module-caching/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java similarity index 100% rename from docker/docker-caching/single-module/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java rename to docker/docker-caching/single-module-caching/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java From 64ffe101dca69244c5fb85e7dca2ce71365cdf4d Mon Sep 17 00:00:00 2001 From: Mladen Savic Date: Sun, 20 Feb 2022 22:51:08 +0100 Subject: [PATCH 029/249] Caching Maven Dependencies with Docker - improvements --- docker/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker/pom.xml b/docker/pom.xml index f481f1b8b7..5c6267c6dd 100644 --- a/docker/pom.xml +++ b/docker/pom.xml @@ -26,6 +26,8 @@ docker-internal-dto docker-spring-boot docker-sample-app + docker-caching/single-module-caching + docker-caching/multi-module-caching From 6ece2c8805059b4b477c152baab854f99c28f787 Mon Sep 17 00:00:00 2001 From: Mladen Savic Date: Sun, 20 Feb 2022 22:51:08 +0100 Subject: [PATCH 030/249] Caching Maven Dependencies with Docker - improvements --- .../multi-module-caching/core/pom.xml | 16 ++++++++-------- .../docker-caching/multi-module-caching/pom.xml | 17 +++++++++-------- .../multi-module-caching/runner/pom.xml | 15 ++++++++------- .../single-module-caching/pom.xml | 10 +++++----- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/docker/docker-caching/multi-module-caching/core/pom.xml b/docker/docker-caching/multi-module-caching/core/pom.xml index 0b79a64143..eeeb5a6e5b 100644 --- a/docker/docker-caching/multi-module-caching/core/pom.xml +++ b/docker/docker-caching/multi-module-caching/core/pom.xml @@ -2,19 +2,14 @@ + 4.0.0 + core + multi-module-caching com.baeldung 0.0.1-SNAPSHOT - 4.0.0 - - core - - - 8 - 8 - @@ -22,4 +17,9 @@ guava + + + 8 + 8 + \ No newline at end of file diff --git a/docker/docker-caching/multi-module-caching/pom.xml b/docker/docker-caching/multi-module-caching/pom.xml index 42205a29de..c5a7d9ec6f 100644 --- a/docker/docker-caching/multi-module-caching/pom.xml +++ b/docker/docker-caching/multi-module-caching/pom.xml @@ -2,19 +2,12 @@ 4.0.0 - pom - - runner - core - com.baeldung multi-module-caching 0.0.1-SNAPSHOT maven-caching maven-caching - - 1.8 - + pom @@ -26,4 +19,12 @@ + + 1.8 + + + + runner + core + diff --git a/docker/docker-caching/multi-module-caching/runner/pom.xml b/docker/docker-caching/multi-module-caching/runner/pom.xml index d306baf05d..e3654bff17 100644 --- a/docker/docker-caching/multi-module-caching/runner/pom.xml +++ b/docker/docker-caching/multi-module-caching/runner/pom.xml @@ -2,14 +2,15 @@ + 4.0.0 + runner + multi-module-caching com.baeldung 0.0.1-SNAPSHOT - 4.0.0 - runner com.baeldung @@ -18,11 +19,6 @@ - - 8 - 8 - - @@ -52,4 +48,9 @@ + + + 8 + 8 + \ No newline at end of file diff --git a/docker/docker-caching/single-module-caching/pom.xml b/docker/docker-caching/single-module-caching/pom.xml index b1abc55772..386b040138 100644 --- a/docker/docker-caching/single-module-caching/pom.xml +++ b/docker/docker-caching/single-module-caching/pom.xml @@ -8,11 +8,6 @@ single-module-caching 1.0-SNAPSHOT - - 8 - 8 - - com.google.guava @@ -50,4 +45,9 @@
+ + + 8 + 8 + \ No newline at end of file From d00308836475c4669916b4506c7251496cf4142f Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 22 Feb 2022 12:01:06 +0530 Subject: [PATCH 031/249] JAVA-10081 :Create new module hibernate-mapping from spring-hibernate-5 module --- .../hibernate-many-to-many/.gitignore | 13 ++ .../hibernate-many-to-many/README.md | 7 + .../_2.fdt | Bin 0 -> 160 bytes .../_2.fdx | Bin 0 -> 84 bytes .../_2.fnm | Bin 0 -> 532 bytes .../_2.nvd | Bin 0 -> 65 bytes .../_2.nvm | Bin 0 -> 88 bytes .../_2.si | Bin 0 -> 514 bytes .../_2.tvd | Bin 0 -> 392 bytes .../_2.tvx | Bin 0 -> 79 bytes .../_2_Lucene50_0.doc | Bin 0 -> 190 bytes .../_2_Lucene50_0.pos | Bin 0 -> 162 bytes .../_2_Lucene50_0.tim | Bin 0 -> 914 bytes .../_2_Lucene50_0.tip | Bin 0 -> 195 bytes .../_3.cfe | Bin 0 -> 341 bytes .../_3.cfs | Bin 0 -> 2119 bytes .../_3.si | Bin 0 -> 371 bytes .../segments_5 | Bin 0 -> 198 bytes .../write.lock | 0 .../hibernate-many-to-many/pom.xml | 136 ++++++++++++++ .../hibernate/manytomany/model/Employee.java | 176 +++++++++--------- .../hibernate/manytomany/model/Project.java | 122 ++++++------ .../manytomany/util/HibernateUtil.java | 90 ++++----- .../manytomany/spring/PersistenceConfig.java | 140 +++++++------- .../persistence/dao/common/AbstractDao.java | 14 ++ .../dao/common/AbstractHibernateDao.java | 59 ++++++ .../persistence/dao/common/IOperations.java | 20 ++ .../manytomany/dao/IEmployeeDao.java | 16 +- .../manytomany/dao/IProjectDao.java | 16 +- .../manytomany/dao/impl/EmployeeDao.java | 32 ++-- .../manytomany/dao/impl/ProjectDao.java | 34 ++-- .../baeldung/spring/PersistenceConfig.java | 75 ++++++++ .../src/main/resources/import.sql | 31 +++ .../src/main/resources/logback.xml | 19 ++ .../src/main/resources/manytomany.cfg.xml | 30 +-- .../main/resources/persistence-h2.properties | 21 +++ .../java/com/baeldung/SpringContextTest.java | 19 ++ ...notationJavaConfigMainIntegrationTest.java | 98 +++++----- ...nyToManyAnnotationMainIntegrationTest.java | 160 ++++++++-------- .../src/test/resources/.gitignore | 13 ++ .../hibernate/criteria/model/Item.hbm.xml | 22 +++ .../src/test/resources/import.sql | 21 +++ .../src/test/resources/manytomany.cfg.xml | 0 .../spring-hibernate-5/README.md | 1 - .../spring-hibernate-5/pom.xml | 20 ++ .../src/test/resources/import.sql | 1 + 46 files changed, 948 insertions(+), 458 deletions(-) create mode 100644 persistence-modules/hibernate-many-to-many/.gitignore create mode 100644 persistence-modules/hibernate-many-to-many/README.md create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fdt create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fdx create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fnm create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.nvd create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.nvm create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.si create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.tvd create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.tvx create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2_Lucene50_0.doc create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2_Lucene50_0.pos create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2_Lucene50_0.tim create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2_Lucene50_0.tip create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.cfe create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.cfs create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.si create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/segments_5 create mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/write.lock create mode 100644 persistence-modules/hibernate-many-to-many/pom.xml rename persistence-modules/{spring-hibernate-5 => hibernate-many-to-many}/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java (96%) rename persistence-modules/{spring-hibernate-5 => hibernate-many-to-many}/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java (95%) rename persistence-modules/{spring-hibernate-5 => hibernate-many-to-many}/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java (97%) rename persistence-modules/{spring-hibernate-5 => hibernate-many-to-many}/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java (97%) create mode 100644 persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java create mode 100644 persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java create mode 100644 persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/IOperations.java rename persistence-modules/{spring-hibernate-5 => hibernate-many-to-many}/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java (96%) rename persistence-modules/{spring-hibernate-5 => hibernate-many-to-many}/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java (96%) rename persistence-modules/{spring-hibernate-5 => hibernate-many-to-many}/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java (96%) rename persistence-modules/{spring-hibernate-5 => hibernate-many-to-many}/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java (96%) create mode 100644 persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/spring/PersistenceConfig.java create mode 100644 persistence-modules/hibernate-many-to-many/src/main/resources/import.sql create mode 100644 persistence-modules/hibernate-many-to-many/src/main/resources/logback.xml rename persistence-modules/{spring-hibernate-5 => hibernate-many-to-many}/src/main/resources/manytomany.cfg.xml (98%) create mode 100644 persistence-modules/hibernate-many-to-many/src/main/resources/persistence-h2.properties create mode 100644 persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/SpringContextTest.java rename persistence-modules/{spring-hibernate-5 => hibernate-many-to-many}/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java (97%) rename persistence-modules/{spring-hibernate-5 => hibernate-many-to-many}/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java (96%) create mode 100644 persistence-modules/hibernate-many-to-many/src/test/resources/.gitignore create mode 100644 persistence-modules/hibernate-many-to-many/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml create mode 100644 persistence-modules/hibernate-many-to-many/src/test/resources/import.sql rename persistence-modules/{spring-hibernate-5 => hibernate-many-to-many}/src/test/resources/manytomany.cfg.xml (100%) diff --git a/persistence-modules/hibernate-many-to-many/.gitignore b/persistence-modules/hibernate-many-to-many/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/persistence-modules/hibernate-many-to-many/README.md b/persistence-modules/hibernate-many-to-many/README.md new file mode 100644 index 0000000000..19b865d4e1 --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/README.md @@ -0,0 +1,7 @@ +## Hibernate 5 with Spring + +This module contains articles about Hibernate 5 with Spring. + +### Relevant articles + +- [Hibernate Many to Many Annotation Tutorial](https://www.baeldung.com/hibernate-many-to-many) \ No newline at end of file diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fdt b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fdt new file mode 100644 index 0000000000000000000000000000000000000000..d71a08150212e0d18327d1491c3687976b1c0d38 GIT binary patch literal 160 zcmcD&o+B>fQ<|KbmuhMdT#{dun&Ot3nv+uOmRMZkl30?+z`($mbzSAP`{iOo;d#DB z{fW~w7#bQFnHYE&m>Bf`D==s!=jZArB?2{-=B4XpWG1B+d6=BK3Q y=miwzr<5j_a4;I`Gf2xDfe2#|VFDsd^%=wiK$2#Rj0ZF(zW`bZ2Af23UjYC|kS^)~ literal 0 HcmV?d00001 diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fdx b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fdx new file mode 100644 index 0000000000000000000000000000000000000000..72359255c620cb440b643215ce0e4a85f205da77 GIT binary patch literal 84 zcmcD&o+B>nQ<|KbmuhMdT#{dun&Ot3nv+uOmRMZknU|7U!N9=4m~~y{wfp5_L*aS8 hM*WG?G#Ho|fuamnK+Mp`ctB(F3!o}62&>U62LPU67+U}U literal 0 HcmV?d00001 diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fnm b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fnm new file mode 100644 index 0000000000000000000000000000000000000000..b0143e1ac5e967810feee7771557bca5f71a4922 GIT binary patch literal 532 zcmcD&o+B>gQ<|KbmuhO@mYJH9;+dD0U(CS3z?gMi<+c0eVngA1zDE6t(=-@Z1>!R@ zlTwTF5=&C!lXDV_iy4@h8U8~7lWah05!i%){Nj?#y!2wX{G!~%61_Aq#R0Pfm$Ks0 zw6x3$MgykI6h;~t%Uw{EpHiA!;+L44%EU;0XLF~d7AF^F7L;V>=P}d3e74-w-29?S W7A8ijhxh@F$uEEr4hGV{B@6-GbkQ<|KbmuhP4mtT}y?2=fL$N&Uc*HvD-UoJKjp66@SpEyl}p`^5=qP+Zo P#^e_uX%J`#I_?Dk?LHOl literal 0 HcmV?d00001 diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.nvm b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.nvm new file mode 100644 index 0000000000000000000000000000000000000000..19f60a39bcf9a121ca3bc1590ba6df45481bf44a GIT binary patch literal 88 zcmcD&o+B>mQ<|KbmuhP4mtT}y?3-GWn37nM$N&Uc*HvD-UoJKjp66@SpEyl}fe9oE b0_Dt%5C((xe<0vLpfULcRDfZE({vpGz#bVo literal 0 HcmV?d00001 diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.si b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.si new file mode 100644 index 0000000000000000000000000000000000000000..3d537083b422c76bfcef3c42fb25ad1eeb45bf4f GIT binary patch literal 514 zcmZWm-AcnS7+u9~xJ_kF@X}p)F_49(cGKM`sGA6z3LSV^LX*u()08Bwdy8ENUivJ) zgBN=R!3XeC(?5_cA^AAx`_AEzTrB;A<|uMWK)QxaW|Rc-Hkh(fsiZwGkG^j{1#G^L z%>{aEE3TyfJLTW{1{2jsFTm_Yw4hOYMlk|0QJC-DbL9G@b;WqdIFcR<>Uoeh~}|{1}jVe#N8(yQQWik zQ)?at(xar1ultt;i?~bl)UlS{L*z=vHCR=Cd9F=p0Ank05)#pH8}_U&JhRM`Qv+J{ zvSWfE#=0uPOMr}VQl?mDXx?y4r+8<_03j2ZhNfddR`BW=X6}kmC0JuZ?Xa-6Rc?ZZ k9`UglGER{Mlwnf69M}`bei#g{KiaQf$xkNh=X|#K1BMr#*8l(j literal 0 HcmV?d00001 diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.tvd b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.tvd new file mode 100644 index 0000000000000000000000000000000000000000..b46c8d109cc2a907cd84fbbf6e87ad51cff7929d GIT binary patch literal 392 zcmW-dze`(D6vxlgC=Ftbkz&VE+Y%kb7xR(~f;J6xskBJ7;&$@h$$eMukH@|D5#1c@ zY@rZ05n3p562ZMwXQ6|CK$p@kP90qA)dSxH-w)?}hwt*0n4W%<$D}A)cuz)dQtY&` zZFC3#!OqpQzpFoOICZ>MJ;Z(mhW4MpC=5S6J3Rp?TztHUHa12|C4al(ec7uGFuV`N zwtdxl{be0L)M|6li$@3D#^4}aXWR8M+x#~3{HS=hKLx>c1%=gFCMeF0A>~LVU5v?S znR1r$L}+IvNp1G5MB}nlE2>6yT!fHycnKzVAHu{-D2z5B46Dsq7;C_JiiUB;x<2JC z{0js+vW_b<#BzbA1vkY!%e3)~^|&EH*1D7{AFu^KP$fq5gc(A&1lJEdWhiiWuVWi1 zZLV0H5@vs(@86~Fa6$8MJKp0e(LK9Ztw#&2BXY@6^4MsryRHdSk84eMcW;8=d*$dQ<|KbmuhMdl3J7-mYQ6WUsUXwmy%k+z`($mbzSAP`{iOo;d#DB{fW~w c7?>D=q6{WL%lQ<|KbmuhMdkY8MqnU`K1UX)pqTI7lQ<|KbmuhMdkY8MqnU`K1UX)pqS_I@V072GumDlcM>D0O1m)+6Xon>a0yL6Ju zPB5UIt(}E`f&YVGdMiQjZ}81-E~Sw9*!Mke-tWy$&h(9yN7^KB4lKX{*up(gi6?}x z*JpSCJpJLeS3f@=zLy_2d(Y|wN*E1Z4#)(+SyRNB1?i()WjRx+P*rY95IW@bkya%{+IS}l zD2zQ8g_$Z19Sd2lrR}*wTHi$UTwPVhhN?R=Ri|!pY zU}+~qDjJ_4PtwPPQ1s#)4eVlYj=Dxd(kyhtg(^aYXnj$PsFP(_UTSb9ySE;6O@d^d4#s+OQVVr!snE98D%uaoJ%K^ar7cF zA>#Ha<=ewOJ{*nN&XA9H2Yfsl(7m=nB9mIqk6AW7hdb7Fq2!f9CDu4|ud%Q3 z)|O}=w*Qa=sf%)2=veIo2S29o{)`q GU*tdZxy^3? literal 0 HcmV?d00001 diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2_Lucene50_0.tip b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2_Lucene50_0.tip new file mode 100644 index 0000000000000000000000000000000000000000..9803f1b398829ace933101fbc393ea47807267f3 GIT binary patch literal 195 zcmcD&o+B>ol#`#F9a5B<8j@O+TkM&al3KyQz`&GsUFEg=&diPJQ=d`gp3 z^HNO>;tlM9+L+yfLx9Ry85o(FA2Bg7FfyQtvaZ7>%C`xdDE~WbqC%6vqUOHImHmuB VyFg&+0gcHoAWQ~^%eLE20RSolE8PG9 literal 0 HcmV?d00001 diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.cfe b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.cfe new file mode 100644 index 0000000000000000000000000000000000000000..8fb074f30e754beeb8a030f31d07de2babe63b62 GIT binary patch literal 341 zcmcD&o+B>qQ<|KbmuhO@oS$2eUz(TVnpaYknOe*M1X zMK3L-0we_ldJu{sm_;wIECtGGgwodh@i2qq4fG1~!R7(w_CVz$QRGwdlOf`aqEPuf z6#0_OT&R3Agl1A?(JO&j%De=sX$r_CP?aneP{9bGoAY3T6QJ5fKprW9aM)nl8$o75 heaEf})$WhxkOGJ}J5)2n;R70zUqIC|B=Stl1OR>yJ!${| literal 0 HcmV?d00001 diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.cfs b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.cfs new file mode 100644 index 0000000000000000000000000000000000000000..e26078b9e7cfbaca6e06ec3cf3156f48d0b92d08 GIT binary patch literal 2119 zcmcIl%TE(Q7@wKl?Nj9~Z^TD}V5}4bjIXK?ltc&#L?Vgcc6Uk_yF1P9Ho&d%ZHikvL|pRoxVQ^K z83{+s+sl-S$2ZRGxRR1B3lRZvSZ<_#keUvHD~?{6F0vg-IFEoEWVdZrCXvvlaVybO zd<3xJbWT_UvQ7y;{ItU=wG>lJ+Zr>3Bf$6RRA=Ul2s+O7`|vvMJrf^(q(=FfsB`Js zdh6tGi|wZ)o5chXa%rs*9YE3nP;9|rzY@LhlP6H+Cg2g^emCA_KJlIwzKdsR=fI@nK?+`vA14I OvhREg-uJeq`PhGT-i literal 0 HcmV?d00001 diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.si b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.si new file mode 100644 index 0000000000000000000000000000000000000000..f2d6b6a030c291e9fdddf28b924e5caad9a02f57 GIT binary patch literal 371 zcmcD&o+B>oQ<|KbmuhMdoSL4SnpfhPmzK}Kz`&SwUFEg=&diPN-zVhpTE zn30i-DZiL2JTosPzr0w%(11HDu`E%qEEUKv67nxfOwLJFaLz9($S+DP$;{8=fl3z@ z13B!5hI$5ihKBqQ!Cas=u(%*pT-#FDCnQ+c(9(o22kbnU0#;K!AY{)k)=Ml(&R|W< zO))bO0UJ_OnpcvUn+j8iX%bs;erZv1Dr;I!X>kS@&;+QREQSVp2Am+h#U+Wk1-yo4 zCZ>iKCPv2Q#-`@XtntQr#hGkCGC8dnLZvdw!^5m3zbG}uEi*MIrPwXMC^xZ0FE>9W cmCMOBI3zwez}3~|fX3t(pr8YRcS#F10cJaIr~m)} literal 0 HcmV?d00001 diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/segments_5 b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/segments_5 new file mode 100644 index 0000000000000000000000000000000000000000..66a4c385a5adac5ff16e505da6de875fcd295c3d GIT binary patch literal 198 zcmcD&o+HjtoSL4SnpaZHz`($kbzSAP`{iOo;d#DB{fX1G8BJMPS%DHDAOOTHK+FUb zVv09nL{qE5;ZvHNnwM&7@*fI7nqX`g4H9EuiZ@2rtwp?Uh65UtUx3X45?V&3b^sz| BR7L;* literal 0 HcmV?d00001 diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/write.lock b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/write.lock new file mode 100644 index 0000000000..e69de29bb2 diff --git a/persistence-modules/hibernate-many-to-many/pom.xml b/persistence-modules/hibernate-many-to-many/pom.xml new file mode 100644 index 0000000000..6f1abb6a7a --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/pom.xml @@ -0,0 +1,136 @@ + + + 4.0.0 + hibernate-many-to-many + 0.1-SNAPSHOT + hibernate-many-to-many + + + com.baeldung + persistence-modules + 1.0.0-SNAPSHOT + + + + + + org.springframework + spring-context + ${org.springframework.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-aspects + ${org.springframework.version} + + + + org.springframework + spring-orm + ${org.springframework.version} + + + org.springframework.data + spring-data-jpa + ${org.springframework.data.version} + + + org.hibernate + hibernate-core + ${hibernate.version} + + + javax.transaction + jta + ${jta.version} + + + org.hibernate + hibernate-search-orm + ${hibernatesearch.version} + + + org.apache.tomcat + tomcat-dbcp + ${tomcat-dbcp.version} + + + + + com.google.guava + guava + ${guava.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + test + + + org.springframework + spring-test + ${org.springframework.version} + test + + + org.springframework.security + spring-security-test + ${org.springframework.security.version} + test + + + org.hsqldb + hsqldb + ${hsqldb.version} + + + com.h2database + h2 + ${h2.version} + + + jakarta.xml.bind + jakarta.xml.bind-api + 2.3.2 + + + com.sun.xml.bind + jaxb-core + 2.3.0.1 + + + javax.xml.bind + jaxb-api + 2.3.1 + + + com.sun.xml.bind + jaxb-impl + 2.3.1 + + + + + + 5.0.2.RELEASE + 1.10.6.RELEASE + 4.2.1.RELEASE + + 5.2.10.Final + 5.8.2.Final + 9.0.0.M26 + 1.1 + 2.3.4 + + + \ No newline at end of file diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java similarity index 96% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java rename to persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java index 8157945e2c..bfe1b5ad29 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java +++ b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java @@ -1,88 +1,88 @@ -package com.baeldung.hibernate.manytomany.model; - -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.Table; - -@Entity -@Table(name = "Employee") -public class Employee implements Serializable { - @Id - @Column(name = "employee_id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long employeeId; - - @Column(name = "first_name") - private String firstName; - - @Column(name = "last_name") - private String lastName; - - @ManyToMany(cascade = { CascadeType.ALL }) - @JoinTable( - name = "Employee_Project", - joinColumns = { @JoinColumn(name = "employee_id") }, - inverseJoinColumns = { @JoinColumn(name = "project_id") } - ) - Set projects = new HashSet(); - - - public Employee() { - super(); - } - - public Employee(String firstName, String lastName) { - this.firstName = firstName; - this.lastName = lastName; - } - - public Employee(String firstName, String lastName, Set projects) { - this.firstName = firstName; - this.lastName = lastName; - this.projects = projects; - } - - - public Long getEmployeeId() { - return employeeId; - } - - public void setEmployeeId(Long employeeId) { - this.employeeId = employeeId; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public Set getProjects() { - return projects; - } - - public void setProjects(Set projects) { - this.projects = projects; - } -} +package com.baeldung.hibernate.manytomany.model; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.Table; + +@Entity +@Table(name = "Employee") +public class Employee implements Serializable { + @Id + @Column(name = "employee_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long employeeId; + + @Column(name = "first_name") + private String firstName; + + @Column(name = "last_name") + private String lastName; + + @ManyToMany(cascade = { CascadeType.ALL }) + @JoinTable( + name = "Employee_Project", + joinColumns = { @JoinColumn(name = "employee_id") }, + inverseJoinColumns = { @JoinColumn(name = "project_id") } + ) + Set projects = new HashSet(); + + + public Employee() { + super(); + } + + public Employee(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public Employee(String firstName, String lastName, Set projects) { + this.firstName = firstName; + this.lastName = lastName; + this.projects = projects; + } + + + public Long getEmployeeId() { + return employeeId; + } + + public void setEmployeeId(Long employeeId) { + this.employeeId = employeeId; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public Set getProjects() { + return projects; + } + + public void setProjects(Set projects) { + this.projects = projects; + } +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java similarity index 95% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java rename to persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java index d6c049f33e..c291d7d7af 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java +++ b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java @@ -1,61 +1,61 @@ -package com.baeldung.hibernate.manytomany.model; - -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.ManyToMany; -import javax.persistence.Table; - -@Entity -@Table(name = "Project") -public class Project implements Serializable { - - @Id - @Column(name = "project_id") - @GeneratedValue - private Long projectId; - - @Column(name = "title") - private String title; - - @ManyToMany(mappedBy = "projects") - private Set employees = new HashSet(); - - public Project() { - super(); - } - - public Project(String title) { - this.title = title; - } - - public Long getProjectId() { - return projectId; - } - - public void setProjectId(Long projectId) { - this.projectId = projectId; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public Set getEmployees() { - return employees; - } - - public void setEmployees(Set employees) { - this.employees = employees; - } - - -} +package com.baeldung.hibernate.manytomany.model; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.ManyToMany; +import javax.persistence.Table; + +@Entity +@Table(name = "Project") +public class Project implements Serializable { + + @Id + @Column(name = "project_id") + @GeneratedValue + private Long projectId; + + @Column(name = "title") + private String title; + + @ManyToMany(mappedBy = "projects") + private Set employees = new HashSet(); + + public Project() { + super(); + } + + public Project(String title) { + this.title = title; + } + + public Long getProjectId() { + return projectId; + } + + public void setProjectId(Long projectId) { + this.projectId = projectId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public Set getEmployees() { + return employees; + } + + public void setEmployees(Set employees) { + this.employees = employees; + } + + +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java similarity index 97% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java rename to persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java index 29e8d7515a..ff035c0c37 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java +++ b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java @@ -1,45 +1,45 @@ -package com.baeldung.hibernate.manytomany.util; - -import org.hibernate.SessionFactory; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -import org.hibernate.cfg.Configuration; -import org.hibernate.service.ServiceRegistry; -import com.baeldung.hibernate.manytomany.model.Employee; -import com.baeldung.hibernate.manytomany.model.Project; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class HibernateUtil { - - private static final Logger LOGGER = LoggerFactory.getLogger(HibernateUtil.class); - private static SessionFactory sessionFactory; - - private static SessionFactory buildSessionFactory() { - try { - // Create the SessionFactory from hibernate-annotation.cfg.xml - Configuration configuration = new Configuration(); - configuration.addAnnotatedClass(Employee.class); - configuration.addAnnotatedClass(Project.class); - configuration.configure("manytomany.cfg.xml"); - LOGGER.debug("Hibernate Annotation Configuration loaded"); - - ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()) - .build(); - LOGGER.debug("Hibernate Annotation serviceRegistry created"); - - SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry); - - return sessionFactory; - } catch (Throwable ex) { - LOGGER.error("Initial SessionFactory creation failed.", ex); - throw new ExceptionInInitializerError(ex); - } - } - - public static SessionFactory getSessionFactory() { - if (sessionFactory == null) { - sessionFactory = buildSessionFactory(); - } - return sessionFactory; - } -} +package com.baeldung.hibernate.manytomany.util; + +import org.hibernate.SessionFactory; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Configuration; +import org.hibernate.service.ServiceRegistry; +import com.baeldung.hibernate.manytomany.model.Employee; +import com.baeldung.hibernate.manytomany.model.Project; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HibernateUtil { + + private static final Logger LOGGER = LoggerFactory.getLogger(HibernateUtil.class); + private static SessionFactory sessionFactory; + + private static SessionFactory buildSessionFactory() { + try { + // Create the SessionFactory from hibernate-annotation.cfg.xml + Configuration configuration = new Configuration(); + configuration.addAnnotatedClass(Employee.class); + configuration.addAnnotatedClass(Project.class); + configuration.configure("manytomany.cfg.xml"); + LOGGER.debug("Hibernate Annotation Configuration loaded"); + + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()) + .build(); + LOGGER.debug("Hibernate Annotation serviceRegistry created"); + + SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry); + + return sessionFactory; + } catch (Throwable ex) { + LOGGER.error("Initial SessionFactory creation failed.", ex); + throw new ExceptionInInitializerError(ex); + } + } + + public static SessionFactory getSessionFactory() { + if (sessionFactory == null) { + sessionFactory = buildSessionFactory(); + } + return sessionFactory; + } +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java similarity index 97% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java rename to persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java index b8e7e1b2fd..f7179b07e5 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java +++ b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java @@ -1,70 +1,70 @@ -package com.baeldung.manytomany.spring; - -import java.util.Properties; -import javax.sql.DataSource; -import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.core.env.Environment; -import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; -import org.springframework.orm.hibernate5.HibernateTransactionManager; -import org.springframework.orm.hibernate5.LocalSessionFactoryBean; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - - -@Configuration -@EnableTransactionManagement -@PropertySource({ "classpath:persistence-h2.properties" }) -@ComponentScan({ "com.baeldung.hibernate.manytomany" }) -public class PersistenceConfig { - - @Autowired - private Environment env; - - @Bean - public LocalSessionFactoryBean sessionFactory() { - final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); - sessionFactory.setDataSource(restDataSource()); - sessionFactory.setPackagesToScan(new String[] { "com.baeldung.hibernate.manytomany" }); - sessionFactory.setHibernateProperties(hibernateProperties()); - - return sessionFactory; - } - - @Bean - public DataSource restDataSource() { - final BasicDataSource dataSource = new BasicDataSource(); - dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName")); - dataSource.setUrl(env.getProperty("jdbc.url")); - dataSource.setUsername(env.getProperty("jdbc.user")); - dataSource.setPassword(env.getProperty("jdbc.pass")); - - return dataSource; - } - - @Bean - public PlatformTransactionManager hibernateTransactionManager() { - final HibernateTransactionManager transactionManager = new HibernateTransactionManager(); - transactionManager.setSessionFactory(sessionFactory().getObject()); - return transactionManager; - } - - @Bean - public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { - return new PersistenceExceptionTranslationPostProcessor(); - } - - private final Properties hibernateProperties() { - final Properties hibernateProperties = new Properties(); - hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); - hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); - hibernateProperties.setProperty("hibernate.show_sql", "false"); - - return hibernateProperties; - } -} +package com.baeldung.manytomany.spring; + +import java.util.Properties; +import javax.sql.DataSource; +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.orm.hibernate5.HibernateTransactionManager; +import org.springframework.orm.hibernate5.LocalSessionFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + + +@Configuration +@EnableTransactionManagement +@PropertySource({ "classpath:persistence-h2.properties" }) +@ComponentScan({ "com.baeldung.hibernate.manytomany" }) +public class PersistenceConfig { + + @Autowired + private Environment env; + + @Bean + public LocalSessionFactoryBean sessionFactory() { + final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); + sessionFactory.setDataSource(restDataSource()); + sessionFactory.setPackagesToScan(new String[] { "com.baeldung.hibernate.manytomany" }); + sessionFactory.setHibernateProperties(hibernateProperties()); + + return sessionFactory; + } + + @Bean + public DataSource restDataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName")); + dataSource.setUrl(env.getProperty("jdbc.url")); + dataSource.setUsername(env.getProperty("jdbc.user")); + dataSource.setPassword(env.getProperty("jdbc.pass")); + + return dataSource; + } + + @Bean + public PlatformTransactionManager hibernateTransactionManager() { + final HibernateTransactionManager transactionManager = new HibernateTransactionManager(); + transactionManager.setSessionFactory(sessionFactory().getObject()); + return transactionManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + private final Properties hibernateProperties() { + final Properties hibernateProperties = new Properties(); + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + hibernateProperties.setProperty("hibernate.show_sql", "false"); + + return hibernateProperties; + } +} diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java new file mode 100644 index 0000000000..5a6c76a93a --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java @@ -0,0 +1,14 @@ +package com.baeldung.persistence.dao.common; + +import java.io.Serializable; + +import com.google.common.base.Preconditions; + +public abstract class AbstractDao implements IOperations { + + protected Class clazz; + + protected final void setClazz(final Class clazzToSet) { + clazz = Preconditions.checkNotNull(clazzToSet); + } +} diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java new file mode 100644 index 0000000000..f34866d883 --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java @@ -0,0 +1,59 @@ +package com.baeldung.persistence.dao.common; + +import java.io.Serializable; +import java.util.List; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import com.google.common.base.Preconditions; + +@SuppressWarnings("unchecked") +public abstract class AbstractHibernateDao extends AbstractDao implements IOperations { + + @Autowired + protected SessionFactory sessionFactory; + + // API + + @Override + public T findOne(final long id) { + return (T) getCurrentSession().get(clazz, id); + } + + @Override + public List findAll() { + return getCurrentSession().createQuery("from " + clazz.getName()).getResultList(); + } + + @Override + public void create(final T entity) { + Preconditions.checkNotNull(entity); + getCurrentSession().saveOrUpdate(entity); + } + + @Override + public T update(final T entity) { + Preconditions.checkNotNull(entity); + return (T) getCurrentSession().merge(entity); + } + + @Override + public void delete(final T entity) { + Preconditions.checkNotNull(entity); + getCurrentSession().delete(entity); + } + + @Override + public void deleteById(final long entityId) { + final T entity = findOne(entityId); + Preconditions.checkState(entity != null); + delete(entity); + } + + protected Session getCurrentSession() { + return sessionFactory.getCurrentSession(); + } + +} \ No newline at end of file diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/IOperations.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/IOperations.java new file mode 100644 index 0000000000..4ef99221ab --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/IOperations.java @@ -0,0 +1,20 @@ +package com.baeldung.persistence.dao.common; + +import java.io.Serializable; +import java.util.List; + +public interface IOperations { + + T findOne(final long id); + + List findAll(); + + void create(final T entity); + + T update(final T entity); + + void delete(final T entity); + + void deleteById(final long entityId); + +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java similarity index 96% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java rename to persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java index d619807b64..5ba018dc52 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java +++ b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java @@ -1,8 +1,8 @@ -package com.baeldung.persistence.manytomany.dao; - -import com.baeldung.hibernate.manytomany.model.Employee; -import com.baeldung.persistence.dao.common.IOperations; - -public interface IEmployeeDao extends IOperations{ - -} +package com.baeldung.persistence.manytomany.dao; + +import com.baeldung.hibernate.manytomany.model.Employee; +import com.baeldung.persistence.dao.common.IOperations; + +public interface IEmployeeDao extends IOperations{ + +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java similarity index 96% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java rename to persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java index 4a55714f8d..48fbb8bf6b 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java +++ b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java @@ -1,8 +1,8 @@ -package com.baeldung.persistence.manytomany.dao; - -import com.baeldung.hibernate.manytomany.model.Project; -import com.baeldung.persistence.dao.common.IOperations; - -public interface IProjectDao extends IOperations{ - -} +package com.baeldung.persistence.manytomany.dao; + +import com.baeldung.hibernate.manytomany.model.Project; +import com.baeldung.persistence.dao.common.IOperations; + +public interface IProjectDao extends IOperations{ + +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java similarity index 96% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java rename to persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java index b062c00ff9..25fee8c379 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java +++ b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java @@ -1,16 +1,16 @@ -package com.baeldung.persistence.manytomany.dao.impl; - -import org.springframework.stereotype.Repository; -import com.baeldung.hibernate.manytomany.model.Employee; -import com.baeldung.persistence.dao.common.AbstractHibernateDao; -import com.baeldung.persistence.manytomany.dao.IEmployeeDao; - -@Repository -public class EmployeeDao extends AbstractHibernateDao implements IEmployeeDao { - - public EmployeeDao() { - super(); - - setClazz(Employee.class); - } -} +package com.baeldung.persistence.manytomany.dao.impl; + +import org.springframework.stereotype.Repository; +import com.baeldung.hibernate.manytomany.model.Employee; +import com.baeldung.persistence.dao.common.AbstractHibernateDao; +import com.baeldung.persistence.manytomany.dao.IEmployeeDao; + +@Repository +public class EmployeeDao extends AbstractHibernateDao implements IEmployeeDao { + + public EmployeeDao() { + super(); + + setClazz(Employee.class); + } +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java similarity index 96% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java rename to persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java index 772026fbc1..8fc29a5de3 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java +++ b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java @@ -1,17 +1,17 @@ -package com.baeldung.persistence.manytomany.dao.impl; - -import org.springframework.stereotype.Repository; -import com.baeldung.hibernate.manytomany.model.Project; -import com.baeldung.persistence.dao.common.AbstractHibernateDao; -import com.baeldung.persistence.manytomany.dao.IProjectDao; - - -@Repository -public class ProjectDao extends AbstractHibernateDao implements IProjectDao { - - public ProjectDao() { - super(); - - setClazz(Project.class); - } -} +package com.baeldung.persistence.manytomany.dao.impl; + +import org.springframework.stereotype.Repository; +import com.baeldung.hibernate.manytomany.model.Project; +import com.baeldung.persistence.dao.common.AbstractHibernateDao; +import com.baeldung.persistence.manytomany.dao.IProjectDao; + + +@Repository +public class ProjectDao extends AbstractHibernateDao implements IProjectDao { + + public ProjectDao() { + super(); + + setClazz(Project.class); + } +} diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/spring/PersistenceConfig.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/spring/PersistenceConfig.java new file mode 100644 index 0000000000..e1ea3e2024 --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/spring/PersistenceConfig.java @@ -0,0 +1,75 @@ +package com.baeldung.spring; + +import com.google.common.base.Preconditions; +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.orm.hibernate5.HibernateTransactionManager; +import org.springframework.orm.hibernate5.LocalSessionFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; +import java.util.Properties; + +@Configuration +@EnableTransactionManagement +@PropertySource({ "classpath:persistence-h2.properties" }) +@ComponentScan({ "com.baeldung.persistence" }) +public class PersistenceConfig { + + @Autowired + private Environment env; + + @Bean + public LocalSessionFactoryBean sessionFactory() { + final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); + sessionFactory.setDataSource(dataSource()); + sessionFactory.setPackagesToScan(new String[] { "com.baeldung.persistence.model" }); + sessionFactory.setHibernateProperties(hibernateProperties()); + + return sessionFactory; + } + + @Bean + public DataSource dataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); + dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); + + return dataSource; + } + + @Bean + public PlatformTransactionManager hibernateTransactionManager() { + final HibernateTransactionManager transactionManager = new HibernateTransactionManager(); + transactionManager.setSessionFactory(sessionFactory().getObject()); + return transactionManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + private final Properties hibernateProperties() { + final Properties hibernateProperties = new Properties(); + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + + hibernateProperties.setProperty("hibernate.show_sql", "false"); + + // Envers properties + hibernateProperties.setProperty("org.hibernate.envers.audit_table_suffix", env.getProperty("envers.audit_table_suffix")); + + return hibernateProperties; + } + +} \ No newline at end of file diff --git a/persistence-modules/hibernate-many-to-many/src/main/resources/import.sql b/persistence-modules/hibernate-many-to-many/src/main/resources/import.sql new file mode 100644 index 0000000000..ae008f29bc --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/src/main/resources/import.sql @@ -0,0 +1,31 @@ +insert into item (item_id, item_name, item_desc, item_price) +values(1,'item One', 'test 1', 35.12); + +insert into item (item_id, item_name, item_desc, item_price) +values(2,'Pogo stick', 'Pogo stick', 466.12); +insert into item (item_id, item_name, item_desc, item_price) +values(3,'Raft', 'Raft', 345.12); + +insert into item (item_id, item_name, item_desc, item_price) +values(4,'Skate Board', 'Skating', 135.71); + +insert into item (item_id, item_name, item_desc, item_price) +values(5,'Umbrella', 'Umbrella for Rain', 619.25); + +insert into item (item_id, item_name, item_desc, item_price) +values(6,'Glue', 'Glue for home', 432.73); + +insert into item (item_id, item_name, item_desc, item_price) +values(7,'Paint', 'Paint for Room', 1311.40); + +insert into item (item_id, item_name, item_desc, item_price) +values(8,'Red paint', 'Red paint for room', 1135.71); + +insert into item (item_id, item_name, item_desc, item_price) +values(9,'Household Chairs', 'Chairs for house', 25.71); + +insert into item (item_id, item_name, item_desc, item_price) +values(10,'Office Chairs', 'Chairs for office', 395.98); + +insert into item (item_id, item_name, item_desc, item_price) +values(11,'Outdoor Chairs', 'Chairs for outdoor activities', 1234.36); diff --git a/persistence-modules/hibernate-many-to-many/src/main/resources/logback.xml b/persistence-modules/hibernate-many-to-many/src/main/resources/logback.xml new file mode 100644 index 0000000000..ec0dc2469a --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml b/persistence-modules/hibernate-many-to-many/src/main/resources/manytomany.cfg.xml similarity index 98% rename from persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml rename to persistence-modules/hibernate-many-to-many/src/main/resources/manytomany.cfg.xml index 315e2e3118..d7c8f24fb0 100644 --- a/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml +++ b/persistence-modules/hibernate-many-to-many/src/main/resources/manytomany.cfg.xml @@ -1,15 +1,15 @@ - - - - - com.mysql.jdbc.Driver - tutorialmy5ql - jdbc:mysql://localhost:3306/spring_hibernate_many_to_many - tutorialuser - org.hibernate.dialect.MySQLDialect - thread - false - - + + + + + com.mysql.jdbc.Driver + tutorialmy5ql + jdbc:mysql://localhost:3306/spring_hibernate_many_to_many + tutorialuser + org.hibernate.dialect.MySQLDialect + thread + false + + diff --git a/persistence-modules/hibernate-many-to-many/src/main/resources/persistence-h2.properties b/persistence-modules/hibernate-many-to-many/src/main/resources/persistence-h2.properties new file mode 100644 index 0000000000..e3544d354a --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/src/main/resources/persistence-h2.properties @@ -0,0 +1,21 @@ +# jdbc.X +jdbc.driverClassName=org.h2.Driver +jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +jdbc.eventGeneratedId=sa +jdbc.user=sa +jdbc.pass= + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=false +hibernate.hbm2ddl.auto=create-drop +hibernate.cache.use_second_level_cache=true +hibernate.cache.use_query_cache=true +hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory + +# hibernate.search.X +hibernate.search.default.directory_provider = filesystem +hibernate.search.default.indexBase = /data/index/default + +# envers.X +envers.audit_table_suffix=_audit_log diff --git a/persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/SpringContextTest.java new file mode 100644 index 0000000000..24c038aeb6 --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/SpringContextTest.java @@ -0,0 +1,19 @@ +package com.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + + +import com.baeldung.spring.PersistenceConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +public class SpringContextTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java b/persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java similarity index 97% rename from persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java rename to persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java index 614de6d3ad..797d3384a0 100644 --- a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java +++ b/persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java @@ -1,49 +1,49 @@ -package com.baeldung.hibernate.manytomany; - -import java.util.HashSet; -import java.util.Set; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.support.AnnotationConfigContextLoader; -import com.baeldung.hibernate.manytomany.model.Employee; -import com.baeldung.hibernate.manytomany.model.Project; -import com.baeldung.manytomany.spring.PersistenceConfig; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) -public class HibernateManyToManyAnnotationJavaConfigMainIntegrationTest { - - @Autowired - private SessionFactory sessionFactory; - - private Session session; - - @Before - public final void before() { - session = sessionFactory.openSession(); - session.beginTransaction(); - } - - @After - public final void after() { - session.getTransaction().commit(); - session.close(); - } - - @Test - public final void whenEntitiesAreCreated_thenNoExceptions() { - Set projects = new HashSet(); - projects.add(new Project("IT Project")); - projects.add(new Project("Networking Project")); - session.persist(new Employee("Peter", "Oven", projects)); - session.persist(new Employee("Allan", "Norman", projects)); - } - -} +package com.baeldung.hibernate.manytomany; + +import java.util.HashSet; +import java.util.Set; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; +import com.baeldung.hibernate.manytomany.model.Employee; +import com.baeldung.hibernate.manytomany.model.Project; +import com.baeldung.manytomany.spring.PersistenceConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +public class HibernateManyToManyAnnotationJavaConfigMainIntegrationTest { + + @Autowired + private SessionFactory sessionFactory; + + private Session session; + + @Before + public final void before() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @After + public final void after() { + session.getTransaction().commit(); + session.close(); + } + + @Test + public final void whenEntitiesAreCreated_thenNoExceptions() { + Set projects = new HashSet(); + projects.add(new Project("IT Project")); + projects.add(new Project("Networking Project")); + session.persist(new Employee("Peter", "Oven", projects)); + session.persist(new Employee("Allan", "Norman", projects)); + } + +} diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java b/persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java similarity index 96% rename from persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java rename to persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java index 0073e181cc..d09b2888df 100644 --- a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java +++ b/persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java @@ -1,80 +1,80 @@ -package com.baeldung.hibernate.manytomany; - -import static org.junit.Assert.assertNotNull; -import static junit.framework.TestCase.assertEquals; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.baeldung.hibernate.manytomany.util.HibernateUtil; -import com.baeldung.hibernate.manytomany.model.Employee; -import com.baeldung.hibernate.manytomany.model.Project; - -/** - * Configured in: manytomany.cfg.xml - */ -public class HibernateManyToManyAnnotationMainIntegrationTest { - private static SessionFactory sessionFactory; - - private Session session; - - @BeforeClass - public static void beforeTests() { - sessionFactory = HibernateUtil.getSessionFactory(); - } - - @Before - public void setUp() { - session = sessionFactory.openSession(); - session.beginTransaction(); - } - - @Test - public void givenData_whenInsert_thenCreatesMtoMrelationship() { - String[] employeeData = { "Peter Oven", "Allan Norman" }; - String[] projectData = { "IT Project", "Networking Project" }; - Set projects = new HashSet(); - - for (String proj : projectData) { - projects.add(new Project(proj)); - } - - for (String emp : employeeData) { - Employee employee = new Employee(emp.split(" ")[0], emp.split(" ")[1]); - assertEquals(0, employee.getProjects().size()); - employee.setProjects(projects); - session.persist(employee); - assertNotNull(employee); - } - } - - @Test - public void givenSession_whenRead_thenReturnsMtoMdata() { - @SuppressWarnings("unchecked") - List employeeList = session.createQuery("FROM Employee").list(); - assertNotNull(employeeList); - for(Employee employee : employeeList) { - assertNotNull(employee.getProjects()); - } - } - - @After - public void tearDown() { - session.getTransaction() - .commit(); - session.close(); - } - - @AfterClass - public static void afterTests() { - sessionFactory.close(); - } - -} +package com.baeldung.hibernate.manytomany; + +import static org.junit.Assert.assertNotNull; +import static junit.framework.TestCase.assertEquals; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.baeldung.hibernate.manytomany.util.HibernateUtil; +import com.baeldung.hibernate.manytomany.model.Employee; +import com.baeldung.hibernate.manytomany.model.Project; + +/** + * Configured in: manytomany.cfg.xml + */ +public class HibernateManyToManyAnnotationMainIntegrationTest { + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsert_thenCreatesMtoMrelationship() { + String[] employeeData = { "Peter Oven", "Allan Norman" }; + String[] projectData = { "IT Project", "Networking Project" }; + Set projects = new HashSet(); + + for (String proj : projectData) { + projects.add(new Project(proj)); + } + + for (String emp : employeeData) { + Employee employee = new Employee(emp.split(" ")[0], emp.split(" ")[1]); + assertEquals(0, employee.getProjects().size()); + employee.setProjects(projects); + session.persist(employee); + assertNotNull(employee); + } + } + + @Test + public void givenSession_whenRead_thenReturnsMtoMdata() { + @SuppressWarnings("unchecked") + List employeeList = session.createQuery("FROM Employee").list(); + assertNotNull(employeeList); + for(Employee employee : employeeList) { + assertNotNull(employee.getProjects()); + } + } + + @After + public void tearDown() { + session.getTransaction() + .commit(); + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } + +} diff --git a/persistence-modules/hibernate-many-to-many/src/test/resources/.gitignore b/persistence-modules/hibernate-many-to-many/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/persistence-modules/hibernate-many-to-many/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml b/persistence-modules/hibernate-many-to-many/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml new file mode 100644 index 0000000000..9e0109aae2 --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-many-to-many/src/test/resources/import.sql b/persistence-modules/hibernate-many-to-many/src/test/resources/import.sql new file mode 100644 index 0000000000..087d62d331 --- /dev/null +++ b/persistence-modules/hibernate-many-to-many/src/test/resources/import.sql @@ -0,0 +1,21 @@ +insert into item (item_id, item_name, item_desc, item_price) values(1,'item One', 'test 1', 35.12); + +insert into item (item_id, item_name, item_desc, item_price) values(2,'Pogo stick', 'Pogo stick', 466.12); + +insert into item (item_id, item_name, item_desc, item_price) values(3,'Raft', 'Raft', 345.12); + +insert into item (item_id, item_name, item_desc, item_price) values(4,'Skate Board', 'Skating', 135.71); + +insert into item (item_id, item_name, item_desc, item_price) values(5,'Umbrella', 'Umbrella for Rain', 619.25); + +insert into item (item_id, item_name, item_desc, item_price) values(6,'Glue', 'Glue for home', 432.73); + +insert into item (item_id, item_name, item_desc, item_price) values(7,'Paint', 'Paint for Room', 1311.40); + +insert into item (item_id, item_name, item_desc, item_price) values(8,'Red paint', 'Red paint for room', 1135.71); + +insert into item (item_id, item_name, item_desc, item_price) values(9,'Household Chairs', 'Chairs for house', 25.71); + +insert into item (item_id, item_name, item_desc, item_price) values(10,'Office Chairs', 'Chairs for office', 395.98); + +insert into item (item_id, item_name, item_desc, item_price) values(11,'Outdoor Chairs', 'Chairs for outdoor activities', 1234.36); diff --git a/persistence-modules/spring-hibernate-5/src/test/resources/manytomany.cfg.xml b/persistence-modules/hibernate-many-to-many/src/test/resources/manytomany.cfg.xml similarity index 100% rename from persistence-modules/spring-hibernate-5/src/test/resources/manytomany.cfg.xml rename to persistence-modules/hibernate-many-to-many/src/test/resources/manytomany.cfg.xml diff --git a/persistence-modules/spring-hibernate-5/README.md b/persistence-modules/spring-hibernate-5/README.md index eff59a0362..9770fe95af 100644 --- a/persistence-modules/spring-hibernate-5/README.md +++ b/persistence-modules/spring-hibernate-5/README.md @@ -4,7 +4,6 @@ This module contains articles about Hibernate 5 with Spring. ### Relevant articles -- [Hibernate Many to Many Annotation Tutorial](https://www.baeldung.com/hibernate-many-to-many) - [Programmatic Transactions in the Spring TestContext Framework](https://www.baeldung.com/spring-test-programmatic-transactions) - [JPA Criteria Queries](https://www.baeldung.com/hibernate-criteria-queries) - [Introduction to Hibernate Search](https://www.baeldung.com/hibernate-search) diff --git a/persistence-modules/spring-hibernate-5/pom.xml b/persistence-modules/spring-hibernate-5/pom.xml index d0fa23504c..bb8c4e8228 100644 --- a/persistence-modules/spring-hibernate-5/pom.xml +++ b/persistence-modules/spring-hibernate-5/pom.xml @@ -108,6 +108,26 @@ h2 ${h2.version} + + jakarta.xml.bind + jakarta.xml.bind-api + 2.3.2 + + + com.sun.xml.bind + jaxb-core + 2.3.0.1 + + + javax.xml.bind + jaxb-api + 2.3.1 + + + com.sun.xml.bind + jaxb-impl + 2.3.1 + diff --git a/persistence-modules/spring-hibernate-5/src/test/resources/import.sql b/persistence-modules/spring-hibernate-5/src/test/resources/import.sql index 087d62d331..52c800f6b4 100644 --- a/persistence-modules/spring-hibernate-5/src/test/resources/import.sql +++ b/persistence-modules/spring-hibernate-5/src/test/resources/import.sql @@ -1,3 +1,4 @@ + insert into item (item_id, item_name, item_desc, item_price) values(1,'item One', 'test 1', 35.12); insert into item (item_id, item_name, item_desc, item_price) values(2,'Pogo stick', 'Pogo stick', 466.12); From 9d191600435a8812a8ed50bcbe1cfb595dd0f148 Mon Sep 17 00:00:00 2001 From: sampadawagde Date: Tue, 22 Feb 2022 21:53:39 +0530 Subject: [PATCH 032/249] JAVA-9824: Identify boot modules not using parent-boot-2 as parent and upgrade log4j for them --- jta/pom.xml | 13 +++++++++++++ maven-modules/maven-generate-war/pom.xml | 1 + patterns/enterprise-patterns/pom.xml | 8 ++++++++ persistence-modules/spring-data-dynamodb/pom.xml | 8 ++++++++ quarkus-vs-springboot/spring-project/pom.xml | 1 + spring-5-data-reactive/pom.xml | 13 +++++++++++++ spring-activiti/pom.xml | 13 +++++++++++++ spring-boot-modules/spring-boot-2/pom.xml | 2 +- .../spring-boot-logging-log4j2/pom.xml | 1 + spring-boot-modules/spring-boot-mvc-birt/pom.xml | 1 + spring-boot-modules/spring-boot-react/pom.xml | 13 +++++++++++++ .../spring-boot-swagger-keycloak/pom.xml | 8 ++++++++ spring-boot-modules/spring-boot-testing/pom.xml | 13 +++++++++++++ spring-cloud/spring-cloud-contract/pom.xml | 8 ++++++++ .../spring-cloud-eureka-self-preservation/pom.xml | 13 +++++++++++++ spring-cloud/spring-cloud-eureka/pom.xml | 13 +++++++++++++ spring-cloud/spring-cloud-load-balancer/pom.xml | 13 +++++++++++++ .../twitterhdfs/pom.xml | 1 + .../eureka-client/pom.xml | 11 +++++++++++ .../eureka-server/pom.xml | 11 +++++++++++ .../zuul-server/pom.xml | 11 +++++++++++ .../spring-zuul-rate-limiting/pom.xml | 13 +++++++++++++ spring-di-2/pom.xml | 8 ++++++++ spring-di-3/pom.xml | 8 ++++++++ spring-native/pom.xml | 1 + spring-roo/pom.xml | 1 + .../spring-5-security-oauth/pom.xml | 14 ++++++++++++++ .../spring-security-legacy-oidc/pom.xml | 13 +++++++++++++ .../custom-validations-opeanpi-codegen/pom.xml | 1 + spring-web-modules/spring-boot-jsp/pom.xml | 8 ++++++++ 30 files changed, 242 insertions(+), 1 deletion(-) diff --git a/jta/pom.xml b/jta/pom.xml index e9f9364646..e62c480c81 100644 --- a/jta/pom.xml +++ b/jta/pom.xml @@ -15,6 +15,18 @@ 0.0.1-SNAPSHOT ../parent-boot-2 + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + @@ -37,6 +49,7 @@ 2.4.7 + 2.17.1 \ No newline at end of file diff --git a/maven-modules/maven-generate-war/pom.xml b/maven-modules/maven-generate-war/pom.xml index 56256f58ea..b388cfdadd 100644 --- a/maven-modules/maven-generate-war/pom.xml +++ b/maven-modules/maven-generate-war/pom.xml @@ -63,6 +63,7 @@ 11 + 2.17.1 \ No newline at end of file diff --git a/patterns/enterprise-patterns/pom.xml b/patterns/enterprise-patterns/pom.xml index 10c07d6d05..999b359170 100644 --- a/patterns/enterprise-patterns/pom.xml +++ b/patterns/enterprise-patterns/pom.xml @@ -48,6 +48,13 @@ pom import + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + @@ -63,6 +70,7 @@ 3.7.4 2.2.2.RELEASE + 2.17.1 \ No newline at end of file diff --git a/persistence-modules/spring-data-dynamodb/pom.xml b/persistence-modules/spring-data-dynamodb/pom.xml index 148215b68a..0e990c69f3 100644 --- a/persistence-modules/spring-data-dynamodb/pom.xml +++ b/persistence-modules/spring-data-dynamodb/pom.xml @@ -24,6 +24,13 @@ pom import + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + @@ -184,6 +191,7 @@ https://s3-us-west-2.amazonaws.com/dynamodb-local/release 3.1.1 2.4.7 + 2.17.1 \ No newline at end of file diff --git a/quarkus-vs-springboot/spring-project/pom.xml b/quarkus-vs-springboot/spring-project/pom.xml index bf524cd550..7f0fa4c8c6 100644 --- a/quarkus-vs-springboot/spring-project/pom.xml +++ b/quarkus-vs-springboot/spring-project/pom.xml @@ -187,6 +187,7 @@ 11 0.11.0-RC1 + 2.17.1 \ No newline at end of file diff --git a/spring-5-data-reactive/pom.xml b/spring-5-data-reactive/pom.xml index c145992737..023eda856b 100644 --- a/spring-5-data-reactive/pom.xml +++ b/spring-5-data-reactive/pom.xml @@ -13,6 +13,18 @@ 0.0.1-SNAPSHOT ../parent-boot-2 + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + @@ -138,6 +150,7 @@ 3.3.1.RELEASE 2.2.6.RELEASE + 2.17.1 \ No newline at end of file diff --git a/spring-activiti/pom.xml b/spring-activiti/pom.xml index c685207cc4..2ede13a152 100644 --- a/spring-activiti/pom.xml +++ b/spring-activiti/pom.xml @@ -16,6 +16,18 @@ 0.0.1-SNAPSHOT ../parent-boot-1 + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + @@ -59,6 +71,7 @@ 6.0.0 + 2.17.1 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-2/pom.xml b/spring-boot-modules/spring-boot-2/pom.xml index 08dc517fa0..0da07eaf00 100644 --- a/spring-boot-modules/spring-boot-2/pom.xml +++ b/spring-boot-modules/spring-boot-2/pom.xml @@ -62,7 +62,7 @@ - 2.14.1 + 2.17.1 5.3.15 11 11 diff --git a/spring-boot-modules/spring-boot-logging-log4j2/pom.xml b/spring-boot-modules/spring-boot-logging-log4j2/pom.xml index 8cf052deb3..036df19887 100644 --- a/spring-boot-modules/spring-boot-logging-log4j2/pom.xml +++ b/spring-boot-modules/spring-boot-logging-log4j2/pom.xml @@ -102,6 +102,7 @@ 4.13.2 5.8.1 + 2.17.1 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc-birt/pom.xml b/spring-boot-modules/spring-boot-mvc-birt/pom.xml index 16b07000f8..8f1c770bbe 100644 --- a/spring-boot-modules/spring-boot-mvc-birt/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-birt/pom.xml @@ -70,6 +70,7 @@ 1.8 4.8.0 1.2.17 + 2.17.1 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-react/pom.xml b/spring-boot-modules/spring-boot-react/pom.xml index d515aed6ce..dc0c6914c9 100644 --- a/spring-boot-modules/spring-boot-react/pom.xml +++ b/spring-boot-modules/spring-boot-react/pom.xml @@ -11,6 +11,18 @@ 1.0.0-SNAPSHOT + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + + org.springframework.boot @@ -128,6 +140,7 @@ v1.12.1 2.4.4 1.0.2 + 2.17.1 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml b/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml index 82e1951b8e..a7f3e01014 100644 --- a/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml +++ b/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml @@ -24,6 +24,13 @@ pom import + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + @@ -62,6 +69,7 @@ 2.4.5 3.0.0 15.0.2 + 2.17.1 diff --git a/spring-boot-modules/spring-boot-testing/pom.xml b/spring-boot-modules/spring-boot-testing/pom.xml index 658eb7728e..fcfc2364ba 100644 --- a/spring-boot-modules/spring-boot-testing/pom.xml +++ b/spring-boot-modules/spring-boot-testing/pom.xml @@ -14,6 +14,18 @@ 1.0.0-SNAPSHOT + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + + org.springframework.boot @@ -131,6 +143,7 @@ 1.6 0.7.2 2.5.0 + 2.17.1 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-contract/pom.xml b/spring-cloud/spring-cloud-contract/pom.xml index 8546e76586..6e8b130ed1 100644 --- a/spring-cloud/spring-cloud-contract/pom.xml +++ b/spring-cloud/spring-cloud-contract/pom.xml @@ -21,6 +21,13 @@ + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.boot spring-boot-starter-web @@ -55,6 +62,7 @@ 2.1.1.RELEASE 2.1.4.RELEASE + 2.17.1 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-eureka-self-preservation/pom.xml b/spring-cloud/spring-cloud-eureka-self-preservation/pom.xml index 0b7da2ce4a..e22ad6b7c9 100644 --- a/spring-cloud/spring-cloud-eureka-self-preservation/pom.xml +++ b/spring-cloud/spring-cloud-eureka-self-preservation/pom.xml @@ -14,6 +14,18 @@ spring-cloud 1.0.0-SNAPSHOT + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + spring-cloud-eureka-server @@ -32,6 +44,7 @@ 2.1.3.RELEASE Greenwich.SR3 + 2.17.1 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-eureka/pom.xml b/spring-cloud/spring-cloud-eureka/pom.xml index e5327d4530..795eab7d6e 100644 --- a/spring-cloud/spring-cloud-eureka/pom.xml +++ b/spring-cloud/spring-cloud-eureka/pom.xml @@ -14,6 +14,18 @@ spring-cloud 1.0.0-SNAPSHOT + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + spring-cloud-eureka-server @@ -34,6 +46,7 @@ 2.1.2.RELEASE Greenwich.RELEASE + 2.17.1 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-load-balancer/pom.xml b/spring-cloud/spring-cloud-load-balancer/pom.xml index 9c650565ed..65cf83de09 100644 --- a/spring-cloud/spring-cloud-load-balancer/pom.xml +++ b/spring-cloud/spring-cloud-load-balancer/pom.xml @@ -19,6 +19,18 @@ spring-cloud-loadbalancer-server spring-cloud-loadbalancer-client + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + @@ -32,6 +44,7 @@ 2.6.1 2021.0.0 + 2.17.1 diff --git a/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml index 1c8fa4e694..73d6e62d37 100644 --- a/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml +++ b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml @@ -78,6 +78,7 @@ 4.13.2 5.8.1 + 2.17.1 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml index 3514924198..b2cb66744b 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml @@ -17,6 +17,13 @@ + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.cloud spring-cloud-starter-parent @@ -45,5 +52,9 @@ test + + + 2.17.1 + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml index dcd912df07..466291650c 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml @@ -17,6 +17,13 @@ + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.cloud spring-cloud-starter-parent @@ -45,5 +52,9 @@ test + + + 2.17.1 + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml index bb38ec1351..27afc3eb69 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml @@ -14,6 +14,13 @@ + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.cloud spring-cloud-starter-parent @@ -53,5 +60,9 @@ test + + + 2.17.1 + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml index 2969b5eed9..4727859ea2 100644 --- a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml @@ -13,6 +13,18 @@ spring-cloud-zuul 0.0.1-SNAPSHOT + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + @@ -44,6 +56,7 @@ 2.2.0.RELEASE 2.4.7 2020.0.4 + 2.17.1 \ No newline at end of file diff --git a/spring-di-2/pom.xml b/spring-di-2/pom.xml index d3be846424..1207506d17 100644 --- a/spring-di-2/pom.xml +++ b/spring-di-2/pom.xml @@ -16,6 +16,13 @@ + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.boot spring-boot-dependencies @@ -80,6 +87,7 @@ 2.6.1 1.11 1 + 2.17.1 \ No newline at end of file diff --git a/spring-di-3/pom.xml b/spring-di-3/pom.xml index 0d4bbd01af..c6a2687606 100644 --- a/spring-di-3/pom.xml +++ b/spring-di-3/pom.xml @@ -16,6 +16,13 @@ + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.boot spring-boot-dependencies @@ -40,6 +47,7 @@ 2.6.1 + 2.17.1 \ No newline at end of file diff --git a/spring-native/pom.xml b/spring-native/pom.xml index 4455e050f2..f54d7b5308 100644 --- a/spring-native/pom.xml +++ b/spring-native/pom.xml @@ -75,6 +75,7 @@ 1.8 1.8 1.8 + 2.17.1 \ No newline at end of file diff --git a/spring-roo/pom.xml b/spring-roo/pom.xml index b55a334256..ea42095d92 100644 --- a/spring-roo/pom.xml +++ b/spring-roo/pom.xml @@ -625,6 +625,7 @@ 1.0.3 2.0.0.RELEASE 1.2.0 + 2.17.1 \ No newline at end of file diff --git a/spring-security-modules/spring-5-security-oauth/pom.xml b/spring-security-modules/spring-5-security-oauth/pom.xml index aa4958ae47..706cdb3082 100644 --- a/spring-security-modules/spring-5-security-oauth/pom.xml +++ b/spring-security-modules/spring-5-security-oauth/pom.xml @@ -15,6 +15,19 @@ 0.0.1-SNAPSHOT ../../parent-boot-2 + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + + @@ -72,6 +85,7 @@ is available --> 2.5.2 com.baeldung.oauth2.SpringOAuthApplication + 2.17.1 \ No newline at end of file diff --git a/spring-security-modules/spring-security-legacy-oidc/pom.xml b/spring-security-modules/spring-security-legacy-oidc/pom.xml index ca54a6765d..9dd898f9dd 100644 --- a/spring-security-modules/spring-security-legacy-oidc/pom.xml +++ b/spring-security-modules/spring-security-legacy-oidc/pom.xml @@ -14,6 +14,18 @@ 0.0.1-SNAPSHOT ../../parent-boot-2 + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + @@ -50,6 +62,7 @@ 1.0.9.RELEASE 0.3.0 2.4.7 + 2.17.1 \ No newline at end of file diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml index 336cb0da74..9add9ae494 100644 --- a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml @@ -100,6 +100,7 @@ 11 3.0.0 + 2.17.1 \ No newline at end of file diff --git a/spring-web-modules/spring-boot-jsp/pom.xml b/spring-web-modules/spring-boot-jsp/pom.xml index b9b4a97e6b..d2a363bafa 100644 --- a/spring-web-modules/spring-boot-jsp/pom.xml +++ b/spring-web-modules/spring-boot-jsp/pom.xml @@ -23,6 +23,13 @@ pom import + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.boot spring-boot-dependencies @@ -92,6 +99,7 @@ 1.2 2.4.4 + 2.17.1 \ No newline at end of file From b07644ee70a6828ce272434e4a5ab2ef5a9db9b7 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Tue, 22 Feb 2022 15:39:23 -0300 Subject: [PATCH 033/249] adding javax-servlets-2 to the parent pom. --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index f5378f9961..ea2177c4d8 100644 --- a/pom.xml +++ b/pom.xml @@ -943,6 +943,7 @@ java-vavr-stream java-websocket javax-servlets + javax-servlets-2 javaxval jaxb jee-7 From b6db99e3a157296796c853cdf5546d89241bfb1e Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Tue, 22 Feb 2022 15:43:49 -0300 Subject: [PATCH 034/249] adding module javax-servlets-2 to all profiles --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ea2177c4d8..f3d16366bd 100644 --- a/pom.xml +++ b/pom.xml @@ -459,6 +459,7 @@ java-vavr-stream java-websocket javax-servlets + javax-servlets-2 javaxval jaxb jee-7 @@ -943,7 +944,7 @@ java-vavr-stream java-websocket javax-servlets - javax-servlets-2 + javax-servlets-2 javaxval jaxb jee-7 From 32813cbc3e8d61a542e36d02168f0c182b534d87 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:01:47 +0800 Subject: [PATCH 035/249] Update README.md --- core-java-modules/core-java-security-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-security-3/README.md b/core-java-modules/core-java-security-3/README.md index 31969cd270..9d82e829e2 100644 --- a/core-java-modules/core-java-security-3/README.md +++ b/core-java-modules/core-java-security-3/README.md @@ -10,4 +10,5 @@ This module contains articles about core Java Security - [HMAC in Java](https://www.baeldung.com/java-hmac) - [Generating a Secure AES Key in Java](https://www.baeldung.com/java-secure-aes-key) - [Computing an X509 Certificate’s Thumbprint in Java](https://www.baeldung.com/java-x509-certificate-thumbprint) +- [Error: “trustAnchors parameter must be non-empty”](https://www.baeldung.com/java-trustanchors-parameter-must-be-non-empty) - More articles: [[<-- prev]](/core-java-modules/core-java-security-2) From 07cd27a9b29b2601383170a542089f16b5555737 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:03:19 +0800 Subject: [PATCH 036/249] Create README.md --- gradle/gradle-source-vs-target-compatibility/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 gradle/gradle-source-vs-target-compatibility/README.md diff --git a/gradle/gradle-source-vs-target-compatibility/README.md b/gradle/gradle-source-vs-target-compatibility/README.md new file mode 100644 index 0000000000..cc3157fde3 --- /dev/null +++ b/gradle/gradle-source-vs-target-compatibility/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Gradle: sourceCompatiblity vs targetCompatibility](https://www.baeldung.com/gradle-sourcecompatiblity-vs-targetcompatibility) From 3b0151e731fd53fd26f80a6dbb68de7ba2142693 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:09:35 +0800 Subject: [PATCH 037/249] Update README.md --- spring-cloud/spring-cloud-openfeign/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-cloud/spring-cloud-openfeign/README.md b/spring-cloud/spring-cloud-openfeign/README.md index 5d3dc060c7..44f4d15b16 100644 --- a/spring-cloud/spring-cloud-openfeign/README.md +++ b/spring-cloud/spring-cloud-openfeign/README.md @@ -4,3 +4,4 @@ - [Differences Between Netflix Feign and OpenFeign](https://www.baeldung.com/netflix-feign-vs-openfeign) - [File Upload With Open Feign](https://www.baeldung.com/java-feign-file-upload) - [Feign Logging Configuration](https://www.baeldung.com/java-feign-logging) +- [Provide an OAuth2 Token to a Feign Client](https://www.baeldung.com/spring-cloud-feign-oauth-token) From 2ef9f3c02672464c8aa7e9126691da4f567dea6f Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:16:19 +0800 Subject: [PATCH 038/249] Update README.md --- spring-di-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-di-3/README.md b/spring-di-3/README.md index 9ab7789f37..4246069616 100644 --- a/spring-di-3/README.md +++ b/spring-di-3/README.md @@ -5,4 +5,5 @@ This module contains articles about dependency injection with Spring ### Relevant Articles - [@Lookup Annotation in Spring](https://www.baeldung.com/spring-lookup) +- [Spring @Autowired Field Null – Common Causes and Solutions](https://www.baeldung.com/spring-autowired-field-null) - More articles: [[<-- prev]](../spring-di-2) From ca061932b3496b239fe19f7822da0162d7910c3c Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:18:05 +0800 Subject: [PATCH 039/249] Update README.md --- spring-boot-modules/spring-boot-swagger/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-swagger/README.md b/spring-boot-modules/spring-boot-swagger/README.md index 174bfe626d..a09df23a80 100644 --- a/spring-boot-modules/spring-boot-swagger/README.md +++ b/spring-boot-modules/spring-boot-swagger/README.md @@ -5,3 +5,4 @@ - [Generate PDF from Swagger API Documentation](https://www.baeldung.com/swagger-generate-pdf) - [Remove Basic Error Controller In SpringFox Swagger-UI](https://www.baeldung.com/spring-swagger-remove-error-controller) - [Setting Example and Description with Swagger](https://www.baeldung.com/swagger-set-example-description) +- [Document Enum in Swagger](https://www.baeldung.com/swagger-enum) From b113c42902efcca7f8a1bc748d97d830ee99858e Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:19:46 +0800 Subject: [PATCH 040/249] Update README.md --- java-native/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/java-native/README.md b/java-native/README.md index 4f85342a38..2aa02c03d5 100644 --- a/java-native/README.md +++ b/java-native/README.md @@ -7,3 +7,4 @@ This module contains articles about the Java Native Interface (JNI). - [Guide to JNI (Java Native Interface)](https://www.baeldung.com/jni) - [Using JNA to Access Native Dynamic Libraries](https://www.baeldung.com/java-jna-dynamic-libraries) - [Check if a Java Program Is Running in 64-Bit or 32-Bit JVM](https://www.baeldung.com/java-detect-jvm-64-or-32-bit) +- [How to use JNI’s RegisterNatives() method?](https://www.baeldung.com/jni-registernatives) From 9fd7fb2c0f955d8f58e383931f071a2928eeb15d Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:45:17 +0800 Subject: [PATCH 041/249] Update README.md --- persistence-modules/hibernate-queries/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/persistence-modules/hibernate-queries/README.md b/persistence-modules/hibernate-queries/README.md index 61d94e32de..58ca74cd24 100644 --- a/persistence-modules/hibernate-queries/README.md +++ b/persistence-modules/hibernate-queries/README.md @@ -7,4 +7,5 @@ This module contains articles about use of Queries in Hibernate. - [Criteria Queries Using JPA Metamodel](https://www.baeldung.com/hibernate-criteria-queries-metamodel) - [Get All Data from a Table with Hibernate](https://www.baeldung.com/hibernate-select-all) - [Hibernate Named Query](https://www.baeldung.com/hibernate-named-query) -- [Hibernate Query Plan Cache](https://www.baeldung.com/hibernate-query-plan-cache) \ No newline at end of file +- [Hibernate Query Plan Cache](https://www.baeldung.com/hibernate-query-plan-cache) +- [Hibernate’s addScalar() Method](https://www.baeldung.com/hibernate-addscalar) From 5c33e8c30ca8afc72f004041d25d37227b52d5d7 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:46:49 +0800 Subject: [PATCH 042/249] Update README.md --- spring-boot-modules/spring-boot-security/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-security/README.md b/spring-boot-modules/spring-boot-security/README.md index b9966709cb..d848f798ba 100644 --- a/spring-boot-modules/spring-boot-security/README.md +++ b/spring-boot-modules/spring-boot-security/README.md @@ -10,6 +10,7 @@ This module contains articles about Spring Boot Security - [Guide to @CurrentSecurityContext in Spring Security](https://www.baeldung.com/spring-currentsecuritycontext) - [Disable Security for a Profile in Spring Boot](https://www.baeldung.com/spring-security-disable-profile) - [Spring @EnableWebSecurity vs. @EnableGlobalMethodSecurity](https://www.baeldung.com/spring-enablewebsecurity-vs-enableglobalmethodsecurity) +- [Spring Security – Configuring Different URLs](https://www.baeldung.com/spring-security-configuring-urls) ### Spring Boot Security Auto-Configuration From cf98dad5db819aee692d575a44eb95e1d70ad5b2 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:51:34 +0800 Subject: [PATCH 043/249] Update README.md --- core-java-modules/core-java-collections-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-4/README.md b/core-java-modules/core-java-collections-4/README.md index 0e14f407c4..cbca44d372 100644 --- a/core-java-modules/core-java-collections-4/README.md +++ b/core-java-modules/core-java-collections-4/README.md @@ -7,3 +7,4 @@ - [ArrayList vs. LinkedList vs. HashMap in Java](https://www.baeldung.com/java-arraylist-vs-linkedlist-vs-hashmap) - [Java Deque vs. Stack](https://www.baeldung.com/java-deque-vs-stack) - [Collection.toArray(new T[0]) or .toArray(new T[size])](https://www.baeldung.com/java-collection-toarray-methods) +- [Create an Empty Map in Java](https://www.baeldung.com/java-create-empty-map) From 9011fdc4f5be943d447878765c7ff3e47e69e190 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:52:51 +0800 Subject: [PATCH 044/249] Update README.md --- core-java-modules/core-java-8-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-8-2/README.md b/core-java-modules/core-java-8-2/README.md index 7f2245ccc0..12a060ccfe 100644 --- a/core-java-modules/core-java-8-2/README.md +++ b/core-java-modules/core-java-8-2/README.md @@ -8,4 +8,5 @@ This module contains articles about Java 8 core features - [Java 8 Stream skip() vs limit()](https://www.baeldung.com/java-stream-skip-vs-limit) - [Guide to Java BiFunction Interface](https://www.baeldung.com/java-bifunction-interface) - [Interface With Default Methods vs Abstract Class](https://www.baeldung.com/java-interface-default-method-vs-abstract-class) +- [Convert Between Byte Array and UUID in Java](https://www.baeldung.com/java-byte-array-to-uuid) - [[<-- Prev]](/core-java-modules/core-java-8) From 7e6df12a3fa70c15950163949cef1b019986d1c8 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:54:30 +0800 Subject: [PATCH 045/249] Update README.md --- docker/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/README.md b/docker/README.md index 0de3694215..0adf1c9b51 100644 --- a/docker/README.md +++ b/docker/README.md @@ -6,3 +6,4 @@ - [How To Configure Java Heap Size Inside a Docker Container](https://www.baeldung.com/ops/docker-jvm-heap-size) - [Dockerfile Strategies for Git](https://www.baeldung.com/ops/dockerfile-git-strategies) - [How to Get Docker-Compose to Always Use the Latest Image](https://www.baeldung.com/ops/docker-compose-latest-image) +- [How to Include Files Outside of Docker’s Build Context](https://www.baeldung.com/ops/docker-include-files-outside-build-context) From 9c5f0cdaf0c875f455a3489fc868e9e111d49980 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:56:08 +0800 Subject: [PATCH 046/249] Update README.md --- spring-boot-modules/spring-boot-libraries-comparison/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-modules/spring-boot-libraries-comparison/README.md b/spring-boot-modules/spring-boot-libraries-comparison/README.md index 3efdac2a4c..d373f91b3b 100644 --- a/spring-boot-modules/spring-boot-libraries-comparison/README.md +++ b/spring-boot-modules/spring-boot-libraries-comparison/README.md @@ -4,4 +4,4 @@ This module contains articles about various Spring Boot libraries Comparison ### Relevant Articles: -- [GraphQL vs REST](https://www.baeldung.com/graphql-vs-rest/) \ No newline at end of file +- [GraphQL vs REST](https://www.baeldung.com/graphql-vs-rest) From e2abcfc461dcf97e65b11fce40ba8c4dac2404ae Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:58:10 +0800 Subject: [PATCH 047/249] Update README.md --- java-collections-maps-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/java-collections-maps-3/README.md b/java-collections-maps-3/README.md index 75842c85a4..e2e0a56489 100644 --- a/java-collections-maps-3/README.md +++ b/java-collections-maps-3/README.md @@ -7,3 +7,4 @@ - [Update the Value Associated With a Key in a HashMap](https://www.baeldung.com/java-hashmap-update-value-by-key) - [Java Map – keySet() vs. entrySet() vs. values() Methods](https://www.baeldung.com/java-map-entries-methods) - [Java IdentityHashMap Class and Its Use Cases](https://www.baeldung.com/java-identityhashmap) +- [How to Invert a Map in Java](https://www.baeldung.com/java-invert-map) From bb7b461a495e8dae1ca592510d4d1670d1a4a1bd Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Wed, 23 Feb 2022 19:54:43 +0530 Subject: [PATCH 048/249] JAVA-10081: Removed unused files and updated pom.xml --- .../hibernate-many-to-many/README.md | 7 -- .../_2.fdt | Bin 160 -> 0 bytes .../_2.fdx | Bin 84 -> 0 bytes .../_2.fnm | Bin 532 -> 0 bytes .../_2.nvd | Bin 65 -> 0 bytes .../_2.nvm | Bin 88 -> 0 bytes .../_2.si | Bin 514 -> 0 bytes .../_2.tvd | Bin 392 -> 0 bytes .../_2.tvx | Bin 79 -> 0 bytes .../_2_Lucene50_0.doc | Bin 190 -> 0 bytes .../_2_Lucene50_0.pos | Bin 162 -> 0 bytes .../_2_Lucene50_0.tim | Bin 914 -> 0 bytes .../_2_Lucene50_0.tip | Bin 195 -> 0 bytes .../_3.cfe | Bin 341 -> 0 bytes .../_3.cfs | Bin 2119 -> 0 bytes .../_3.si | Bin 371 -> 0 bytes .../segments_5 | Bin 198 -> 0 bytes .../write.lock | 0 .../manytomany/dao/IEmployeeDao.java | 8 -- .../manytomany/dao/IProjectDao.java | 8 -- .../baeldung/spring/PersistenceConfig.java | 75 ------------------ .../src/main/resources/import.sql | 31 -------- .../src/main/resources/manytomany.cfg.xml | 15 ---- .../main/resources/persistence-h2.properties | 21 ----- .../src/test/resources/.gitignore | 13 --- .../hibernate/criteria/model/Item.hbm.xml | 22 ----- .../src/test/resources/import.sql | 21 ----- .../.gitignore | 0 .../hibernate-mapping-2/README.md | 7 ++ .../pom.xml | 66 ++------------- .../manytomany}/PersistenceConfig.java | 8 +- .../baeldung/manytomany/dao/IEmployeeDao.java | 8 ++ .../baeldung/manytomany/dao/IProjectDao.java | 8 ++ .../manytomany}/dao/common/AbstractDao.java | 2 +- .../dao/common/AbstractHibernateDao.java | 2 +- .../manytomany}/dao/common/IOperations.java | 2 +- .../manytomany/dao/impl/EmployeeDao.java | 9 ++- .../manytomany/dao/impl/ProjectDao.java | 9 ++- .../baeldung}/manytomany/model/Employee.java | 2 +- .../baeldung}/manytomany/model/Project.java | 3 +- .../manytomany/util/HibernateUtil.java | 7 +- .../src/main/resources/logback.xml | 0 .../main/resources/persistence-h2.properties | 11 +++ .../java/com/baeldung/SpringContextTest.java | 3 +- ...notationJavaConfigMainIntegrationTest.java | 7 +- ...nyToManyAnnotationMainIntegrationTest.java | 10 ++- .../src/test/resources/manytomany.cfg.xml | 2 +- 47 files changed, 79 insertions(+), 308 deletions(-) delete mode 100644 persistence-modules/hibernate-many-to-many/README.md delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fdt delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fdx delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fnm delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.nvd delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.nvm delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.si delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.tvd delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.tvx delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2_Lucene50_0.doc delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2_Lucene50_0.pos delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2_Lucene50_0.tim delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2_Lucene50_0.tip delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.cfe delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.cfs delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.si delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/segments_5 delete mode 100644 persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/write.lock delete mode 100644 persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java delete mode 100644 persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java delete mode 100644 persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/spring/PersistenceConfig.java delete mode 100644 persistence-modules/hibernate-many-to-many/src/main/resources/import.sql delete mode 100644 persistence-modules/hibernate-many-to-many/src/main/resources/manytomany.cfg.xml delete mode 100644 persistence-modules/hibernate-many-to-many/src/main/resources/persistence-h2.properties delete mode 100644 persistence-modules/hibernate-many-to-many/src/test/resources/.gitignore delete mode 100644 persistence-modules/hibernate-many-to-many/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml delete mode 100644 persistence-modules/hibernate-many-to-many/src/test/resources/import.sql rename persistence-modules/{hibernate-many-to-many => hibernate-mapping-2}/.gitignore (100%) create mode 100644 persistence-modules/hibernate-mapping-2/README.md rename persistence-modules/{hibernate-many-to-many => hibernate-mapping-2}/pom.xml (54%) rename persistence-modules/{hibernate-many-to-many/src/main/java/com/baeldung/manytomany/spring => hibernate-mapping-2/src/main/java/com/baeldung/manytomany}/PersistenceConfig.java (95%) create mode 100644 persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IEmployeeDao.java create mode 100644 persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IProjectDao.java rename persistence-modules/{hibernate-many-to-many/src/main/java/com/baeldung/persistence => hibernate-mapping-2/src/main/java/com/baeldung/manytomany}/dao/common/AbstractDao.java (87%) rename persistence-modules/{hibernate-many-to-many/src/main/java/com/baeldung/persistence => hibernate-mapping-2/src/main/java/com/baeldung/manytomany}/dao/common/AbstractHibernateDao.java (96%) rename persistence-modules/{hibernate-many-to-many/src/main/java/com/baeldung/persistence => hibernate-mapping-2/src/main/java/com/baeldung/manytomany}/dao/common/IOperations.java (87%) rename persistence-modules/{hibernate-many-to-many/src/main/java/com/baeldung/persistence => hibernate-mapping-2/src/main/java/com/baeldung}/manytomany/dao/impl/EmployeeDao.java (50%) rename persistence-modules/{hibernate-many-to-many/src/main/java/com/baeldung/persistence => hibernate-mapping-2/src/main/java/com/baeldung}/manytomany/dao/impl/ProjectDao.java (50%) rename persistence-modules/{hibernate-many-to-many/src/main/java/com/baeldung/hibernate => hibernate-mapping-2/src/main/java/com/baeldung}/manytomany/model/Employee.java (97%) rename persistence-modules/{hibernate-many-to-many/src/main/java/com/baeldung/hibernate => hibernate-mapping-2/src/main/java/com/baeldung}/manytomany/model/Project.java (96%) rename persistence-modules/{hibernate-many-to-many/src/main/java/com/baeldung/hibernate => hibernate-mapping-2/src/main/java/com/baeldung}/manytomany/util/HibernateUtil.java (90%) rename persistence-modules/{hibernate-many-to-many => hibernate-mapping-2}/src/main/resources/logback.xml (100%) create mode 100644 persistence-modules/hibernate-mapping-2/src/main/resources/persistence-h2.properties rename persistence-modules/{hibernate-many-to-many => hibernate-mapping-2}/src/test/java/com/baeldung/SpringContextTest.java (91%) rename persistence-modules/{hibernate-many-to-many => hibernate-mapping-2}/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java (89%) rename persistence-modules/{hibernate-many-to-many => hibernate-mapping-2}/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java (92%) rename persistence-modules/{hibernate-many-to-many => hibernate-mapping-2}/src/test/resources/manytomany.cfg.xml (97%) diff --git a/persistence-modules/hibernate-many-to-many/README.md b/persistence-modules/hibernate-many-to-many/README.md deleted file mode 100644 index 19b865d4e1..0000000000 --- a/persistence-modules/hibernate-many-to-many/README.md +++ /dev/null @@ -1,7 +0,0 @@ -## Hibernate 5 with Spring - -This module contains articles about Hibernate 5 with Spring. - -### Relevant articles - -- [Hibernate Many to Many Annotation Tutorial](https://www.baeldung.com/hibernate-many-to-many) \ No newline at end of file diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fdt b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fdt deleted file mode 100644 index d71a08150212e0d18327d1491c3687976b1c0d38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmcD&o+B>fQ<|KbmuhMdT#{dun&Ot3nv+uOmRMZkl30?+z`($mbzSAP`{iOo;d#DB z{fW~w7#bQFnHYE&m>Bf`D==s!=jZArB?2{-=B4XpWG1B+d6=BK3Q y=miwzr<5j_a4;I`Gf2xDfe2#|VFDsd^%=wiK$2#Rj0ZF(zW`bZ2Af23UjYC|kS^)~ diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fdx b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fdx deleted file mode 100644 index 72359255c620cb440b643215ce0e4a85f205da77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmcD&o+B>nQ<|KbmuhMdT#{dun&Ot3nv+uOmRMZknU|7U!N9=4m~~y{wfp5_L*aS8 hM*WG?G#Ho|fuamnK+Mp`ctB(F3!o}62&>U62LPU67+U}U diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fnm b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.fnm deleted file mode 100644 index b0143e1ac5e967810feee7771557bca5f71a4922..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 532 zcmcD&o+B>gQ<|KbmuhO@mYJH9;+dD0U(CS3z?gMi<+c0eVngA1zDE6t(=-@Z1>!R@ zlTwTF5=&C!lXDV_iy4@h8U8~7lWah05!i%){Nj?#y!2wX{G!~%61_Aq#R0Pfm$Ks0 zw6x3$MgykI6h;~t%Uw{EpHiA!;+L44%EU;0XLF~d7AF^F7L;V>=P}d3e74-w-29?S W7A8ijhxh@F$uEEr4hGV{B@6-GbkQ<|KbmuhP4mtT}y?2=fL$N&Uc*HvD-UoJKjp66@SpEyl}p`^5=qP+Zo P#^e_uX%J`#I_?Dk?LHOl diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.nvm b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.nvm deleted file mode 100644 index 19f60a39bcf9a121ca3bc1590ba6df45481bf44a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88 zcmcD&o+B>mQ<|KbmuhP4mtT}y?3-GWn37nM$N&Uc*HvD-UoJKjp66@SpEyl}fe9oE b0_Dt%5C((xe<0vLpfULcRDfZE({vpGz#bVo diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.si b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.si deleted file mode 100644 index 3d537083b422c76bfcef3c42fb25ad1eeb45bf4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 514 zcmZWm-AcnS7+u9~xJ_kF@X}p)F_49(cGKM`sGA6z3LSV^LX*u()08Bwdy8ENUivJ) zgBN=R!3XeC(?5_cA^AAx`_AEzTrB;A<|uMWK)QxaW|Rc-Hkh(fsiZwGkG^j{1#G^L z%>{aEE3TyfJLTW{1{2jsFTm_Yw4hOYMlk|0QJC-DbL9G@b;WqdIFcR<>Uoeh~}|{1}jVe#N8(yQQWik zQ)?at(xar1ultt;i?~bl)UlS{L*z=vHCR=Cd9F=p0Ank05)#pH8}_U&JhRM`Qv+J{ zvSWfE#=0uPOMr}VQl?mDXx?y4r+8<_03j2ZhNfddR`BW=X6}kmC0JuZ?Xa-6Rc?ZZ k9`UglGER{Mlwnf69M}`bei#g{KiaQf$xkNh=X|#K1BMr#*8l(j diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.tvd b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2.tvd deleted file mode 100644 index b46c8d109cc2a907cd84fbbf6e87ad51cff7929d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 392 zcmW-dze`(D6vxlgC=Ftbkz&VE+Y%kb7xR(~f;J6xskBJ7;&$@h$$eMukH@|D5#1c@ zY@rZ05n3p562ZMwXQ6|CK$p@kP90qA)dSxH-w)?}hwt*0n4W%<$D}A)cuz)dQtY&` zZFC3#!OqpQzpFoOICZ>MJ;Z(mhW4MpC=5S6J3Rp?TztHUHa12|C4al(ec7uGFuV`N zwtdxl{be0L)M|6li$@3D#^4}aXWR8M+x#~3{HS=hKLx>c1%=gFCMeF0A>~LVU5v?S znR1r$L}+IvNp1G5MB}nlE2>6yT!fHycnKzVAHu{-D2z5B46Dsq7;C_JiiUB;x<2JC z{0js+vW_b<#BzbA1vkY!%e3)~^|&EH*1D7{AFu^KP$fq5gc(A&1lJEdWhiiWuVWi1 zZLV0H5@vs(@86~Fa6$8MJKp0e(LK9Ztw#&2BXY@6^4MsryRHdSk84eMcW;8=d*$dQ<|KbmuhMdl3J7-mYQ6WUsUXwmy%k+z`($mbzSAP`{iOo;d#DB{fW~w c7?>D=q6{WL%lQ<|KbmuhMdkY8MqnU`K1UX)pqTI7lQ<|KbmuhMdkY8MqnU`K1UX)pqS_I@V072GumDlcM>D0O1m)+6Xon>a0yL6Ju zPB5UIt(}E`f&YVGdMiQjZ}81-E~Sw9*!Mke-tWy$&h(9yN7^KB4lKX{*up(gi6?}x z*JpSCJpJLeS3f@=zLy_2d(Y|wN*E1Z4#)(+SyRNB1?i()WjRx+P*rY95IW@bkya%{+IS}l zD2zQ8g_$Z19Sd2lrR}*wTHi$UTwPVhhN?R=Ri|!pY zU}+~qDjJ_4PtwPPQ1s#)4eVlYj=Dxd(kyhtg(^aYXnj$PsFP(_UTSb9ySE;6O@d^d4#s+OQVVr!snE98D%uaoJ%K^ar7cF zA>#Ha<=ewOJ{*nN&XA9H2Yfsl(7m=nB9mIqk6AW7hdb7Fq2!f9CDu4|ud%Q3 z)|O}=w*Qa=sf%)2=veIo2S29o{)`q GU*tdZxy^3? diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2_Lucene50_0.tip b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_2_Lucene50_0.tip deleted file mode 100644 index 9803f1b398829ace933101fbc393ea47807267f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 195 zcmcD&o+B>ol#`#F9a5B<8j@O+TkM&al3KyQz`&GsUFEg=&diPJQ=d`gp3 z^HNO>;tlM9+L+yfLx9Ry85o(FA2Bg7FfyQtvaZ7>%C`xdDE~WbqC%6vqUOHImHmuB VyFg&+0gcHoAWQ~^%eLE20RSolE8PG9 diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.cfe b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.cfe deleted file mode 100644 index 8fb074f30e754beeb8a030f31d07de2babe63b62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 341 zcmcD&o+B>qQ<|KbmuhO@oS$2eUz(TVnpaYknOe*M1X zMK3L-0we_ldJu{sm_;wIECtGGgwodh@i2qq4fG1~!R7(w_CVz$QRGwdlOf`aqEPuf z6#0_OT&R3Agl1A?(JO&j%De=sX$r_CP?aneP{9bGoAY3T6QJ5fKprW9aM)nl8$o75 heaEf})$WhxkOGJ}J5)2n;R70zUqIC|B=Stl1OR>yJ!${| diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.cfs b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.cfs deleted file mode 100644 index e26078b9e7cfbaca6e06ec3cf3156f48d0b92d08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2119 zcmcIl%TE(Q7@wKl?Nj9~Z^TD}V5}4bjIXK?ltc&#L?Vgcc6Uk_yF1P9Ho&d%ZHikvL|pRoxVQ^K z83{+s+sl-S$2ZRGxRR1B3lRZvSZ<_#keUvHD~?{6F0vg-IFEoEWVdZrCXvvlaVybO zd<3xJbWT_UvQ7y;{ItU=wG>lJ+Zr>3Bf$6RRA=Ul2s+O7`|vvMJrf^(q(=FfsB`Js zdh6tGi|wZ)o5chXa%rs*9YE3nP;9|rzY@LhlP6H+Cg2g^emCA_KJlIwzKdsR=fI@nK?+`vA14I OvhREg-uJeq`PhGT-i diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.si b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/_3.si deleted file mode 100644 index f2d6b6a030c291e9fdddf28b924e5caad9a02f57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 371 zcmcD&o+B>oQ<|KbmuhMdoSL4SnpfhPmzK}Kz`&SwUFEg=&diPN-zVhpTE zn30i-DZiL2JTosPzr0w%(11HDu`E%qEEUKv67nxfOwLJFaLz9($S+DP$;{8=fl3z@ z13B!5hI$5ihKBqQ!Cas=u(%*pT-#FDCnQ+c(9(o22kbnU0#;K!AY{)k)=Ml(&R|W< zO))bO0UJ_OnpcvUn+j8iX%bs;erZv1Dr;I!X>kS@&;+QREQSVp2Am+h#U+Wk1-yo4 zCZ>iKCPv2Q#-`@XtntQr#hGkCGC8dnLZvdw!^5m3zbG}uEi*MIrPwXMC^xZ0FE>9W cmCMOBI3zwez}3~|fX3t(pr8YRcS#F10cJaIr~m)} diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/segments_5 b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/segments_5 deleted file mode 100644 index 66a4c385a5adac5ff16e505da6de875fcd295c3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 198 zcmcD&o+HjtoSL4SnpaZHz`($kbzSAP`{iOo;d#DB{fX1G8BJMPS%DHDAOOTHK+FUb zVv09nL{qE5;ZvHNnwM&7@*fI7nqX`g4H9EuiZ@2rtwp?Uh65UtUx3X45?V&3b^sz| BR7L;* diff --git a/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/write.lock b/persistence-modules/hibernate-many-to-many/com.baeldung.hibernatesearch.model.Product/write.lock deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java deleted file mode 100644 index 5ba018dc52..0000000000 --- a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.persistence.manytomany.dao; - -import com.baeldung.hibernate.manytomany.model.Employee; -import com.baeldung.persistence.dao.common.IOperations; - -public interface IEmployeeDao extends IOperations{ - -} diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java deleted file mode 100644 index 48fbb8bf6b..0000000000 --- a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.persistence.manytomany.dao; - -import com.baeldung.hibernate.manytomany.model.Project; -import com.baeldung.persistence.dao.common.IOperations; - -public interface IProjectDao extends IOperations{ - -} diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/spring/PersistenceConfig.java b/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/spring/PersistenceConfig.java deleted file mode 100644 index e1ea3e2024..0000000000 --- a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/spring/PersistenceConfig.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.baeldung.spring; - -import com.google.common.base.Preconditions; -import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.core.env.Environment; -import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; -import org.springframework.orm.hibernate5.HibernateTransactionManager; -import org.springframework.orm.hibernate5.LocalSessionFactoryBean; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -import javax.sql.DataSource; -import java.util.Properties; - -@Configuration -@EnableTransactionManagement -@PropertySource({ "classpath:persistence-h2.properties" }) -@ComponentScan({ "com.baeldung.persistence" }) -public class PersistenceConfig { - - @Autowired - private Environment env; - - @Bean - public LocalSessionFactoryBean sessionFactory() { - final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); - sessionFactory.setDataSource(dataSource()); - sessionFactory.setPackagesToScan(new String[] { "com.baeldung.persistence.model" }); - sessionFactory.setHibernateProperties(hibernateProperties()); - - return sessionFactory; - } - - @Bean - public DataSource dataSource() { - final BasicDataSource dataSource = new BasicDataSource(); - dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); - dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); - dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); - dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); - - return dataSource; - } - - @Bean - public PlatformTransactionManager hibernateTransactionManager() { - final HibernateTransactionManager transactionManager = new HibernateTransactionManager(); - transactionManager.setSessionFactory(sessionFactory().getObject()); - return transactionManager; - } - - @Bean - public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { - return new PersistenceExceptionTranslationPostProcessor(); - } - - private final Properties hibernateProperties() { - final Properties hibernateProperties = new Properties(); - hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); - hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); - - hibernateProperties.setProperty("hibernate.show_sql", "false"); - - // Envers properties - hibernateProperties.setProperty("org.hibernate.envers.audit_table_suffix", env.getProperty("envers.audit_table_suffix")); - - return hibernateProperties; - } - -} \ No newline at end of file diff --git a/persistence-modules/hibernate-many-to-many/src/main/resources/import.sql b/persistence-modules/hibernate-many-to-many/src/main/resources/import.sql deleted file mode 100644 index ae008f29bc..0000000000 --- a/persistence-modules/hibernate-many-to-many/src/main/resources/import.sql +++ /dev/null @@ -1,31 +0,0 @@ -insert into item (item_id, item_name, item_desc, item_price) -values(1,'item One', 'test 1', 35.12); - -insert into item (item_id, item_name, item_desc, item_price) -values(2,'Pogo stick', 'Pogo stick', 466.12); -insert into item (item_id, item_name, item_desc, item_price) -values(3,'Raft', 'Raft', 345.12); - -insert into item (item_id, item_name, item_desc, item_price) -values(4,'Skate Board', 'Skating', 135.71); - -insert into item (item_id, item_name, item_desc, item_price) -values(5,'Umbrella', 'Umbrella for Rain', 619.25); - -insert into item (item_id, item_name, item_desc, item_price) -values(6,'Glue', 'Glue for home', 432.73); - -insert into item (item_id, item_name, item_desc, item_price) -values(7,'Paint', 'Paint for Room', 1311.40); - -insert into item (item_id, item_name, item_desc, item_price) -values(8,'Red paint', 'Red paint for room', 1135.71); - -insert into item (item_id, item_name, item_desc, item_price) -values(9,'Household Chairs', 'Chairs for house', 25.71); - -insert into item (item_id, item_name, item_desc, item_price) -values(10,'Office Chairs', 'Chairs for office', 395.98); - -insert into item (item_id, item_name, item_desc, item_price) -values(11,'Outdoor Chairs', 'Chairs for outdoor activities', 1234.36); diff --git a/persistence-modules/hibernate-many-to-many/src/main/resources/manytomany.cfg.xml b/persistence-modules/hibernate-many-to-many/src/main/resources/manytomany.cfg.xml deleted file mode 100644 index d7c8f24fb0..0000000000 --- a/persistence-modules/hibernate-many-to-many/src/main/resources/manytomany.cfg.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - com.mysql.jdbc.Driver - tutorialmy5ql - jdbc:mysql://localhost:3306/spring_hibernate_many_to_many - tutorialuser - org.hibernate.dialect.MySQLDialect - thread - false - - diff --git a/persistence-modules/hibernate-many-to-many/src/main/resources/persistence-h2.properties b/persistence-modules/hibernate-many-to-many/src/main/resources/persistence-h2.properties deleted file mode 100644 index e3544d354a..0000000000 --- a/persistence-modules/hibernate-many-to-many/src/main/resources/persistence-h2.properties +++ /dev/null @@ -1,21 +0,0 @@ -# jdbc.X -jdbc.driverClassName=org.h2.Driver -jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 -jdbc.eventGeneratedId=sa -jdbc.user=sa -jdbc.pass= - -# hibernate.X -hibernate.dialect=org.hibernate.dialect.H2Dialect -hibernate.show_sql=false -hibernate.hbm2ddl.auto=create-drop -hibernate.cache.use_second_level_cache=true -hibernate.cache.use_query_cache=true -hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory - -# hibernate.search.X -hibernate.search.default.directory_provider = filesystem -hibernate.search.default.indexBase = /data/index/default - -# envers.X -envers.audit_table_suffix=_audit_log diff --git a/persistence-modules/hibernate-many-to-many/src/test/resources/.gitignore b/persistence-modules/hibernate-many-to-many/src/test/resources/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/persistence-modules/hibernate-many-to-many/src/test/resources/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/persistence-modules/hibernate-many-to-many/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml b/persistence-modules/hibernate-many-to-many/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml deleted file mode 100644 index 9e0109aae2..0000000000 --- a/persistence-modules/hibernate-many-to-many/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/persistence-modules/hibernate-many-to-many/src/test/resources/import.sql b/persistence-modules/hibernate-many-to-many/src/test/resources/import.sql deleted file mode 100644 index 087d62d331..0000000000 --- a/persistence-modules/hibernate-many-to-many/src/test/resources/import.sql +++ /dev/null @@ -1,21 +0,0 @@ -insert into item (item_id, item_name, item_desc, item_price) values(1,'item One', 'test 1', 35.12); - -insert into item (item_id, item_name, item_desc, item_price) values(2,'Pogo stick', 'Pogo stick', 466.12); - -insert into item (item_id, item_name, item_desc, item_price) values(3,'Raft', 'Raft', 345.12); - -insert into item (item_id, item_name, item_desc, item_price) values(4,'Skate Board', 'Skating', 135.71); - -insert into item (item_id, item_name, item_desc, item_price) values(5,'Umbrella', 'Umbrella for Rain', 619.25); - -insert into item (item_id, item_name, item_desc, item_price) values(6,'Glue', 'Glue for home', 432.73); - -insert into item (item_id, item_name, item_desc, item_price) values(7,'Paint', 'Paint for Room', 1311.40); - -insert into item (item_id, item_name, item_desc, item_price) values(8,'Red paint', 'Red paint for room', 1135.71); - -insert into item (item_id, item_name, item_desc, item_price) values(9,'Household Chairs', 'Chairs for house', 25.71); - -insert into item (item_id, item_name, item_desc, item_price) values(10,'Office Chairs', 'Chairs for office', 395.98); - -insert into item (item_id, item_name, item_desc, item_price) values(11,'Outdoor Chairs', 'Chairs for outdoor activities', 1234.36); diff --git a/persistence-modules/hibernate-many-to-many/.gitignore b/persistence-modules/hibernate-mapping-2/.gitignore similarity index 100% rename from persistence-modules/hibernate-many-to-many/.gitignore rename to persistence-modules/hibernate-mapping-2/.gitignore diff --git a/persistence-modules/hibernate-mapping-2/README.md b/persistence-modules/hibernate-mapping-2/README.md new file mode 100644 index 0000000000..7a811e17cf --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/README.md @@ -0,0 +1,7 @@ +## Hibernate Mapping + +This module contains articles about Hibernate Mappings. + +### Relevant articles + +- [Hibernate Many to Many Annotation Tutorial](https://www.baeldung.com/hibernate-many-to-many) \ No newline at end of file diff --git a/persistence-modules/hibernate-many-to-many/pom.xml b/persistence-modules/hibernate-mapping-2/pom.xml similarity index 54% rename from persistence-modules/hibernate-many-to-many/pom.xml rename to persistence-modules/hibernate-mapping-2/pom.xml index 6f1abb6a7a..10c07c95eb 100644 --- a/persistence-modules/hibernate-many-to-many/pom.xml +++ b/persistence-modules/hibernate-mapping-2/pom.xml @@ -3,9 +3,9 @@ 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"> 4.0.0 - hibernate-many-to-many + hibernate-mapping-2y 0.1-SNAPSHOT - hibernate-many-to-many + hibernate-mapping-2 com.baeldung @@ -19,24 +19,8 @@ org.springframework spring-context ${org.springframework.version} - - - commons-logging - commons-logging - - - - - org.springframework - spring-aspects - ${org.springframework.version} - - org.springframework - spring-orm - ${org.springframework.version} - org.springframework.data spring-data-jpa @@ -47,16 +31,6 @@ hibernate-core ${hibernate.version} - - javax.transaction - jta - ${jta.version} - - - org.hibernate - hibernate-search-orm - ${hibernatesearch.version} - org.apache.tomcat tomcat-dbcp @@ -70,53 +44,31 @@ ${guava.version} - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - test - org.springframework spring-test ${org.springframework.version} test - - org.springframework.security - spring-security-test - ${org.springframework.security.version} - test - - - org.hsqldb - hsqldb - ${hsqldb.version} - com.h2database h2 ${h2.version} - - - jakarta.xml.bind - jakarta.xml.bind-api - 2.3.2 - + com.sun.xml.bind jaxb-core - 2.3.0.1 + ${com.sun.xml.version} javax.xml.bind jaxb-api - 2.3.1 + ${javax.xml.bind.version} com.sun.xml.bind jaxb-impl - 2.3.1 + ${com.sun.xml.version} @@ -124,13 +76,11 @@ 5.0.2.RELEASE 1.10.6.RELEASE - 4.2.1.RELEASE 5.2.10.Final - 5.8.2.Final 9.0.0.M26 - 1.1 - 2.3.4 + 2.3.0.1 + 2.3.1 \ No newline at end of file diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/PersistenceConfig.java similarity index 95% rename from persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/PersistenceConfig.java index f7179b07e5..0d7b8bdbcf 100644 --- a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/PersistenceConfig.java @@ -1,7 +1,9 @@ -package com.baeldung.manytomany.spring; +package com.baeldung.manytomany; import java.util.Properties; + import javax.sql.DataSource; + import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -20,7 +22,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableTransactionManagement @PropertySource({ "classpath:persistence-h2.properties" }) -@ComponentScan({ "com.baeldung.hibernate.manytomany" }) +@ComponentScan({ "com.baeldung.manytomany" }) public class PersistenceConfig { @Autowired @@ -30,7 +32,7 @@ public class PersistenceConfig { public LocalSessionFactoryBean sessionFactory() { final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); sessionFactory.setDataSource(restDataSource()); - sessionFactory.setPackagesToScan(new String[] { "com.baeldung.hibernate.manytomany" }); + sessionFactory.setPackagesToScan(new String[] { "com.baeldung.manytomany" }); sessionFactory.setHibernateProperties(hibernateProperties()); return sessionFactory; diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IEmployeeDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IEmployeeDao.java new file mode 100644 index 0000000000..68bf5d5bad --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IEmployeeDao.java @@ -0,0 +1,8 @@ +package com.baeldung.manytomany.dao; + +import com.baeldung.manytomany.dao.common.IOperations; +import com.baeldung.manytomany.model.Employee; + +public interface IEmployeeDao extends IOperations{ + +} diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IProjectDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IProjectDao.java new file mode 100644 index 0000000000..d2645db44a --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IProjectDao.java @@ -0,0 +1,8 @@ +package com.baeldung.manytomany.dao; + +import com.baeldung.manytomany.dao.common.IOperations; +import com.baeldung.manytomany.model.Project; + +public interface IProjectDao extends IOperations{ + +} diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/AbstractDao.java similarity index 87% rename from persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/AbstractDao.java index 5a6c76a93a..b37b48e645 100644 --- a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/AbstractDao.java @@ -1,4 +1,4 @@ -package com.baeldung.persistence.dao.common; +package com.baeldung.manytomany.dao.common; import java.io.Serializable; diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/AbstractHibernateDao.java similarity index 96% rename from persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/AbstractHibernateDao.java index f34866d883..9c8a8faa2e 100644 --- a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/AbstractHibernateDao.java @@ -1,4 +1,4 @@ -package com.baeldung.persistence.dao.common; +package com.baeldung.manytomany.dao.common; import java.io.Serializable; import java.util.List; diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/IOperations.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/IOperations.java similarity index 87% rename from persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/IOperations.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/IOperations.java index 4ef99221ab..8a85b52fc9 100644 --- a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/dao/common/IOperations.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/IOperations.java @@ -1,4 +1,4 @@ -package com.baeldung.persistence.dao.common; +package com.baeldung.manytomany.dao.common; import java.io.Serializable; import java.util.List; diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/impl/EmployeeDao.java similarity index 50% rename from persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/impl/EmployeeDao.java index 25fee8c379..b24013c567 100644 --- a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/impl/EmployeeDao.java @@ -1,9 +1,10 @@ -package com.baeldung.persistence.manytomany.dao.impl; +package com.baeldung.manytomany.dao.impl; import org.springframework.stereotype.Repository; -import com.baeldung.hibernate.manytomany.model.Employee; -import com.baeldung.persistence.dao.common.AbstractHibernateDao; -import com.baeldung.persistence.manytomany.dao.IEmployeeDao; + +import com.baeldung.manytomany.dao.IEmployeeDao; +import com.baeldung.manytomany.dao.common.AbstractHibernateDao; +import com.baeldung.manytomany.model.Employee; @Repository public class EmployeeDao extends AbstractHibernateDao implements IEmployeeDao { diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/impl/ProjectDao.java similarity index 50% rename from persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/impl/ProjectDao.java index 8fc29a5de3..a70212f519 100644 --- a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/impl/ProjectDao.java @@ -1,9 +1,10 @@ -package com.baeldung.persistence.manytomany.dao.impl; +package com.baeldung.manytomany.dao.impl; import org.springframework.stereotype.Repository; -import com.baeldung.hibernate.manytomany.model.Project; -import com.baeldung.persistence.dao.common.AbstractHibernateDao; -import com.baeldung.persistence.manytomany.dao.IProjectDao; + +import com.baeldung.manytomany.dao.IProjectDao; +import com.baeldung.manytomany.dao.common.AbstractHibernateDao; +import com.baeldung.manytomany.model.Project; @Repository diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/model/Employee.java similarity index 97% rename from persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/model/Employee.java index bfe1b5ad29..39671c21bc 100644 --- a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/model/Employee.java @@ -1,4 +1,4 @@ -package com.baeldung.hibernate.manytomany.model; +package com.baeldung.manytomany.model; import java.io.Serializable; import java.util.HashSet; diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/model/Project.java similarity index 96% rename from persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/model/Project.java index c291d7d7af..b5dc3cb856 100644 --- a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/model/Project.java @@ -1,8 +1,9 @@ -package com.baeldung.hibernate.manytomany.model; +package com.baeldung.manytomany.model; import java.io.Serializable; import java.util.HashSet; import java.util.Set; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; diff --git a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/util/HibernateUtil.java similarity index 90% rename from persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/util/HibernateUtil.java index ff035c0c37..d429564564 100644 --- a/persistence-modules/hibernate-many-to-many/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/util/HibernateUtil.java @@ -1,14 +1,15 @@ -package com.baeldung.hibernate.manytomany.util; +package com.baeldung.manytomany.util; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; -import com.baeldung.hibernate.manytomany.model.Employee; -import com.baeldung.hibernate.manytomany.model.Project; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.baeldung.manytomany.model.Employee; +import com.baeldung.manytomany.model.Project; + public class HibernateUtil { private static final Logger LOGGER = LoggerFactory.getLogger(HibernateUtil.class); diff --git a/persistence-modules/hibernate-many-to-many/src/main/resources/logback.xml b/persistence-modules/hibernate-mapping-2/src/main/resources/logback.xml similarity index 100% rename from persistence-modules/hibernate-many-to-many/src/main/resources/logback.xml rename to persistence-modules/hibernate-mapping-2/src/main/resources/logback.xml diff --git a/persistence-modules/hibernate-mapping-2/src/main/resources/persistence-h2.properties b/persistence-modules/hibernate-mapping-2/src/main/resources/persistence-h2.properties new file mode 100644 index 0000000000..9c8cf6e02b --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/main/resources/persistence-h2.properties @@ -0,0 +1,11 @@ +# jdbc.X +jdbc.driverClassName=org.h2.Driver +jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +jdbc.eventGeneratedId=sa +jdbc.user=sa +jdbc.pass= + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=false +hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/SpringContextTest.java similarity index 91% rename from persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/SpringContextTest.java rename to persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/SpringContextTest.java index 24c038aeb6..f1a6f675ce 100644 --- a/persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/SpringContextTest.java +++ b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/SpringContextTest.java @@ -6,8 +6,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; - -import com.baeldung.spring.PersistenceConfig; +import com.baeldung.manytomany.PersistenceConfig; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) diff --git a/persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java similarity index 89% rename from persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java rename to persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java index 797d3384a0..19d1a5ff50 100644 --- a/persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java +++ b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java @@ -2,6 +2,7 @@ package com.baeldung.hibernate.manytomany; import java.util.HashSet; import java.util.Set; + import org.hibernate.Session; import org.hibernate.SessionFactory; import org.junit.After; @@ -12,9 +13,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; -import com.baeldung.hibernate.manytomany.model.Employee; -import com.baeldung.hibernate.manytomany.model.Project; -import com.baeldung.manytomany.spring.PersistenceConfig; +import com.baeldung.manytomany.PersistenceConfig; +import com.baeldung.manytomany.model.Employee; +import com.baeldung.manytomany.model.Project; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) diff --git a/persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java similarity index 92% rename from persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java rename to persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java index d09b2888df..bfa158d43f 100644 --- a/persistence-modules/hibernate-many-to-many/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java +++ b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java @@ -1,10 +1,12 @@ package com.baeldung.hibernate.manytomany; -import static org.junit.Assert.assertNotNull; import static junit.framework.TestCase.assertEquals; +import static org.junit.Assert.assertNotNull; + import java.util.HashSet; import java.util.List; import java.util.Set; + import org.hibernate.Session; import org.hibernate.SessionFactory; import org.junit.After; @@ -13,9 +15,9 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import com.baeldung.hibernate.manytomany.util.HibernateUtil; -import com.baeldung.hibernate.manytomany.model.Employee; -import com.baeldung.hibernate.manytomany.model.Project; +import com.baeldung.manytomany.model.Employee; +import com.baeldung.manytomany.model.Project; +import com.baeldung.manytomany.util.HibernateUtil; /** * Configured in: manytomany.cfg.xml diff --git a/persistence-modules/hibernate-many-to-many/src/test/resources/manytomany.cfg.xml b/persistence-modules/hibernate-mapping-2/src/test/resources/manytomany.cfg.xml similarity index 97% rename from persistence-modules/hibernate-many-to-many/src/test/resources/manytomany.cfg.xml rename to persistence-modules/hibernate-mapping-2/src/test/resources/manytomany.cfg.xml index 2ca23d57d3..3ddff9a993 100644 --- a/persistence-modules/hibernate-many-to-many/src/test/resources/manytomany.cfg.xml +++ b/persistence-modules/hibernate-mapping-2/src/test/resources/manytomany.cfg.xml @@ -13,4 +13,4 @@ false create-drop - + \ No newline at end of file From 91bd7fa37fcab4b499fa38fe527deae21791a4b7 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Wed, 23 Feb 2022 17:43:45 +0200 Subject: [PATCH 049/249] remove duplicate code from old module BAEL-5336 --- spring-5-autowiring-beans/README.md | 3 -- spring-5-autowiring-beans/pom.xml | 24 ---------------- .../java/com/baeldung/autowiring/App.java | 14 ---------- .../controller/CorrectController.java | 18 ------------ .../controller/FlawedController.java | 15 ---------- .../autowiring/service/MyComponent.java | 10 ------- .../autowiring/service/MyService.java | 19 ------------- .../service/MyServiceConfiguration.java | 14 ---------- .../CorrectControllerIntegrationTest.java | 23 --------------- .../FlawedControllerIntegrationTest.java | 28 ------------------- 10 files changed, 168 deletions(-) delete mode 100644 spring-5-autowiring-beans/README.md delete mode 100644 spring-5-autowiring-beans/pom.xml delete mode 100644 spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/App.java delete mode 100644 spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/CorrectController.java delete mode 100644 spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/FlawedController.java delete mode 100644 spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyComponent.java delete mode 100644 spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyService.java delete mode 100644 spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyServiceConfiguration.java delete mode 100644 spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/CorrectControllerIntegrationTest.java delete mode 100644 spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/FlawedControllerIntegrationTest.java diff --git a/spring-5-autowiring-beans/README.md b/spring-5-autowiring-beans/README.md deleted file mode 100644 index dc8751325e..0000000000 --- a/spring-5-autowiring-beans/README.md +++ /dev/null @@ -1,3 +0,0 @@ -### Relevant Articles: - -- [Spring @Autowired Field Null – Common Causes and Solutions](https://www.baeldung.com/spring-autowired-field-null) diff --git a/spring-5-autowiring-beans/pom.xml b/spring-5-autowiring-beans/pom.xml deleted file mode 100644 index 32b56cc9ad..0000000000 --- a/spring-5-autowiring-beans/pom.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - 4.0.0 - spring-5-autowiring-beans - 0.0.1-SNAPSHOT - spring-5-autowiring-beans - - - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../parent-boot-2 - - - - - org.springframework.boot - spring-boot-starter-web - - - - diff --git a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/App.java b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/App.java deleted file mode 100644 index d2d0db7a60..0000000000 --- a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/App.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.autowiring; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.ComponentScan; - -@SpringBootApplication -public class App { - - public static void main(String[] args) { - SpringApplication.run(App.class, args); - } - -} diff --git a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/CorrectController.java b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/CorrectController.java deleted file mode 100644 index e0c0d7eeac..0000000000 --- a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/CorrectController.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.baeldung.autowiring.controller; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; - -import com.baeldung.autowiring.service.MyService; - -@Controller -public class CorrectController { - - @Autowired - MyService myService; - - public String control() { - return myService.serve(); - } - -} diff --git a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/FlawedController.java b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/FlawedController.java deleted file mode 100644 index 673e686f79..0000000000 --- a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/FlawedController.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.baeldung.autowiring.controller; - -import org.springframework.stereotype.Controller; - -import com.baeldung.autowiring.service.MyService; - -@Controller -public class FlawedController { - - public String control() { - MyService userService = new MyService(); - return userService.serve(); - } - -} diff --git a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyComponent.java b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyComponent.java deleted file mode 100644 index c04ca3f4ba..0000000000 --- a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyComponent.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.baeldung.autowiring.service; - -import org.springframework.stereotype.Component; - -@Component -public class MyComponent { - - public void doWork() {} - -} diff --git a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyService.java b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyService.java deleted file mode 100644 index 3443dc05de..0000000000 --- a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyService.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.baeldung.autowiring.service; - -import org.springframework.beans.factory.annotation.Autowired; - -/** - * The bean corresponding to this class is defined in MyServiceConfiguration - * Alternatively, you could choose to decorate this class with @Component or @Service - */ -public class MyService { - - @Autowired - MyComponent myComponent; - - public String serve() { - myComponent.doWork(); - return "success"; - } - -} diff --git a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyServiceConfiguration.java b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyServiceConfiguration.java deleted file mode 100644 index e30e4f770e..0000000000 --- a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyServiceConfiguration.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.autowiring.service; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class MyServiceConfiguration { - - @Bean - MyService myService() { - return new MyService(); - } - -} diff --git a/spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/CorrectControllerIntegrationTest.java b/spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/CorrectControllerIntegrationTest.java deleted file mode 100644 index 3807641edd..0000000000 --- a/spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/CorrectControllerIntegrationTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.baeldung.autowiring.controller; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - -@ExtendWith(SpringExtension.class) -@SpringBootTest -public class CorrectControllerIntegrationTest { - - @Autowired - CorrectController controller; - - @Test - void whenControl_ThenRunSuccessfully() { - assertDoesNotThrow(() -> controller.control()); - } - -} diff --git a/spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/FlawedControllerIntegrationTest.java b/spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/FlawedControllerIntegrationTest.java deleted file mode 100644 index 79d446604f..0000000000 --- a/spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/FlawedControllerIntegrationTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.baeldung.autowiring.controller; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.junit.jupiter.api.Assertions.assertThrows; - -@ExtendWith(SpringExtension.class) -@SpringBootTest -public class FlawedControllerIntegrationTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(FlawedControllerIntegrationTest.class); - - @Autowired - FlawedController myController; - - @Test - void whenControl_ThenThrowNullPointerException() { - NullPointerException npe = assertThrows(NullPointerException.class, () -> myController.control()); - LOGGER.error("Got a NullPointerException", npe); - } - -} From 87c9fde8d71247c349dc0345947f2c5d857af3ed Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Wed, 23 Feb 2022 17:04:52 +0000 Subject: [PATCH 050/249] [JAVA-9909] Fix code for DFS article --- .../baeldung/algorithms/dfs/BinaryTree.java | 78 ++++++------------- .../algorithms/dfs/BinaryTreeUnitTest.java | 14 +--- 2 files changed, 28 insertions(+), 64 deletions(-) diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/BinaryTree.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/BinaryTree.java index a6019ea9f9..a3cb2b396e 100644 --- a/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/BinaryTree.java +++ b/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/BinaryTree.java @@ -1,7 +1,5 @@ package com.baeldung.algorithms.dfs; -import java.util.LinkedList; -import java.util.Queue; import java.util.Stack; public class BinaryTree { @@ -124,69 +122,43 @@ public class BinaryTree { } } - public void traverseLevelOrder() { - if (root == null) { - return; - } - Queue nodes = new LinkedList<>(); - nodes.add(root); - - while (!nodes.isEmpty()) { - - Node node = nodes.remove(); - - System.out.print(" " + node.value); - - if (node.left != null) { - nodes.add(node.left); - } - - if (node.left != null) { - nodes.add(node.right); - } - } - } - - public void traverseInOrderWithoutRecursion() { - Stack stack = new Stack(); + Stack stack = new Stack<>(); Node current = root; - stack.push(root); - while(! stack.isEmpty()) { - while(current.left != null) { - current = current.left; - stack.push(current); - } - current = stack.pop(); - visit(current.value); - if(current.right != null) { - current = current.right; + + while (current != null || !stack.isEmpty()) { + while (current != null) { stack.push(current); + current = current.left; } + + Node top = stack.pop(); + visit(top.value); + current = top.right; } } - + public void traversePreOrderWithoutRecursion() { - Stack stack = new Stack(); - Node current = root; + Stack stack = new Stack<>(); + Node current; stack.push(root); while(! stack.isEmpty()) { current = stack.pop(); visit(current.value); - + if(current.right != null) stack.push(current.right); - + if(current.left != null) stack.push(current.left); - } + } } - + public void traversePostOrderWithoutRecursion() { - Stack stack = new Stack(); + Stack stack = new Stack<>(); Node prev = root; - Node current = root; + Node current; stack.push(root); while (!stack.isEmpty()) { @@ -206,14 +178,14 @@ public class BinaryTree { stack.push(current.left); } } - } - } - - private void visit(int value) { - System.out.print(" " + value); + } } - - class Node { + + private void visit(int value) { + System.out.print(" " + value); + } + + static class Node { int value; Node left; Node right; diff --git a/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/BinaryTreeUnitTest.java b/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/BinaryTreeUnitTest.java index 076da14f81..f98b4377ed 100644 --- a/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/BinaryTreeUnitTest.java +++ b/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/BinaryTreeUnitTest.java @@ -1,11 +1,11 @@ package com.baeldung.algorithms.dfs; +import org.junit.Test; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import org.junit.Test; - public class BinaryTreeUnitTest { @Test @@ -13,7 +13,7 @@ public class BinaryTreeUnitTest { BinaryTree bt = createBinaryTree(); - assertTrue(!bt.isEmpty()); + assertFalse(bt.isEmpty()); } @Test @@ -111,14 +111,6 @@ public class BinaryTreeUnitTest { bt.traversePostOrderWithoutRecursion(); } - @Test - public void givenABinaryTree_WhenTraversingLevelOrder_ThenPrintValues() { - - BinaryTree bt = createBinaryTree(); - - bt.traverseLevelOrder(); - } - private BinaryTree createBinaryTree() { BinaryTree bt = new BinaryTree(); From 6ca42b7a4ecbbffc2b8a890f70995cbbe8dc4a6f Mon Sep 17 00:00:00 2001 From: lsieun <331505785@qq.com> Date: Fri, 25 Feb 2022 05:13:13 +0800 Subject: [PATCH 051/249] BAEL-4151: Guide to ByteBuffer (#11859) * Convert Byte Array to its Numeric Representation * Remove Redundant Getter Method * BAEL-4286 How to get the value of a bit at a certain position from a byte * BAEL-4286(update): remove redundant test methods * BAEL-4151: Guide to ByteBuffer --- .../bytebuffer/ByteBufferUnitTest.java | 339 ++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 core-java-modules/core-java-nio-2/src/test/java/com/baeldung/bytebuffer/ByteBufferUnitTest.java diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/bytebuffer/ByteBufferUnitTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/bytebuffer/ByteBufferUnitTest.java new file mode 100644 index 0000000000..5d108ba14a --- /dev/null +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/bytebuffer/ByteBufferUnitTest.java @@ -0,0 +1,339 @@ +package com.baeldung.bytebuffer; + +import org.junit.Test; + +import java.lang.reflect.Field; +import java.nio.*; +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.*; + +public class ByteBufferUnitTest { + @Test + public void givenBufferCreation_whenUsingAllocate_thenSuccess() { + ByteBuffer buffer = ByteBuffer.allocate(10); + assertNotNull(buffer); + } + + @Test + public void givenBufferCreation_whenUsingAllocateDirect_thenSuccess() { + ByteBuffer buffer = ByteBuffer.allocateDirect(10); + assertNotNull(buffer); + } + + @Test + public void givenBufferCreation_whenUsingWrap_thenSuccess() { + byte[] bytes = new byte[10]; + ByteBuffer buffer = ByteBuffer.wrap(bytes); + assertNotNull(buffer); + } + + @Test + public void givenBufferIndex_whenUsingAllocate_thenInitialIndices() { + // create instance using allocate + ByteBuffer buffer = ByteBuffer.allocate(10); + + // get index + int position = buffer.position(); + int limit = buffer.limit(); + int capacity = buffer.capacity(); + + // assert + assertEquals(0, position); + assertEquals(10, limit); + assertEquals(10, capacity); + } + + @Test + public void givenBufferIndex_whenChangingPositionAndLimit_thenSuccess() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + + // change index + buffer.position(2); + buffer.limit(5); + + // assert + assertIndex(buffer, -1, 2, 5, 10); + } + + @Test + public void givenBufferIndex_whenUsingWrap_thenInitialIndices() { + // create instance + byte[] bytes = new byte[10]; + ByteBuffer buffer = ByteBuffer.wrap(bytes); + + // assert + assertIndex(buffer, -1, 0, 10, 10); + } + + @Test + public void givenBufferIndex_whenUsingWrapWithOffsetAndLength_thenInitialIndices() { + // create instance + byte[] bytes = new byte[10]; + ByteBuffer buffer = ByteBuffer.wrap(bytes, 2, 6); + + // assert + assertIndex(buffer, -1, 2, 8, 10); + } + + @Test + public void givenBufferIndex_whenUsingMarkAndReset_thenOK() { + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + buffer.position(2); + assertIndex(buffer, -1, 2, 10, 10); + + buffer.mark(); + assertIndex(buffer, 2, 2, 10, 10); + + buffer.position(5); + assertIndex(buffer, 2, 5, 10, 10); + + buffer.reset(); + assertIndex(buffer, 2, 2, 10, 10); + } + + @Test + public void givenBufferIndex_whenUsingClear_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // clear + buffer.clear(); + assertIndex(buffer, -1, 0, 10, 10); + } + + @Test + public void givenBufferIndex_whenUsingFlip_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // flip + buffer.flip(); + assertIndex(buffer, -1, 0, 5, 10); + } + + @Test + public void givenBufferIndex_whenUsingRewind_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // rewind + buffer.rewind(); + assertIndex(buffer, -1, 0, 8, 10); + } + + @Test + public void givenBufferIndex_whenUsingCompact_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // compact + buffer.compact(); + assertIndex(buffer, -1, 3, 10, 10); + } + + @Test + public void givenBufferIndex_whenUsingRemain_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + + // change index + buffer.position(2); + buffer.limit(8); + + // remain + boolean flag = buffer.hasRemaining(); + int remaining = buffer.remaining(); + + // assert + assertTrue(flag); + assertEquals(6, remaining); + } + + @Test(expected = BufferUnderflowException.class) + public void givenNotEnoughRemaining_WhenCallingGetInt_thenBufferUnderflowException() { + ByteBuffer buffer = ByteBuffer.allocate(2); + buffer.getInt(); + } + + @Test(expected = BufferOverflowException.class) + public void givenNotEnoughRemaining_WhenCallingPutInt_thenBufferOverflowException() { + ByteBuffer buffer = ByteBuffer.allocate(2); + buffer.putInt(10); + } + + @Test + public void givenBufferView_whenUsingDuplicate_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // view + ByteBuffer view = buffer.duplicate(); + assertIndex(view, 2, 5, 8, 10); + } + + @Test + public void givenBufferView_whenUsingSlice_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // view + ByteBuffer view = buffer.slice(); + assertIndex(view, -1, 0, 3, 3); + } + + @Test + public void givenBufferView_whenUsingAsReaOnlyBuffer_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // view + ByteBuffer view = buffer.asReadOnlyBuffer(); + assertIndex(view, 2, 5, 8, 10); + } + + @Test + public void givenBufferView_whenUsingAsIntBuffer_thenOK() { + // create instance + byte[] bytes = new byte[]{ + (byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE, // CAFEBABE ---> cafebabe + (byte) 0xF0, (byte) 0x07, (byte) 0xBA, (byte) 0x11, // F007BA11 ---> football + (byte) 0x0F, (byte) 0xF1, (byte) 0xCE // 0FF1CE ---> office + }; + ByteBuffer buffer = ByteBuffer.wrap(bytes); + assertIndex(buffer, -1, 0, 11, 11); + + // view + IntBuffer intBuffer = buffer.asIntBuffer(); + int capacity = intBuffer.capacity(); + assertEquals(2, capacity); + assertIndex(intBuffer, -1, 0, 2, 2); + } + + @Test + public void givenByteOrder_whenUsingBigEndian_thenOK() { + // create instance + byte[] bytes = new byte[]{(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE}; + ByteBuffer buffer = ByteBuffer.wrap(bytes); + + // change byte order + buffer.order(ByteOrder.BIG_ENDIAN); + int val = buffer.getInt(); + + // assert + assertEquals(0xCAFEBABE, val); + } + + @Test + public void givenByteOrder_whenUsingLittleEndian_thenOK() { + // create instance + byte[] bytes = new byte[]{(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE}; + ByteBuffer buffer = ByteBuffer.wrap(bytes); + + // change byte order + buffer.order(ByteOrder.LITTLE_ENDIAN); + int val = buffer.getInt(); + + // assert + assertEquals(0xBEBAFECA, val); + } + + @Test + public void givenComparing_whenUsingEqualsAndCompareTo_thenOK() { + // create instance + byte[] bytes1 = "World".getBytes(StandardCharsets.UTF_8); + byte[] bytes2 = "HelloWorld".getBytes(StandardCharsets.UTF_8); + ByteBuffer buffer1 = ByteBuffer.wrap(bytes1); + ByteBuffer buffer2 = ByteBuffer.wrap(bytes2); + + // change index + buffer2.position(5); + + // equals and compareTo + boolean equal = buffer1.equals(buffer2); + int result = buffer1.compareTo(buffer2); + + // assert + assertTrue(equal); + assertEquals(0, result); + } + + private void assertIndex(Buffer buffer, int mark, int position, int limit, int capacity) { + assertEquals(mark, getMark(buffer)); + assertEquals(position, buffer.position()); + assertEquals(limit, buffer.limit()); + assertEquals(capacity, buffer.capacity()); + } + + private int getMark(Buffer buffer) { + try { + Class clazz = Buffer.class; + Field f = clazz.getDeclaredField("mark"); + f.setAccessible(true); + Object result = f.get(buffer); + return (int) result; + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + return -1; + } +} From 1d80576a7c6d795e552af488b42e31662ce7c79c Mon Sep 17 00:00:00 2001 From: vunamtien Date: Fri, 25 Feb 2022 04:15:22 +0700 Subject: [PATCH 052/249] BAEL-5379-create-simple-rock-paper-scissors-game (#11855) * BAEL-5379-create-simple-rock-paper-scissors-game * BAEL-5379-create-simple-rock-paper-scissors-game * BAEL-5379-create-simple-rock-paper-scissors-game Co-authored-by: tienvn4 --- .../baeldung/game/RockPaperScissorsGame.java | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/game/RockPaperScissorsGame.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/game/RockPaperScissorsGame.java index fc9299f12d..17f0f02698 100644 --- a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/game/RockPaperScissorsGame.java +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/game/RockPaperScissorsGame.java @@ -1,17 +1,24 @@ package com.baeldung.game; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; -import java.util.Scanner; +import java.util.*; class RockPaperScissorsGame { - private static Map movesMap = new HashMap() {{ - put(0, "rock"); - put(1, "paper"); - put(2, "scissors"); - }}; + enum Move { + ROCK("rock"), + PAPER("paper"), + SCISSORS("scissors"); + + private String value; + + Move(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); @@ -31,7 +38,7 @@ class RockPaperScissorsGame { break; } - if (!movesMap.containsValue(playerMove)) { + if (Arrays.stream(Move.values()).noneMatch(x -> x.getValue().equals(playerMove))) { System.out.println("Your move isn't valid!"); continue; } @@ -51,15 +58,15 @@ class RockPaperScissorsGame { } private static boolean isPlayerWin(String playerMove, String computerMove) { - return playerMove.equals("rock") && computerMove.equals("scissors") - || (playerMove.equals("scissors") && computerMove.equals("paper")) - || (playerMove.equals("paper") && computerMove.equals("rock")); + return playerMove.equals(Move.ROCK.value) && computerMove.equals(Move.SCISSORS.value) + || (playerMove.equals(Move.SCISSORS.value) && computerMove.equals(Move.PAPER.value)) + || (playerMove.equals(Move.PAPER.value) && computerMove.equals(Move.ROCK.value)); } private static String getComputerMove() { Random random = new Random(); int randomNumber = random.nextInt(3); - String computerMove = movesMap.get(randomNumber); + String computerMove = Move.values()[randomNumber].getValue(); System.out.println("Computer move: " + computerMove); return computerMove; } From cb65018f66cd2a7405f89797d139b9ce63381963 Mon Sep 17 00:00:00 2001 From: lucaCambi77 Date: Fri, 25 Feb 2022 02:17:58 +0100 Subject: [PATCH 053/249] [ BAEL-5337 ] - Enable Logging for Spring Security (#11803) * feat: logging application * fix: apply formatter --- .../baeldung/logging/LoggingController.java | 16 ++++++++++++ .../com/baeldung/logging/SecurityConfig.java | 26 +++++++++++++++++++ .../logging/SecurityLoggingApplication.java | 14 ++++++++++ .../resources/application-logging.properties | 4 +++ 4 files changed, 60 insertions(+) create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/LoggingController.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityConfig.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityLoggingApplication.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/resources/application-logging.properties diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/LoggingController.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/LoggingController.java new file mode 100644 index 0000000000..c2d47fe6d6 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/LoggingController.java @@ -0,0 +1,16 @@ +package com.baeldung.logging; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class LoggingController { + + @GetMapping("/logging") + public ResponseEntity logging() { + return new ResponseEntity<>("logging/baeldung", HttpStatus.OK); + } + +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityConfig.java new file mode 100644 index 0000000000..f48f817dd2 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityConfig.java @@ -0,0 +1,26 @@ +package com.baeldung.logging; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Value("${spring.websecurity.debug:false}") + boolean webSecurityDebug; + + @Override + public void configure(WebSecurity web) { + web.debug(webSecurityDebug); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/**") + .permitAll(); + } +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityLoggingApplication.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityLoggingApplication.java new file mode 100644 index 0000000000..2fadf1cc26 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityLoggingApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.logging; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SecurityLoggingApplication { + + public static void main(String... args) { + SpringApplication application = new SpringApplication(SecurityLoggingApplication.class); + application.setAdditionalProfiles("logging"); + application.run(args); + } +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/resources/application-logging.properties b/spring-security-modules/spring-security-web-boot-3/src/main/resources/application-logging.properties new file mode 100644 index 0000000000..4f0c3450a3 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/resources/application-logging.properties @@ -0,0 +1,4 @@ + +logging.level.org.springframework.security=DEBUG + +spring.websecurity.debug=true \ No newline at end of file From f74400ee6ec1449ebabe16794338927410e2d768 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Fri, 25 Feb 2022 03:36:17 -0300 Subject: [PATCH 054/249] BAEL-2080 - Check if a user is logged-in with Servlets and JSP (#11821) * BAEL-2080 - Check if a user is logged-in with Servlets and JSP * new module: javax-servlets-2 * adding javax-servlets-2 to the parent pom. * adding module javax-servlets-2 to all profiles --- javax-servlets-2/README.md | 5 + javax-servlets-2/pom.xml | 60 ++++++++++++ .../java/com/baeldung/user/check/User.java | 80 +++++++++++++++ .../baeldung/user/check/UserCheckFilter.java | 46 +++++++++ .../user/check/UserCheckLoginServlet.java | 56 +++++++++++ .../user/check/UserCheckLogoutServlet.java | 26 +++++ .../baeldung/user/check/UserCheckServlet.java | 28 ++++++ .../src/main/resources/logback.xml | 13 +++ .../main/webapp/WEB-INF/user.check/home.jsp | 31 ++++++ .../main/webapp/WEB-INF/user.check/login.jsp | 33 +++++++ .../user/check/UserCheckServletLiveTest.java | 98 +++++++++++++++++++ pom.xml | 2 + 12 files changed, 478 insertions(+) create mode 100644 javax-servlets-2/README.md create mode 100644 javax-servlets-2/pom.xml create mode 100644 javax-servlets-2/src/main/java/com/baeldung/user/check/User.java create mode 100644 javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java create mode 100644 javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLoginServlet.java create mode 100644 javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLogoutServlet.java create mode 100644 javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckServlet.java create mode 100644 javax-servlets-2/src/main/resources/logback.xml create mode 100644 javax-servlets-2/src/main/webapp/WEB-INF/user.check/home.jsp create mode 100644 javax-servlets-2/src/main/webapp/WEB-INF/user.check/login.jsp create mode 100644 javax-servlets-2/src/test/java/com/baeldung/user/check/UserCheckServletLiveTest.java diff --git a/javax-servlets-2/README.md b/javax-servlets-2/README.md new file mode 100644 index 0000000000..f126f17297 --- /dev/null +++ b/javax-servlets-2/README.md @@ -0,0 +1,5 @@ +## Servlets + +This module contains articles about Servlets. + +### Relevant Articles: diff --git a/javax-servlets-2/pom.xml b/javax-servlets-2/pom.xml new file mode 100644 index 0000000000..34c00c3d05 --- /dev/null +++ b/javax-servlets-2/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + com.baeldung.javax-servlets + javax-servlets-2 + 1.0-SNAPSHOT + javax-servlets-2 + war + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + commons-fileupload + commons-fileupload + ${commons-fileupload.version} + + + + javax.servlet + javax.servlet-api + ${javax.servlet-api.version} + + + javax.servlet.jsp + javax.servlet.jsp-api + ${javax.servlet.jsp-api.version} + provided + + + javax.servlet + jstl + ${jstl.version} + + + org.apache.httpcomponents + httpclient + ${org.apache.httpcomponents.version} + test + + + commons-logging + commons-logging + + + + + + + 4.5.13 + 4.0.1 + + diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/User.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/User.java new file mode 100644 index 0000000000..f61c0490bc --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/User.java @@ -0,0 +1,80 @@ +package com.baeldung.user.check; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; + +/** + * @since 6 de fev de 2022 + * @author ulisses + */ +public class User implements Serializable { + private static final long serialVersionUID = 1L; + + protected static final HashMap DB = new HashMap<>(); + static { + DB.put("admin", new User("admin", "password")); + DB.put("user", new User("user", "pass")); + } + + private String name; + private String password; + + private List logins = new ArrayList(); + + public User(String name, String password) { + this.name = name; + this.password = password; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getLogins() { + return logins; + } + + public void setLogins(List logins) { + this.logins = logins; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + User other = (User) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } +} diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java new file mode 100644 index 0000000000..2a370afe85 --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java @@ -0,0 +1,46 @@ +package com.baeldung.user.check; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebFilter("/user-check/*") +public class UserCheckFilter implements Filter { + public static void forward(HttpServletRequest request, HttpServletResponse response, String page) throws ServletException, IOException { + request.getRequestDispatcher("/WEB-INF/user.check" + page) + .forward(request, response); + } + + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { + if (!(req instanceof HttpServletRequest)) { + throw new ServletException("Can only process HttpServletRequest"); + } + + if (!(res instanceof HttpServletResponse)) { + throw new ServletException("Can only process HttpServletResponse"); + } + + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + + request.setAttribute("origin", request.getRequestURI()); + + if (!request.getRequestURI() + .contains("login") && request.getSession(false) == null) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + forward(request, response, "/login.jsp"); + // we return here so the original servlet is not processed + return; + } + + chain.doFilter(request, response); + } +} diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLoginServlet.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLoginServlet.java new file mode 100644 index 0000000000..e1a38fc7b8 --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLoginServlet.java @@ -0,0 +1,56 @@ +package com.baeldung.user.check; + +import java.io.IOException; +import java.util.Date; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +@WebServlet("/user-check/login") +public class UserCheckLoginServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + if (request.getSession(false) != null) { + response.sendRedirect(request.getContextPath() + "/user-check/home"); + return; + } + + String referer = (String) request.getAttribute("origin"); + request.setAttribute("origin", referer); + UserCheckFilter.forward(request, response, "/login.jsp"); + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + String key = request.getParameter("name"); + String pass = request.getParameter("password"); + + User user = User.DB.get(key); + if (user == null || !user.getPassword() + .equals(pass)) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + request.setAttribute("origin", request.getParameter("origin")); + request.setAttribute("error", "invalid login"); + UserCheckFilter.forward(request, response, "/login.jsp"); + return; + } + + user.getLogins() + .add(new Date()); + + HttpSession session = request.getSession(); + session.setAttribute("user", user); + + String origin = request.getParameter("origin"); + if (origin == null || origin.contains("login")) + origin = "./"; + + response.sendRedirect(origin); + } +} diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLogoutServlet.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLogoutServlet.java new file mode 100644 index 0000000000..42c0bb87ab --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLogoutServlet.java @@ -0,0 +1,26 @@ +package com.baeldung.user.check; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +@WebServlet("/user-check/logout") +public class UserCheckLogoutServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + HttpSession session = request.getSession(false); + if (session != null) { + session.invalidate(); + } + + request.setAttribute("loggedOut", true); + response.sendRedirect("./"); + } +} diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckServlet.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckServlet.java new file mode 100644 index 0000000000..d7d5d1e762 --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckServlet.java @@ -0,0 +1,28 @@ +package com.baeldung.user.check; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +@WebServlet(name = "home", urlPatterns = { "/user-check/", "/user-check", "/user-check/home" }) +public class UserCheckServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + HttpSession session = request.getSession(false); + if (session == null || session.getAttribute("user") == null) { + throw new IllegalStateException("user not logged in"); + } + + User user = (User) session.getAttribute("user"); + request.setAttribute("user", user); + + UserCheckFilter.forward(request, response, "/home.jsp"); + } +} diff --git a/javax-servlets-2/src/main/resources/logback.xml b/javax-servlets-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/javax-servlets-2/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/javax-servlets-2/src/main/webapp/WEB-INF/user.check/home.jsp b/javax-servlets-2/src/main/webapp/WEB-INF/user.check/home.jsp new file mode 100644 index 0000000000..4e17763552 --- /dev/null +++ b/javax-servlets-2/src/main/webapp/WEB-INF/user.check/home.jsp @@ -0,0 +1,31 @@ +<%@ page contentType="text/html;charset=UTF-8" session="false"%> +<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%> + + + + login success - current session info + + +
+

user info

+
+ name: ${user.name} +
+ +
+ logins: +
    + +
  • ${login}
  • +
    +
+
+ + +
+ + diff --git a/javax-servlets-2/src/main/webapp/WEB-INF/user.check/login.jsp b/javax-servlets-2/src/main/webapp/WEB-INF/user.check/login.jsp new file mode 100644 index 0000000000..19a857585d --- /dev/null +++ b/javax-servlets-2/src/main/webapp/WEB-INF/user.check/login.jsp @@ -0,0 +1,33 @@ +<%@ page contentType="text/html;charset=UTF-8" session="false"%> +<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%> + + + + login + + +
+ + +
* redirected to login from: ${origin}
+
+ + +
* error: ${error}
+
+ +
+ credentials + + + + + + + + +
+
+ + diff --git a/javax-servlets-2/src/test/java/com/baeldung/user/check/UserCheckServletLiveTest.java b/javax-servlets-2/src/test/java/com/baeldung/user/check/UserCheckServletLiveTest.java new file mode 100644 index 0000000000..42858d61e7 --- /dev/null +++ b/javax-servlets-2/src/test/java/com/baeldung/user/check/UserCheckServletLiveTest.java @@ -0,0 +1,98 @@ +package com.baeldung.user.check; + +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.LaxRedirectStrategy; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class UserCheckServletLiveTest { + private static final String BASE_URL = "http://localhost:8080/javax-servlets-2/user-check"; + + @Mock + HttpServletRequest request; + + @Mock + HttpServletResponse response; + + private CloseableHttpClient buildClient() { + return HttpClientBuilder.create() + .setRedirectStrategy(new LaxRedirectStrategy()) + .build(); + } + + @Test + public void whenCorrectCredentials_thenLoginSucceeds() throws Exception { + try (CloseableHttpClient client = buildClient()) { + HttpPost post = new HttpPost(BASE_URL + "/login"); + + List form = new ArrayList<>(); + form.add(new BasicNameValuePair("name", "admin")); + form.add(new BasicNameValuePair("password", "password")); + + post.setEntity(new UrlEncodedFormEntity(form)); + try (CloseableHttpResponse response = client.execute(post)) { + String body = EntityUtils.toString(response.getEntity()); + + assertTrue(response.getStatusLine() + .getStatusCode() == 200); + + assertTrue(body.contains("login success")); + } + } + } + + @Test + public void whenIncorrectCredentials_thenLoginFails() throws Exception { + try (CloseableHttpClient client = buildClient()) { + HttpPost post = new HttpPost(BASE_URL + "/login"); + + List form = new ArrayList<>(); + form.add(new BasicNameValuePair("name", "admin")); + form.add(new BasicNameValuePair("password", "invalid")); + + post.setEntity(new UrlEncodedFormEntity(form)); + try (CloseableHttpResponse response = client.execute(post)) { + String body = EntityUtils.toString(response.getEntity()); + + assertTrue(response.getStatusLine() + .getStatusCode() == 401); + + assertTrue(body.contains("invalid login")); + } + } + } + + @Test + public void whenNotLoggedIn_thenRedirectedToLoginPage() throws Exception { + try (CloseableHttpClient client = buildClient()) { + HttpGet get = new HttpGet(BASE_URL + "/home"); + + try (CloseableHttpResponse response = client.execute(get)) { + String body = EntityUtils.toString(response.getEntity()); + + assertTrue(response.getStatusLine() + .getStatusCode() == 401); + + assertTrue(body.contains("redirected to login")); + } + } + } +} diff --git a/pom.xml b/pom.xml index 99217774e9..cab9a34f02 100644 --- a/pom.xml +++ b/pom.xml @@ -459,6 +459,7 @@ java-vavr-stream java-websocket javax-servlets + javax-servlets-2 javaxval jaxb jee-7 @@ -943,6 +944,7 @@ java-vavr-stream java-websocket javax-servlets + javax-servlets-2 javaxval jaxb jee-7 From f4d7c9a0ea1272f7998130628b08d00a3ef745cf Mon Sep 17 00:00:00 2001 From: mladensavic94 Date: Fri, 25 Feb 2022 09:54:42 +0100 Subject: [PATCH 055/249] Caching Maven Dependencies with Docker - fix --- .../src/main/java/com/baeldung/maven_caching/CoreClass.java | 4 ++-- docker/docker-caching/multi-module-caching/pom.xml | 3 +-- .../java/com/baeldung/maven_caching/MavenCachingMain.java | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docker/docker-caching/multi-module-caching/core/src/main/java/com/baeldung/maven_caching/CoreClass.java b/docker/docker-caching/multi-module-caching/core/src/main/java/com/baeldung/maven_caching/CoreClass.java index 7d57110d72..d8c73a331a 100644 --- a/docker/docker-caching/multi-module-caching/core/src/main/java/com/baeldung/maven_caching/CoreClass.java +++ b/docker/docker-caching/multi-module-caching/core/src/main/java/com/baeldung/maven_caching/CoreClass.java @@ -4,11 +4,11 @@ import com.google.common.io.Files; public class CoreClass { - public String method(){ + public String method() { return "Hello from core module!!"; } - public String dependencyMethod(){ + public String dependencyMethod() { return Files.simplifyPath("/home/app/test"); } } diff --git a/docker/docker-caching/multi-module-caching/pom.xml b/docker/docker-caching/multi-module-caching/pom.xml index c5a7d9ec6f..7968114385 100644 --- a/docker/docker-caching/multi-module-caching/pom.xml +++ b/docker/docker-caching/multi-module-caching/pom.xml @@ -5,8 +5,7 @@ com.baeldung multi-module-caching 0.0.1-SNAPSHOT - maven-caching - maven-caching + Multi-module Maven caching example pom diff --git a/docker/docker-caching/single-module-caching/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java b/docker/docker-caching/single-module-caching/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java index 81673fd9ac..4fbd8e5311 100644 --- a/docker/docker-caching/single-module-caching/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java +++ b/docker/docker-caching/single-module-caching/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java @@ -5,7 +5,7 @@ import com.google.common.io.Files; public class MavenCachingMain { public static void main(String[] args) { - System.out.println("Hello from maven_caching app!!!"); + System.out.println("Hello from maven_caching app!!!"); System.out.println(Files.simplifyPath("/home/app/test")); } } From 12c25ba2e3a2903fe779001bdf7ef51b2709acf4 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Fri, 25 Feb 2022 15:47:15 +0530 Subject: [PATCH 056/249] JAVA-10307:Fix Table ITEM not found issue --- .../src/main/resources/{import.sql => import-db.sql} | 0 .../spring-hibernate-5/src/test/resources/criteria.cfg.xml | 1 + .../src/test/resources/{import.sql => import-db.sql} | 0 3 files changed, 1 insertion(+) rename persistence-modules/spring-hibernate-5/src/main/resources/{import.sql => import-db.sql} (100%) rename persistence-modules/spring-hibernate-5/src/test/resources/{import.sql => import-db.sql} (100%) diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/import.sql b/persistence-modules/spring-hibernate-5/src/main/resources/import-db.sql similarity index 100% rename from persistence-modules/spring-hibernate-5/src/main/resources/import.sql rename to persistence-modules/spring-hibernate-5/src/main/resources/import-db.sql diff --git a/persistence-modules/spring-hibernate-5/src/test/resources/criteria.cfg.xml b/persistence-modules/spring-hibernate-5/src/test/resources/criteria.cfg.xml index bc4fed9680..9ca9836a70 100644 --- a/persistence-modules/spring-hibernate-5/src/test/resources/criteria.cfg.xml +++ b/persistence-modules/spring-hibernate-5/src/test/resources/criteria.cfg.xml @@ -11,6 +11,7 @@ org.hibernate.dialect.H2Dialect create-drop + import-db.sql false diff --git a/persistence-modules/spring-hibernate-5/src/test/resources/import.sql b/persistence-modules/spring-hibernate-5/src/test/resources/import-db.sql similarity index 100% rename from persistence-modules/spring-hibernate-5/src/test/resources/import.sql rename to persistence-modules/spring-hibernate-5/src/test/resources/import-db.sql From de6d367e413f3ec302ac19030030e20c11fabe06 Mon Sep 17 00:00:00 2001 From: sanitaso Date: Fri, 25 Feb 2022 12:54:20 +0100 Subject: [PATCH 057/249] add files to springdoc --- .../swaggerResponseAPI/.gitignore | 33 ++++++++ .../swaggerResponseAPI/pom.xml | 69 +++++++++++++++++ .../SwaggerResponseApiApplication.java | 13 ++++ .../controller/ProductController.java | 39 ++++++++++ .../swaggerresponseapi/model/Product.java | 15 ++++ .../service/ProductService.java | 21 +++++ .../src/main/resources/application.properties | 1 + .../ProductIntegrationTest.java | 76 +++++++++++++++++++ .../SwaggerResponseApiApplicationTests.java | 13 ++++ 9 files changed, 280 insertions(+) create mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/.gitignore create mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/pom.xml create mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java create mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java create mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java create mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java create mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/resources/application.properties create mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/ProductIntegrationTest.java create mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplicationTests.java diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/.gitignore b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/.gitignore new file mode 100644 index 0000000000..f60f3beecd --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/ +!**/src/main/**/target/ +!**/src/test/**/target/ +mvnv* + +### 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/ diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/pom.xml b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/pom.xml new file mode 100644 index 0000000000..17544290e4 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + com.baeldung.spring-boot-modules + spring-boot-disable-logging + 1.0.0-SNAPSHOT + + com.baeldung + swaggerResponseAPI + 0.0.1-SNAPSHOT + swaggerResponseAPI + swaggerResponseAPI + + 11 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + true + + + org.springdoc + springdoc-openapi-ui + 1.6.6 + + + junit + junit + 4.13.2 + test + + + com.fasterxml.jackson.core + jackson-databind + 2.13.0 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java new file mode 100644 index 0000000000..913544b459 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.swaggerresponseapi; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SwaggerResponseApiApplication { + + public static void main(String[] args) { + SpringApplication.run(SwaggerResponseApiApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java new file mode 100644 index 0000000000..3e9a3291d9 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java @@ -0,0 +1,39 @@ +package com.baeldung.swaggerresponseapi.controller; + +import com.baeldung.swaggerresponseapi.model.Product; +import com.baeldung.swaggerresponseapi.service.ProductService; + +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +public class ProductController { + private final ProductService productService; + + public ProductController(ProductService productService) { + this.productService = productService; + } + + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Product successfully added!") }) + @PostMapping("/create") + public Product addProduct(@RequestBody Product product) { + return productService.addProducts(product); + } + + @ApiResponses(value = { @ApiResponse(content = { @Content(mediaType = "application/json", + array = @ArraySchema(schema = @Schema(implementation = Product.class))) }) }) + @GetMapping("/products") + public List getProductsList() { + return productService.getProductsList(); + } +} diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java new file mode 100644 index 0000000000..0a100582fc --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java @@ -0,0 +1,15 @@ +package com.baeldung.swaggerresponseapi.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class Product { + String code; + String name; +} diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java new file mode 100644 index 0000000000..5e7533d6f4 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java @@ -0,0 +1,21 @@ +package com.baeldung.swaggerresponseapi.service; + +import com.baeldung.swaggerresponseapi.model.Product; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class ProductService { + List productsList = new ArrayList<>(); + + public Product addProducts(Product product) { + productsList.add(product); + return product; + } + + public List getProductsList() { + return productsList; + } +} diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/resources/application.properties b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/resources/application.properties new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/ProductIntegrationTest.java b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/ProductIntegrationTest.java new file mode 100644 index 0000000000..ef6a8953e2 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/ProductIntegrationTest.java @@ -0,0 +1,76 @@ +package com.baeldung.swaggerresponseapi; + +import com.baeldung.swaggerresponseapi.controller.ProductController; +import com.baeldung.swaggerresponseapi.model.Product; +import com.baeldung.swaggerresponseapi.service.ProductService; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import java.util.Arrays; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.reset; +import static org.hamcrest.CoreMatchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@WebMvcTest(ProductController.class) +public class ProductIntegrationTest { + + @Autowired + MockMvc mock; + + @MockBean + private ProductService productService; + + @Test + public void givenProduct_whenAddNewProduct_thenReturnValidStatusCode() throws Exception { + Product product = new Product("1001", "Milk"); + given(productService.addProducts(any(Product.class))).willReturn(product); + + mock.perform(post("/create").contentType(MediaType.APPLICATION_JSON) + .content(toJsonString(product))) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("1001")); + + reset(productService); + } + + @Test + public void givenProductsList_whenGetAllProducts_thenReturnValidProducts() throws Exception { + Product product1 = new Product("1001", "Milk"); + Product product2 = new Product("2002", "Butter"); + + given(productService.getProductsList()).willReturn(Arrays.asList(product1, product2)); + + mock.perform(get("/products").contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andDo(print()) + .andExpect(jsonPath("$[0].code", is(product1.getCode()))) + .andExpect(jsonPath("$[1].name", is(product2.getName()))); + + reset(productService); + } + + public String toJsonString(Product product) throws JsonProcessingException { + ObjectMapper om = new ObjectMapper(); + String json = om.writeValueAsString(product); + return json; + } +} diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplicationTests.java b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplicationTests.java new file mode 100644 index 0000000000..9e8c6ee0fa --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplicationTests.java @@ -0,0 +1,13 @@ +package com.baeldung.swaggerresponseapi; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class SwaggerResponseApiApplicationTests { + + @Test + void contextLoads() { + } + +} From f62de535543e8f04bfaa073ae2eaf185492fd0cd Mon Sep 17 00:00:00 2001 From: sanitaso Date: Fri, 25 Feb 2022 15:25:38 +0100 Subject: [PATCH 058/249] modify pom --- .../spring-boot-springdoc/swaggerResponseAPI/pom.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/pom.xml b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/pom.xml index 17544290e4..c168248df2 100644 --- a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/pom.xml +++ b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/pom.xml @@ -3,9 +3,10 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung.spring-boot-modules - spring-boot-disable-logging - 1.0.0-SNAPSHOT + org.springframework.boot + spring-boot-starter-parent + 2.6.3 + com.baeldung swaggerResponseAPI From 6aa40fd5fbc9f713e763dea82f9832203dc71e49 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Fri, 25 Feb 2022 20:43:35 +0000 Subject: [PATCH 059/249] [JAVA-10127] Update commented out modules in pom --- pom.xml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/pom.xml b/pom.xml index 99217774e9..e55743990a 100644 --- a/pom.xml +++ b/pom.xml @@ -400,7 +400,6 @@ dagger data-structures ddd - deeplearning4j discord4j disruptor @@ -432,7 +431,6 @@ hazelcast helidon httpclient - httpclient-simple hystrix @@ -482,8 +480,8 @@ kubernetes ksqldb - language-interop - libraries-2 + language-interop + libraries-2 libraries-3 libraries-apache-commons libraries-apache-commons-collections @@ -519,12 +517,12 @@ micronaut microprofile msf4j - + mustache mybatis netflix-modules - + netty ninja open-liberty @@ -885,7 +883,6 @@ dagger data-structures ddd - deeplearning4j discord4j disruptor @@ -916,7 +913,6 @@ hazelcast helidon httpclient - httpclient-simple hystrix @@ -1003,12 +999,12 @@ micronaut microprofile msf4j - + mustache mybatis netflix-modules - + netty ninja open-liberty @@ -1198,7 +1194,6 @@ wildfly xml xstream - @@ -1339,12 +1334,15 @@ core-java-modules/core-java-time-measurements core-java-modules/core-java-networking-3 core-java-modules/multimodulemavenproject + ddd-modules + httpclient-2 + libraries-concurrency persistence-modules/sirix persistence-modules/spring-data-cassandra-2 quarkus-vs-springboot quarkus-jandex - spring-boot-modules/spring-boot-cassandre - spring-boot-modules/spring-boot-camel + spring-boot-modules/spring-boot-cassandre + spring-boot-modules/spring-boot-camel testing-modules/testing-assertions @@ -1397,12 +1395,15 @@ core-java-modules/core-java-networking-3 core-java-modules/multimodulemavenproject core-java-modules/core-java-strings + ddd-modules + httpclient-2 + libraries-concurrency persistence-modules/sirix persistence-modules/spring-data-cassandra-2 quarkus-vs-springboot quarkus-jandex - spring-boot-modules/spring-boot-cassandre - spring-boot-modules/spring-boot-camel + spring-boot-modules/spring-boot-cassandre + spring-boot-modules/spring-boot-camel testing-modules/testing-assertions @@ -1470,7 +1471,6 @@ 0.0.1 3.12.2 3.0.0 - 3.13.0 1.18.20 1.4.200 From e65fe9db25acc832bc07af7057aeb9034b7be7b2 Mon Sep 17 00:00:00 2001 From: Elmar Mammadov Date: Sat, 26 Feb 2022 05:24:07 +0100 Subject: [PATCH 060/249] BAEL-5350: Java - How to create new Entry (key, value) (#11817) * BAEL-5350: 1. Added example usage of creating entries with Java itself 2. Added example usage of creating entries with Apache commons collecttions & Guava 3. Custom entry class and its usages * BAEL-5350: 1. Created unit tests * BAEL-5350: 1. simplifed assertion for java 9 entry creation * BAEL-5350: 1. moved into core-java-collections-maps-4 module 2. updated custom entry class and its unit test --- .../core-java-collections-maps-4/pom.xml | 25 +++- .../entries/SimpleCustomKeyValue.java | 53 ++++++++ .../entries/EntriesExampleUnitTest.java | 113 ++++++++++++++++++ .../entries/SimpleCustomKeyValueUnitTest.java | 31 +++++ core-java-modules/pom.xml | 1 - pom.xml | 2 + 6 files changed, 222 insertions(+), 3 deletions(-) create mode 100644 core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/entries/SimpleCustomKeyValue.java create mode 100644 core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/entries/EntriesExampleUnitTest.java create mode 100644 core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/entries/SimpleCustomKeyValueUnitTest.java diff --git a/core-java-modules/core-java-collections-maps-4/pom.xml b/core-java-modules/core-java-collections-maps-4/pom.xml index be467dd57b..e5afd87bbe 100644 --- a/core-java-modules/core-java-collections-maps-4/pom.xml +++ b/core-java-modules/core-java-collections-maps-4/pom.xml @@ -15,6 +15,16 @@ + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + com.google.guava + guava + ${guava.version} + junit junit @@ -37,12 +47,23 @@ + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + UTF-8 - 1.8 - 1.8 + 1.9 + 1.9
\ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/entries/SimpleCustomKeyValue.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/entries/SimpleCustomKeyValue.java new file mode 100644 index 0000000000..b2925cd508 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/entries/SimpleCustomKeyValue.java @@ -0,0 +1,53 @@ +package com.baeldung.entries; + +import java.util.Map; +import java.util.Objects; +import java.util.StringJoiner; + +public class SimpleCustomKeyValue implements Map.Entry { + + private final K key; + private V value; + + public SimpleCustomKeyValue(K key, V value) { + this.key = key; + this.value = value; + } + + @Override + public K getKey() { + return key; + } + + @Override + public V getValue() { + return value; + } + + @Override + public V setValue(V value) { + return this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SimpleCustomKeyValue that = (SimpleCustomKeyValue) o; + return Objects.equals(key, that.key) && Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(key, value); + } + + @Override + public String toString() { + return new StringJoiner(", ", SimpleCustomKeyValue.class.getSimpleName() + "[", "]").add("key=" + key).add("value=" + value).toString(); + } +} diff --git a/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/entries/EntriesExampleUnitTest.java b/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/entries/EntriesExampleUnitTest.java new file mode 100644 index 0000000000..954a4a4f22 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/entries/EntriesExampleUnitTest.java @@ -0,0 +1,113 @@ +package com.baeldung.entries; + +import com.google.common.collect.Maps; +import org.apache.commons.collections4.KeyValue; +import org.apache.commons.collections4.keyvalue.DefaultMapEntry; +import org.apache.commons.collections4.keyvalue.UnmodifiableMapEntry; +import org.junit.jupiter.api.Test; + +import java.util.AbstractMap; +import java.util.Map; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + +public class EntriesExampleUnitTest { + + @Test + public void givenEntries_whenVerifying_thenShouldContainKeyValues() { + AbstractMap.SimpleEntry firstEntry = new AbstractMap.SimpleEntry<>("key1", "value1"); + AbstractMap.SimpleEntry secondEntry = new AbstractMap.SimpleEntry<>("key2", "value2"); + AbstractMap.SimpleEntry thirdEntry = new AbstractMap.SimpleEntry<>(firstEntry); + thirdEntry.setValue("a different value"); + + assertThat(Stream.of(firstEntry, secondEntry, thirdEntry)) + .extracting("key", "value") + .containsExactly( + tuple("key1", "value1"), + tuple("key2", "value2"), + tuple("key1", "a different value")); + } + + @Test + public void givenImmutableEntries_whenVerifying_thenShouldContainKeyValues() { + AbstractMap.SimpleImmutableEntry firstEntry = new AbstractMap.SimpleImmutableEntry<>("key1", "value1"); + AbstractMap.SimpleImmutableEntry secondEntry = new AbstractMap.SimpleImmutableEntry<>("key2", "value2"); + AbstractMap.SimpleImmutableEntry thirdEntry = new AbstractMap.SimpleImmutableEntry<>(firstEntry); + + assertThat(Stream.of(firstEntry, secondEntry, thirdEntry)) + .extracting("key", "value") + .containsExactly( + tuple("key1", "value1"), + tuple("key2", "value2"), + tuple("key1", "value1")); + } + + @Test + public void givenImmutableEntryUsingJava9_whenVerifying_thenShouldContainKeyValues() { + Map.Entry entry = Map.entry("key", "value"); + + assertThat(entry.getKey()) + .isEqualTo("key"); + assertThat(entry.getValue()) + .isEqualTo("value"); + } + + + @Test + public void givenEntriesWithApacheCommons_whenVerifying_thenShouldContainKeyValues() { + Map.Entry firstEntry = new DefaultMapEntry<>("key1", "value1"); + KeyValue secondEntry = new DefaultMapEntry<>("key2", "value2"); + + KeyValue thirdEntry = new DefaultMapEntry<>(firstEntry); + KeyValue fourthEntry = new DefaultMapEntry<>(secondEntry); + + firstEntry.setValue("a different value"); + + assertThat(firstEntry) + .extracting("key", "value") + .containsExactly("key1", "a different value"); + + assertThat(Stream.of(secondEntry, thirdEntry, fourthEntry)) + .extracting("key", "value") + .containsExactly( + tuple("key2", "value2"), + tuple("key1", "value1"), + tuple("key2", "value2")); + } + + @Test + public void givenImmutableEntriesWithApacheCommons_whenVerifying_thenShouldContainKeyValues() { + Map.Entry firstEntry = new UnmodifiableMapEntry<>("key1", "value1"); + KeyValue secondEntry = new UnmodifiableMapEntry<>("key2", "value2"); + + KeyValue thirdEntry = new UnmodifiableMapEntry<>(firstEntry); + KeyValue fourthEntry = new UnmodifiableMapEntry<>(secondEntry); + + assertThat(firstEntry) + .extracting("key", "value") + .containsExactly("key1", "value1"); + + assertThat(Stream.of(secondEntry, thirdEntry, fourthEntry)) + .extracting("key", "value") + .containsExactly( + tuple("key2", "value2"), + tuple("key1", "value1"), + tuple("key2", "value2")); + } + + + @Test + public void givenImmutableEntriesWithGuava_whenVerifying_thenShouldContainKeyValues() { + Map.Entry firstEntry = Maps.immutableEntry("key1", "value1"); + Map.Entry secondEntry = Maps.immutableEntry("key2", "value2"); + + assertThat(Stream.of(firstEntry, secondEntry)) + .extracting("key", "value") + .containsExactly( + tuple("key1", "value1"), + tuple("key2", "value2")); + } + +} diff --git a/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/entries/SimpleCustomKeyValueUnitTest.java b/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/entries/SimpleCustomKeyValueUnitTest.java new file mode 100644 index 0000000000..d055bb1653 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/entries/SimpleCustomKeyValueUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.entries; + +import com.google.common.collect.ImmutableMap; +import org.junit.jupiter.api.Test; + +import java.util.Map; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + +class SimpleCustomKeyValueUnitTest { + + + @Test + public void givenModifiableEntries_whenVerifying_thenShouldContainKeyValues() { + Map.Entry firstEntry = new SimpleCustomKeyValue<>("key1", "value1"); + + Map.Entry secondEntry = new SimpleCustomKeyValue<>("key2", "value2"); + secondEntry.setValue("different value"); + + Map map = Map.ofEntries(firstEntry, secondEntry); + + assertThat(map) + .isEqualTo(ImmutableMap.builder() + .put("key1", "value1") + .put("key2", "different value") + .build()); + } + +} \ No newline at end of file diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index a25cf11454..60319b4de4 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -38,7 +38,6 @@ core-java-collections-maps core-java-collections-maps-2 core-java-collections-maps-3 - core-java-collections-maps-4 core-java-concurrency-2 core-java-concurrency-advanced core-java-concurrency-advanced-2 diff --git a/pom.xml b/pom.xml index cab9a34f02..3138b5c610 100644 --- a/pom.xml +++ b/pom.xml @@ -1329,6 +1329,7 @@ core-java-modules/core-java-collections-set + core-java-modules/core-java-collections-maps-4 core-java-modules/core-java-date-operations-1 core-java-modules/core-java-datetime-conversion core-java-modules/core-java-datetime-string @@ -1387,6 +1388,7 @@ core-java-modules/core-java-collections-set + core-java-modules/core-java-collections-maps-4 core-java-modules/core-java-date-operations-1 core-java-modules/core-java-datetime-conversion core-java-modules/core-java-datetime-string From 768e9ae3877175cee1d12f3eb1de71fe81eddf41 Mon Sep 17 00:00:00 2001 From: Sameer Date: Sat, 26 Feb 2022 17:25:31 +0530 Subject: [PATCH 061/249] Maven Classifier (#11833) * maven classifier * static imports * bumped up plugin versions Co-authored-by: s9m33r --- .../maven-classifier-example-consumer/pom.xml | 53 ++++++++ .../classifier/consumer/FuelStation.java | 17 +++ .../consumer/FuelStationUnitTest.java | 21 +++ .../maven-classifier-example-provider/pom.xml | 122 ++++++++++++++++++ .../provider/factory/CarFactory.java | 14 ++ .../classifier/provider/model/Car.java | 26 ++++ .../provider/model/PowerSource.java | 5 + .../provider/factory/CarFactoryUnitTest.java | 32 +++++ .../classifier/provider/stub/CarStub.java | 17 +++ maven-modules/maven-classifier/pom.xml | 27 ++++ maven-modules/pom.xml | 1 + 11 files changed, 335 insertions(+) create mode 100644 maven-modules/maven-classifier/maven-classifier-example-consumer/pom.xml create mode 100644 maven-modules/maven-classifier/maven-classifier-example-consumer/src/main/java/com/baeldung/maven/classifier/consumer/FuelStation.java create mode 100644 maven-modules/maven-classifier/maven-classifier-example-consumer/src/test/java/com/baeldung/maven/classifier/consumer/FuelStationUnitTest.java create mode 100644 maven-modules/maven-classifier/maven-classifier-example-provider/pom.xml create mode 100644 maven-modules/maven-classifier/maven-classifier-example-provider/src/main/java/com/baeldung/maven/dependency/classifier/provider/factory/CarFactory.java create mode 100644 maven-modules/maven-classifier/maven-classifier-example-provider/src/main/java/com/baeldung/maven/dependency/classifier/provider/model/Car.java create mode 100644 maven-modules/maven-classifier/maven-classifier-example-provider/src/main/java/com/baeldung/maven/dependency/classifier/provider/model/PowerSource.java create mode 100644 maven-modules/maven-classifier/maven-classifier-example-provider/src/test/java/com/baeldung/maven/dependency/classifier/provider/factory/CarFactoryUnitTest.java create mode 100644 maven-modules/maven-classifier/maven-classifier-example-provider/src/test/java/com/baeldung/maven/dependency/classifier/provider/stub/CarStub.java create mode 100644 maven-modules/maven-classifier/pom.xml diff --git a/maven-modules/maven-classifier/maven-classifier-example-consumer/pom.xml b/maven-modules/maven-classifier/maven-classifier-example-consumer/pom.xml new file mode 100644 index 0000000000..cbf046ed5a --- /dev/null +++ b/maven-modules/maven-classifier/maven-classifier-example-consumer/pom.xml @@ -0,0 +1,53 @@ + + + + maven-classifier + com.baeldung + 0.0.1-SNAPSHOT + + + 4.0.0 + + maven-classifier-example-consumer + + + 8 + 8 + + + + + com.baeldung + maven-classifier-example-provider + 0.0.1-SNAPSHOT + + + com.baeldung + maven-classifier-example-provider + 0.0.1-SNAPSHOT + arbitrary + + + + + + + + + + com.baeldung + maven-classifier-example-provider + 0.0.1-SNAPSHOT + sources + + + com.baeldung + maven-classifier-example-provider + 0.0.1-SNAPSHOT + tests + + + + diff --git a/maven-modules/maven-classifier/maven-classifier-example-consumer/src/main/java/com/baeldung/maven/classifier/consumer/FuelStation.java b/maven-modules/maven-classifier/maven-classifier-example-consumer/src/main/java/com/baeldung/maven/classifier/consumer/FuelStation.java new file mode 100644 index 0000000000..cf5dc03457 --- /dev/null +++ b/maven-modules/maven-classifier/maven-classifier-example-consumer/src/main/java/com/baeldung/maven/classifier/consumer/FuelStation.java @@ -0,0 +1,17 @@ + +package com.baeldung.maven.classifier.consumer; + +import com.baeldung.maven.dependency.classifier.provider.model.Car; +import com.baeldung.maven.dependency.classifier.provider.model.PowerSource; + +public class FuelStation { + + public FuelStation.Zone refill(Car car) { + return PowerSource.BATTERY.equals(car.getPowerSource()) ? FuelStation.Zone.BATTERY : FuelStation.Zone.UNKNOWN; + } + + public enum Zone { + BATTERY, + UNKNOWN + } +} diff --git a/maven-modules/maven-classifier/maven-classifier-example-consumer/src/test/java/com/baeldung/maven/classifier/consumer/FuelStationUnitTest.java b/maven-modules/maven-classifier/maven-classifier-example-consumer/src/test/java/com/baeldung/maven/classifier/consumer/FuelStationUnitTest.java new file mode 100644 index 0000000000..e04afb8276 --- /dev/null +++ b/maven-modules/maven-classifier/maven-classifier-example-consumer/src/test/java/com/baeldung/maven/classifier/consumer/FuelStationUnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.maven.classifier.consumer; + +import com.baeldung.maven.classifier.consumer.FuelStation.Zone; +import com.baeldung.maven.dependency.classifier.provider.model.Car; +import com.baeldung.maven.dependency.classifier.provider.stub.CarStub; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class FuelStationUnitTest { + + @Test + @DisplayName("Given fuel type battery When request for refill Then Return Battery Zone") + public void givenFuelTypeBattery_whenRequestToRefill_thenReturnBatteryZone() { + FuelStation fuelStation = new FuelStation(); + Car electricCar = CarStub.ELECTRIC_CAR; + + assertEquals(Zone.BATTERY, fuelStation.refill(electricCar)); + } +} diff --git a/maven-modules/maven-classifier/maven-classifier-example-provider/pom.xml b/maven-modules/maven-classifier/maven-classifier-example-provider/pom.xml new file mode 100644 index 0000000000..12cb4fa1a2 --- /dev/null +++ b/maven-modules/maven-classifier/maven-classifier-example-provider/pom.xml @@ -0,0 +1,122 @@ + + + + 4.0.0 + + + maven-classifier + com.baeldung + 0.0.1-SNAPSHOT + + + maven-classifier-example-provider + 0.0.1-SNAPSHOT + + + 8 + 8 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.0 + + + JDK 8 + compile + + compile + + + 8 + 8 + true + + + + + + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.2 + + + Arbitrary + + jar + + + arbitrary + + + + Test Jar + + test-jar + + + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + attach-sources + verify + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.3.2 + + + attach-javadocs + + jar + + + + + + + diff --git a/maven-modules/maven-classifier/maven-classifier-example-provider/src/main/java/com/baeldung/maven/dependency/classifier/provider/factory/CarFactory.java b/maven-modules/maven-classifier/maven-classifier-example-provider/src/main/java/com/baeldung/maven/dependency/classifier/provider/factory/CarFactory.java new file mode 100644 index 0000000000..285fec9ddc --- /dev/null +++ b/maven-modules/maven-classifier/maven-classifier-example-provider/src/main/java/com/baeldung/maven/dependency/classifier/provider/factory/CarFactory.java @@ -0,0 +1,14 @@ +package com.baeldung.maven.dependency.classifier.provider.factory; + +import com.baeldung.maven.dependency.classifier.provider.model.Car; +import com.baeldung.maven.dependency.classifier.provider.model.Car.Type; + +public class CarFactory { + + public static Car manufacture(Type carType) { + Car car = new Car(); + car.setType(carType); + + return car; + } +} diff --git a/maven-modules/maven-classifier/maven-classifier-example-provider/src/main/java/com/baeldung/maven/dependency/classifier/provider/model/Car.java b/maven-modules/maven-classifier/maven-classifier-example-provider/src/main/java/com/baeldung/maven/dependency/classifier/provider/model/Car.java new file mode 100644 index 0000000000..93d5091f55 --- /dev/null +++ b/maven-modules/maven-classifier/maven-classifier-example-provider/src/main/java/com/baeldung/maven/dependency/classifier/provider/model/Car.java @@ -0,0 +1,26 @@ +package com.baeldung.maven.dependency.classifier.provider.model; + +public class Car { + private Type type; + private PowerSource fuelType; + + public Type getType() { + return this.type; + } + + public void setType(Type carType) { + this.type = carType; + } + + public PowerSource getPowerSource() { + return this.fuelType; + } + + public void setFuelType(PowerSource fuelType) { + this.fuelType = fuelType; + } + + public enum Type { + ELECTRIC + } +} diff --git a/maven-modules/maven-classifier/maven-classifier-example-provider/src/main/java/com/baeldung/maven/dependency/classifier/provider/model/PowerSource.java b/maven-modules/maven-classifier/maven-classifier-example-provider/src/main/java/com/baeldung/maven/dependency/classifier/provider/model/PowerSource.java new file mode 100644 index 0000000000..3ac5d98efe --- /dev/null +++ b/maven-modules/maven-classifier/maven-classifier-example-provider/src/main/java/com/baeldung/maven/dependency/classifier/provider/model/PowerSource.java @@ -0,0 +1,5 @@ +package com.baeldung.maven.dependency.classifier.provider.model; + +public enum PowerSource { + BATTERY +} diff --git a/maven-modules/maven-classifier/maven-classifier-example-provider/src/test/java/com/baeldung/maven/dependency/classifier/provider/factory/CarFactoryUnitTest.java b/maven-modules/maven-classifier/maven-classifier-example-provider/src/test/java/com/baeldung/maven/dependency/classifier/provider/factory/CarFactoryUnitTest.java new file mode 100644 index 0000000000..36f0b36f1c --- /dev/null +++ b/maven-modules/maven-classifier/maven-classifier-example-provider/src/test/java/com/baeldung/maven/dependency/classifier/provider/factory/CarFactoryUnitTest.java @@ -0,0 +1,32 @@ + +package com.baeldung.maven.dependency.classifier.provider.factory; + +import com.baeldung.maven.dependency.classifier.provider.model.Car; +import com.baeldung.maven.dependency.classifier.provider.model.Car.Type; +import com.baeldung.maven.dependency.classifier.provider.model.PowerSource; +import com.baeldung.maven.dependency.classifier.provider.stub.CarStub; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class CarFactoryUnitTest { + + @Test + @DisplayName("Given Car type When CarFactory manufacture is called Then create a Car of the given type") + public void givenCarType_whenCarFactoryManufactureCalled_thenCreateCarOfGivenType() { + Car car = CarFactory.manufacture(Type.ELECTRIC); + + assertNotNull(car, "CarFactory didn't manufacture a car. Car is null"); + assertEquals(Type.ELECTRIC, car.getType()); + } + + @Test + @DisplayName("Given an electric car When asked for fuel type Then return Battery") + public void givenElectricCar_whenAskedForFuelType_thenReturnBattery() { + Car car = CarStub.ELECTRIC_CAR; + + assertEquals(PowerSource.BATTERY, car.getPowerSource()); + } +} diff --git a/maven-modules/maven-classifier/maven-classifier-example-provider/src/test/java/com/baeldung/maven/dependency/classifier/provider/stub/CarStub.java b/maven-modules/maven-classifier/maven-classifier-example-provider/src/test/java/com/baeldung/maven/dependency/classifier/provider/stub/CarStub.java new file mode 100644 index 0000000000..54dbd1166f --- /dev/null +++ b/maven-modules/maven-classifier/maven-classifier-example-provider/src/test/java/com/baeldung/maven/dependency/classifier/provider/stub/CarStub.java @@ -0,0 +1,17 @@ +package com.baeldung.maven.dependency.classifier.provider.stub; + +import com.baeldung.maven.dependency.classifier.provider.model.Car; +import com.baeldung.maven.dependency.classifier.provider.model.PowerSource; +import com.baeldung.maven.dependency.classifier.provider.model.Car.Type; +import org.mockito.Mockito; + +import static org.mockito.Mockito.when; + +public class CarStub { + public static Car ELECTRIC_CAR = Mockito.mock(Car.class); + + static { + when(ELECTRIC_CAR.getType()).thenReturn(Type.ELECTRIC); + when(ELECTRIC_CAR.getPowerSource()).thenReturn(PowerSource.BATTERY); + } +} diff --git a/maven-modules/maven-classifier/pom.xml b/maven-modules/maven-classifier/pom.xml new file mode 100644 index 0000000000..6b75f60893 --- /dev/null +++ b/maven-modules/maven-classifier/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + maven-classifier + pom + 0.0.1-SNAPSHOT + + + maven-classifier-example-consumer + maven-classifier-example-provider + + + + com.baeldung + maven-modules + 0.0.1-SNAPSHOT + + + + 8 + 8 + + + diff --git a/maven-modules/pom.xml b/maven-modules/pom.xml index 21bc0e72e1..37be581804 100644 --- a/maven-modules/pom.xml +++ b/maven-modules/pom.xml @@ -36,6 +36,7 @@ maven-surefire-plugin maven-parent-pom-resolution maven-simple + maven-classifier From eae57f5496a6e56d73393f295fcc6955d0a65273 Mon Sep 17 00:00:00 2001 From: Kapil Khandelwal Date: Mon, 28 Feb 2022 01:51:17 +0530 Subject: [PATCH 062/249] BAEL-5359: Updating Multiple Fields in a MongoDB Document (#11861) * BAEL-5359: Updating Multiple Fields in a MongoDB Document * BAEL-5359: Add test class file * BAEL-5359: Rename UpdateMultipleFieldsUnitTest.java to UpdateMultipleFieldsLiveTest.java --- .../mongo/update/MultipleFieldsExample.java | 44 ++++++++++ .../mongo/update/UpdateMultipleFields.java | 36 +++++++++ .../update/UpdateMultipleFieldsLiveTest.java | 80 +++++++++++++++++++ 3 files changed, 160 insertions(+) create mode 100644 persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/MultipleFieldsExample.java create mode 100644 persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateMultipleFields.java create mode 100644 persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateMultipleFieldsLiveTest.java diff --git a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/MultipleFieldsExample.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/MultipleFieldsExample.java new file mode 100644 index 0000000000..b2fcddeafb --- /dev/null +++ b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/MultipleFieldsExample.java @@ -0,0 +1,44 @@ +package com.baeldung.mongo.update; + +import org.bson.Document; + +import com.mongodb.BasicDBObject; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.result.UpdateResult; + +public class MultipleFieldsExample { + + public static void main(String[] args) { + + // + // Connect to cluster (default is localhost:27017) + // + + MongoClient mongoClient = new MongoClient("localhost", 27017); + MongoDatabase database = mongoClient.getDatabase("baeldung"); + MongoCollection collection = database.getCollection("employee"); + + // + // Filter on the basis of employee_id + // + + BasicDBObject searchQuery = new BasicDBObject("employee_id", 794875); + + // + // Update the fields in Document + // + + BasicDBObject updateFields = new BasicDBObject(); + updateFields.append("department_id", 3); + updateFields.append("job", "Sales Manager"); + BasicDBObject setQuery = new BasicDBObject(); + setQuery.append("$set", updateFields); + UpdateResult updateResult = collection.updateMany(searchQuery, setQuery); + + System.out.println("updateResult:- " + updateResult); + System.out.println("updateResult:- " + updateResult.getModifiedCount()); + + } +} diff --git a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateMultipleFields.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateMultipleFields.java new file mode 100644 index 0000000000..20af6d99cb --- /dev/null +++ b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateMultipleFields.java @@ -0,0 +1,36 @@ +package com.baeldung.mongo.update; + +import org.bson.Document; + +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Updates; +import com.mongodb.client.result.UpdateResult; + +public class UpdateMultipleFields { + + public static void main(String[] args) { + + // + // Connect to cluster + // + + MongoClient mongoClient = new MongoClient("localhost", 27007); + MongoDatabase database = mongoClient.getDatabase("baeldung"); + MongoCollection collection = database.getCollection("employee"); + + // + // Update query + // + + UpdateResult updateResult = collection.updateMany(Filters.eq("employee_id", 794875), + Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager"))); + + System.out.println("updateResult:- " + updateResult); + System.out.println("updateResult:- " + updateResult.getModifiedCount()); + + } + +} \ No newline at end of file diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateMultipleFieldsLiveTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateMultipleFieldsLiveTest.java new file mode 100644 index 0000000000..d1538d5312 --- /dev/null +++ b/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateMultipleFieldsLiveTest.java @@ -0,0 +1,80 @@ +package com.baeldung.update; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; + +import org.bson.Document; +import org.junit.Before; +import org.junit.Test; + +import com.mongodb.BasicDBObject; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Updates; +import com.mongodb.client.result.UpdateResult; + +public class UpdateMultipleFieldsLiveTest { + + private MongoClient mongoClient; + private MongoDatabase db; + private MongoCollection collection; + + @Before + public void setup() { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + db = mongoClient.getDatabase("baeldung"); + collection = db.getCollection("employee"); + + collection.insertOne(Document.parse( + "{'employee_id':794875,'employee_name': 'David smith','job': 'Sales Representative','department_id': 2,'salary': 20000,'hire_date': NumberLong(\"1643969311817\")}")); + } + } + + @Test + public void updateMultipleFieldsUsingDBObject() { + + BasicDBObject searchQuery = new BasicDBObject("employee_id", 794875); + BasicDBObject updateFields = new BasicDBObject(); + updateFields.append("department_id", 4); + updateFields.append("job", "Sales Manager"); + BasicDBObject setQuery = new BasicDBObject(); + setQuery.append("$set", updateFields); + + collection.updateMany(searchQuery, setQuery); + + Document nameDoc = collection.find(Filters.eq("employee_id", 794875)).first(); + assertNotNull(nameDoc); + assertFalse(nameDoc.isEmpty()); + + String job = nameDoc.get("job", String.class); + assertNotNull(job); + + Integer department_id = nameDoc.get("department_id", Integer.class); + assertNotNull(department_id); + + } + + @Test + public void updateMultipleFieldsUsingDocument() { + + collection.updateMany(Filters.eq("employee_id", 794875), + Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager"))); + + Document nameDoc = collection.find(Filters.eq("employee_id", 794875)).first(); + assertNotNull(nameDoc); + assertFalse(nameDoc.isEmpty()); + + String job = nameDoc.get("job", String.class); + assertNotNull(job); + + Integer department_id = nameDoc.get("department_id", Integer.class); + assertNotNull(department_id); + + } + +} From e10e20a24be601c031dc677001043f01b075f93a Mon Sep 17 00:00:00 2001 From: Chukwuka Onyekachukwu Victor Date: Sun, 27 Feb 2022 21:33:39 +0100 Subject: [PATCH 063/249] Added a new Class and few test cases to the core-java-modules (#11867) * added a new project: hexagonal architecture * Added some test cases for the project * Added a new project to demo the error: variable might not have been initialized * Added a new Class to the core-java-modules * Added a New Class to the core-java-module --- .../VariableMightNotHaveBeenInitialized.java | 45 +++++++++++++++++++ ...leMightNotHaveBeenInitializedUnitTest.java | 24 ++++++++++ 2 files changed, 69 insertions(+) create mode 100644 core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitialized.java create mode 100644 core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitializedUnitTest.java diff --git a/core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitialized.java b/core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitialized.java new file mode 100644 index 0000000000..64118e6307 --- /dev/null +++ b/core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitialized.java @@ -0,0 +1,45 @@ +package com.baeldung.exception.variablemightnothavebeeninitialized; + +public class VariableMightNotHaveBeenInitialized { + + private static int instanceVariableCount; + + /** + * Method would not compile if lines 14 and 18 are uncommented. + */ + public static void countEven() { + //uninstantiated + int count; + int[] arr = new int[]{23, 56, 89, 12, 23}; + for (int i = 0; i < arr.length; i++) { + if ((arr[i] % 2) == 0) { + // count++; + } + + } + // System.out.println("Total Even Numbers : " + count); + } + + public static int countEvenUsingInstanceVariable(int[] arr) { + + for (int i = 0; i < arr.length; i++) { + if ((arr[i] % 2) == 0) { + instanceVariableCount++; + } + + } + return instanceVariableCount; + } + + public static int countEvenUsingIfElse(int[] arr, int args) { + int count; + count = args > 0 ? args : 0; + for (int i = 0; i < arr.length; i++) { + if ((arr[i] % 2) == 0) { + count++; + } + + } + return count; + } +} diff --git a/core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitializedUnitTest.java b/core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitializedUnitTest.java new file mode 100644 index 0000000000..c4773d6442 --- /dev/null +++ b/core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitializedUnitTest.java @@ -0,0 +1,24 @@ +package com.baeldung.exception.variablemightnothavebeeninitialized; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class VariableMightNotHaveBeenInitializedUnitTest { + + @Test + public void usingInstanceVariable_returnCount() { + int[] arr = new int[]{1, 2, 3, 4, 5, 6}; + int value = VariableMightNotHaveBeenInitialized.countEvenUsingInstanceVariable(arr); + + assertEquals(3, value); + } + + @Test + public void usingArgumentsAndIfElse_returnCount() { + int[] arr = new int[]{1, 2, 3, 4, 5, 6}; + int value = VariableMightNotHaveBeenInitialized.countEvenUsingIfElse(arr, 2); + + assertEquals(5, value); + } +} From c0aef97db63ded4d6981c17a385fecb8fab7a9b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor?= Date: Sun, 27 Feb 2022 23:06:47 +0100 Subject: [PATCH 064/249] BAEL-4626 First draft of the source code for the article: https://drafts.baeldung.com/wp-admin/post.php?post=127644&action=edit --- apache-tomcat/pom.xml | 34 + apache-tomcat/sso/.dockerignore | 24 + apache-tomcat/sso/README.md | 5 + apache-tomcat/sso/docker-compose.yml | 11 + apache-tomcat/sso/pom.xml | 18 + apache-tomcat/sso/res/conf/catalina.policy | 264 + .../sso/res/conf/catalina.properties | 208 + apache-tomcat/sso/res/conf/context.xml | 31 + .../sso/res/conf/jaspic-providers.xml | 23 + .../sso/res/conf/jaspic-providers.xsd | 53 + apache-tomcat/sso/res/conf/logging.properties | 90 + apache-tomcat/sso/res/conf/server.xml | 151 + apache-tomcat/sso/res/conf/tomcat-users.xml | 59 + apache-tomcat/sso/res/conf/tomcat-users.xsd | 59 + apache-tomcat/sso/res/conf/web.xml | 4742 +++++++++++++++++ .../sso/webapps/ping/WEB-INF/web.xml | 50 + apache-tomcat/sso/webapps/ping/index.html | 9 + apache-tomcat/sso/webapps/ping/logging.html | 26 + .../sso/webapps/ping/logging_error.html | 10 + .../sso/webapps/ping/private/index.html | 9 + .../sso/webapps/pong/WEB-INF/web.xml | 51 + apache-tomcat/sso/webapps/pong/index.html | 9 + apache-tomcat/sso/webapps/pong/logging.html | 26 + .../sso/webapps/pong/logging_error.html | 10 + .../sso/webapps/pong/private/index.html | 9 + 25 files changed, 5981 insertions(+) create mode 100644 apache-tomcat/pom.xml create mode 100644 apache-tomcat/sso/.dockerignore create mode 100644 apache-tomcat/sso/README.md create mode 100644 apache-tomcat/sso/docker-compose.yml create mode 100644 apache-tomcat/sso/pom.xml create mode 100644 apache-tomcat/sso/res/conf/catalina.policy create mode 100644 apache-tomcat/sso/res/conf/catalina.properties create mode 100644 apache-tomcat/sso/res/conf/context.xml create mode 100644 apache-tomcat/sso/res/conf/jaspic-providers.xml create mode 100644 apache-tomcat/sso/res/conf/jaspic-providers.xsd create mode 100644 apache-tomcat/sso/res/conf/logging.properties create mode 100644 apache-tomcat/sso/res/conf/server.xml create mode 100644 apache-tomcat/sso/res/conf/tomcat-users.xml create mode 100644 apache-tomcat/sso/res/conf/tomcat-users.xsd create mode 100644 apache-tomcat/sso/res/conf/web.xml create mode 100644 apache-tomcat/sso/webapps/ping/WEB-INF/web.xml create mode 100644 apache-tomcat/sso/webapps/ping/index.html create mode 100644 apache-tomcat/sso/webapps/ping/logging.html create mode 100644 apache-tomcat/sso/webapps/ping/logging_error.html create mode 100644 apache-tomcat/sso/webapps/ping/private/index.html create mode 100644 apache-tomcat/sso/webapps/pong/WEB-INF/web.xml create mode 100644 apache-tomcat/sso/webapps/pong/index.html create mode 100644 apache-tomcat/sso/webapps/pong/logging.html create mode 100644 apache-tomcat/sso/webapps/pong/logging_error.html create mode 100644 apache-tomcat/sso/webapps/pong/private/index.html diff --git a/apache-tomcat/pom.xml b/apache-tomcat/pom.xml new file mode 100644 index 0000000000..36487f2108 --- /dev/null +++ b/apache-tomcat/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + com.baeldung + apache-tomcat + 1.0.0-SNAPSHOT + apache-tomcat + pom + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + sso + + + + install + + + + org.codehaus.mojo + exec-maven-plugin + + + + + \ No newline at end of file diff --git a/apache-tomcat/sso/.dockerignore b/apache-tomcat/sso/.dockerignore new file mode 100644 index 0000000000..95520b4e81 --- /dev/null +++ b/apache-tomcat/sso/.dockerignore @@ -0,0 +1,24 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/bin +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +README.md diff --git a/apache-tomcat/sso/README.md b/apache-tomcat/sso/README.md new file mode 100644 index 0000000000..2b515178e0 --- /dev/null +++ b/apache-tomcat/sso/README.md @@ -0,0 +1,5 @@ +### Related articles + +### Launch Example using Docker + +$ docker-compose up \ No newline at end of file diff --git a/apache-tomcat/sso/docker-compose.yml b/apache-tomcat/sso/docker-compose.yml new file mode 100644 index 0000000000..e150de7ba1 --- /dev/null +++ b/apache-tomcat/sso/docker-compose.yml @@ -0,0 +1,11 @@ +version: '3.4' + +services: + tomcatsso: + image: tomcat:10-jdk17-openjdk-slim-buster + volumes: + - ./res/conf:/usr/local/tomcat/conf + - ./webapps:/usr/local/tomcat/webapps + ports: + - 8080:8080 + command: ["catalina.sh", "run"] \ No newline at end of file diff --git a/apache-tomcat/sso/pom.xml b/apache-tomcat/sso/pom.xml new file mode 100644 index 0000000000..d46fe45f66 --- /dev/null +++ b/apache-tomcat/sso/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + com.baeldung.apache_tomcat + sso + 1.0.0-SNAPSHOT + pom + + + com.baeldung + apache-tomcat + 1.0.0-SNAPSHOT + + + diff --git a/apache-tomcat/sso/res/conf/catalina.policy b/apache-tomcat/sso/res/conf/catalina.policy new file mode 100644 index 0000000000..7aab95dee5 --- /dev/null +++ b/apache-tomcat/sso/res/conf/catalina.policy @@ -0,0 +1,264 @@ +// 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. + +// ============================================================================ +// catalina.policy - Security Policy Permissions for Tomcat +// +// This file contains a default set of security policies to be enforced (by the +// JVM) when Catalina is executed with the "-security" option. In addition +// to the permissions granted here, the following additional permissions are +// granted to each web application: +// +// * Read access to the web application's document root directory +// * Read, write and delete access to the web application's working directory +// ============================================================================ + + +// ========== SYSTEM CODE PERMISSIONS ========================================= + + +// These permissions apply to javac +grant codeBase "file:${java.home}/lib/-" { + permission java.security.AllPermission; +}; + +// These permissions apply to all shared system extensions +grant codeBase "file:${java.home}/jre/lib/ext/-" { + permission java.security.AllPermission; +}; + +// These permissions apply to javac when ${java.home} points at $JAVA_HOME/jre +grant codeBase "file:${java.home}/../lib/-" { + permission java.security.AllPermission; +}; + +// These permissions apply to all shared system extensions when +// ${java.home} points at $JAVA_HOME/jre +grant codeBase "file:${java.home}/lib/ext/-" { + permission java.security.AllPermission; +}; + +// This permission is required when using javac to compile JSPs on Java 9 +// onwards +//grant codeBase "jrt:/jdk.compiler" { +// permission java.security.AllPermission; +//}; + + +// ========== CATALINA CODE PERMISSIONS ======================================= + +// These permissions apply to the daemon code +grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" { + permission java.security.AllPermission; +}; + +// These permissions apply to the logging API +// Note: If tomcat-juli.jar is in ${catalina.base} and not in ${catalina.home}, +// update this section accordingly. +// grant codeBase "file:${catalina.base}/bin/tomcat-juli.jar" {..} +grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" { + permission java.io.FilePermission + "${java.home}${file.separator}lib${file.separator}logging.properties", "read"; + + permission java.io.FilePermission + "${catalina.base}${file.separator}conf${file.separator}logging.properties", "read"; + permission java.io.FilePermission + "${catalina.base}${file.separator}logs", "read, write"; + permission java.io.FilePermission + "${catalina.base}${file.separator}logs${file.separator}*", "read, write, delete"; + + permission java.lang.RuntimePermission "shutdownHooks"; + permission java.lang.RuntimePermission "getClassLoader"; + permission java.lang.RuntimePermission "setContextClassLoader"; + + permission java.lang.management.ManagementPermission "monitor"; + + permission java.util.logging.LoggingPermission "control"; + + permission java.util.PropertyPermission "java.util.logging.config.class", "read"; + permission java.util.PropertyPermission "java.util.logging.config.file", "read"; + permission java.util.PropertyPermission "org.apache.juli.AsyncMaxRecordCount", "read"; + permission java.util.PropertyPermission "org.apache.juli.AsyncOverflowDropType", "read"; + permission java.util.PropertyPermission "org.apache.juli.ClassLoaderLogManager.debug", "read"; + permission java.util.PropertyPermission "catalina.base", "read"; + + // Note: To enable per context logging configuration, permit read access to + // the appropriate file. Be sure that the logging configuration is + // secure before enabling such access. + // E.g. for the examples web application (uncomment and unwrap + // the following to be on a single line): + // permission java.io.FilePermission "${catalina.base}${file.separator} + // webapps${file.separator}examples${file.separator}WEB-INF + // ${file.separator}classes${file.separator}logging.properties", "read"; +}; + +// These permissions apply to the server startup code +grant codeBase "file:${catalina.home}/bin/bootstrap.jar" { + permission java.security.AllPermission; +}; + +// These permissions apply to the servlet API classes +// and those that are shared across all class loaders +// located in the "lib" directory +grant codeBase "file:${catalina.home}/lib/-" { + permission java.security.AllPermission; +}; + + +// If using a per instance lib directory, i.e. ${catalina.base}/lib, +// then the following permission will need to be uncommented +// grant codeBase "file:${catalina.base}/lib/-" { +// permission java.security.AllPermission; +// }; + + +// ========== WEB APPLICATION PERMISSIONS ===================================== + + +// These permissions are granted by default to all web applications +// In addition, a web application will be given a read FilePermission +// for all files and directories in its document root. +grant { + // Required for JNDI lookup of named JDBC DataSource's and + // javamail named MimePart DataSource used to send mail + permission java.util.PropertyPermission "java.home", "read"; + permission java.util.PropertyPermission "java.naming.*", "read"; + permission java.util.PropertyPermission "javax.sql.*", "read"; + + // OS Specific properties to allow read access + permission java.util.PropertyPermission "os.name", "read"; + permission java.util.PropertyPermission "os.version", "read"; + permission java.util.PropertyPermission "os.arch", "read"; + permission java.util.PropertyPermission "file.separator", "read"; + permission java.util.PropertyPermission "path.separator", "read"; + permission java.util.PropertyPermission "line.separator", "read"; + + // JVM properties to allow read access + permission java.util.PropertyPermission "java.version", "read"; + permission java.util.PropertyPermission "java.vendor", "read"; + permission java.util.PropertyPermission "java.vendor.url", "read"; + permission java.util.PropertyPermission "java.class.version", "read"; + permission java.util.PropertyPermission "java.specification.version", "read"; + permission java.util.PropertyPermission "java.specification.vendor", "read"; + permission java.util.PropertyPermission "java.specification.name", "read"; + + permission java.util.PropertyPermission "java.vm.specification.version", "read"; + permission java.util.PropertyPermission "java.vm.specification.vendor", "read"; + permission java.util.PropertyPermission "java.vm.specification.name", "read"; + permission java.util.PropertyPermission "java.vm.version", "read"; + permission java.util.PropertyPermission "java.vm.vendor", "read"; + permission java.util.PropertyPermission "java.vm.name", "read"; + + // Required for OpenJMX + permission java.lang.RuntimePermission "getAttribute"; + + // Allow read of JAXP compliant XML parser debug + permission java.util.PropertyPermission "jaxp.debug", "read"; + + // All JSPs need to be able to read this package + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat"; + + // Precompiled JSPs need access to these packages. + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.el"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime"; + permission java.lang.RuntimePermission + "accessClassInPackage.org.apache.jasper.runtime.*"; + + // Applications using WebSocket need to be able to access these packages + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat.websocket"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat.websocket.server"; +}; + + +// The Manager application needs access to the following packages to support the +// session display functionality. It also requires the custom Tomcat +// DeployXmlPermission to enable the use of META-INF/context.xml +// These settings support the following configurations: +// - default CATALINA_HOME == CATALINA_BASE +// - CATALINA_HOME != CATALINA_BASE, per instance Manager in CATALINA_BASE +// - CATALINA_HOME != CATALINA_BASE, shared Manager in CATALINA_HOME +grant codeBase "file:${catalina.base}/webapps/manager/-" { + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.ha.session"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.util"; + permission org.apache.catalina.security.DeployXmlPermission "manager"; +}; +grant codeBase "file:${catalina.home}/webapps/manager/-" { + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.ha.session"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.util"; + permission org.apache.catalina.security.DeployXmlPermission "manager"; +}; + +// The Host Manager application needs the custom Tomcat DeployXmlPermission to +// enable the use of META-INF/context.xml +// These settings support the following configurations: +// - default CATALINA_HOME == CATALINA_BASE +// - CATALINA_HOME != CATALINA_BASE, per instance Host Manager in CATALINA_BASE +// - CATALINA_HOME != CATALINA_BASE, shared Host Manager in CATALINA_HOME +grant codeBase "file:${catalina.base}/webapps/host-manager/-" { + permission org.apache.catalina.security.DeployXmlPermission "host-manager"; +}; +grant codeBase "file:${catalina.home}/webapps/host-manager/-" { + permission org.apache.catalina.security.DeployXmlPermission "host-manager"; +}; + + +// You can assign additional permissions to particular web applications by +// adding additional "grant" entries here, based on the code base for that +// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files. +// +// Different permissions can be granted to JSP pages, classes loaded from +// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/ +// directory, or even to individual jar files in the /WEB-INF/lib/ directory. +// +// For instance, assume that the standard "examples" application +// included a JDBC driver that needed to establish a network connection to the +// corresponding database and used the scrape taglib to get the weather from +// the NOAA web server. You might create a "grant" entries like this: +// +// The permissions granted to the context root directory apply to JSP pages. +// grant codeBase "file:${catalina.base}/webapps/examples/-" { +// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect"; +// permission java.net.SocketPermission "*.noaa.gov:80", "connect"; +// }; +// +// The permissions granted to the context WEB-INF/classes directory +// grant codeBase "file:${catalina.base}/webapps/examples/WEB-INF/classes/-" { +// }; +// +// The permission granted to your JDBC driver +// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar!/-" { +// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect"; +// }; +// The permission granted to the scrape taglib +// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/scrape.jar!/-" { +// permission java.net.SocketPermission "*.noaa.gov:80", "connect"; +// }; + +// To grant permissions for web applications using packed WAR files, use the +// Tomcat specific WAR url scheme. +// +// The permissions granted to the entire web application +// grant codeBase "war:file:${catalina.base}/webapps/examples.war*/-" { +// }; +// +// The permissions granted to a specific JAR +// grant codeBase "war:file:${catalina.base}/webapps/examples.war*/WEB-INF/lib/foo.jar" { +// }; \ No newline at end of file diff --git a/apache-tomcat/sso/res/conf/catalina.properties b/apache-tomcat/sso/res/conf/catalina.properties new file mode 100644 index 0000000000..d73a8bfbb2 --- /dev/null +++ b/apache-tomcat/sso/res/conf/catalina.properties @@ -0,0 +1,208 @@ +# 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. + +# +# List of comma-separated packages that start with or equal this string +# will cause a security exception to be thrown when +# passed to checkPackageAccess unless the +# corresponding RuntimePermission ("accessClassInPackage."+package) has +# been granted. +package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.tomcat. +# +# List of comma-separated packages that start with or equal this string +# will cause a security exception to be thrown when +# passed to checkPackageDefinition unless the +# corresponding RuntimePermission ("defineClassInPackage."+package) has +# been granted. +# +# by default, no packages are restricted for definition, and none of +# the class loaders supplied with the JDK call checkPackageDefinition. +# +package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,\ +org.apache.jasper.,org.apache.naming.,org.apache.tomcat. + +# +# +# List of comma-separated paths defining the contents of the "common" +# classloader. Prefixes should be used to define what is the repository type. +# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute. +# If left as blank,the JVM system loader will be used as Catalina's "common" +# loader. +# Examples: +# "foo": Add this folder as a class repository +# "foo/*.jar": Add all the JARs of the specified folder as class +# repositories +# "foo/bar.jar": Add bar.jar as a class repository +# +# Note: Values are enclosed in double quotes ("...") in case either the +# ${catalina.base} path or the ${catalina.home} path contains a comma. +# Because double quotes are used for quoting, the double quote character +# may not appear in a path. +common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar" + +# +# List of comma-separated paths defining the contents of the "server" +# classloader. Prefixes should be used to define what is the repository type. +# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute. +# If left as blank, the "common" loader will be used as Catalina's "server" +# loader. +# Examples: +# "foo": Add this folder as a class repository +# "foo/*.jar": Add all the JARs of the specified folder as class +# repositories +# "foo/bar.jar": Add bar.jar as a class repository +# +# Note: Values may be enclosed in double quotes ("...") in case either the +# ${catalina.base} path or the ${catalina.home} path contains a comma. +# Because double quotes are used for quoting, the double quote character +# may not appear in a path. +server.loader= + +# +# List of comma-separated paths defining the contents of the "shared" +# classloader. Prefixes should be used to define what is the repository type. +# Path may be relative to the CATALINA_BASE path or absolute. If left as blank, +# the "common" loader will be used as Catalina's "shared" loader. +# Examples: +# "foo": Add this folder as a class repository +# "foo/*.jar": Add all the JARs of the specified folder as class +# repositories +# "foo/bar.jar": Add bar.jar as a class repository +# Please note that for single jars, e.g. bar.jar, you need the URL form +# starting with file:. +# +# Note: Values may be enclosed in double quotes ("...") in case either the +# ${catalina.base} path or the ${catalina.home} path contains a comma. +# Because double quotes are used for quoting, the double quote character +# may not appear in a path. +shared.loader= + +# Default list of JAR files that should not be scanned using the JarScanner +# functionality. This is typically used to scan JARs for configuration +# information. JARs that do not contain such information may be excluded from +# the scan to speed up the scanning process. This is the default list. JARs on +# this list are excluded from all scans. The list must be a comma separated list +# of JAR file names. +# The list of JARs to skip may be over-ridden at a Context level for individual +# scan types by configuring a JarScanner with a nested JarScanFilter. +# The JARs listed below include: +# - Tomcat Bootstrap JARs +# - Tomcat API JARs +# - Catalina JARs +# - Jasper JARs +# - Tomcat JARs +# - Common non-Tomcat JARs +# - Test JARs (JUnit, Cobertura and dependencies) +tomcat.util.scan.StandardJarScanFilter.jarsToSkip=\ +annotations-api.jar,\ +ant-junit*.jar,\ +ant-launcher.jar,\ +ant.jar,\ +asm-*.jar,\ +aspectj*.jar,\ +bootstrap.jar,\ +catalina-ant.jar,\ +catalina-ha.jar,\ +catalina-ssi.jar,\ +catalina-storeconfig.jar,\ +catalina-tribes.jar,\ +catalina.jar,\ +cglib-*.jar,\ +cobertura-*.jar,\ +commons-beanutils*.jar,\ +commons-codec*.jar,\ +commons-collections*.jar,\ +commons-daemon.jar,\ +commons-dbcp*.jar,\ +commons-digester*.jar,\ +commons-fileupload*.jar,\ +commons-httpclient*.jar,\ +commons-io*.jar,\ +commons-lang*.jar,\ +commons-logging*.jar,\ +commons-math*.jar,\ +commons-pool*.jar,\ +derby-*.jar,\ +dom4j-*.jar,\ +easymock-*.jar,\ +ecj-*.jar,\ +el-api.jar,\ +geronimo-spec-jaxrpc*.jar,\ +h2*.jar,\ +hamcrest-*.jar,\ +hibernate*.jar,\ +httpclient*.jar,\ +icu4j-*.jar,\ +jakartaee-migration-*.jar,\ +jasper-el.jar,\ +jasper.jar,\ +jaspic-api.jar,\ +jaxb-*.jar,\ +jaxen-*.jar,\ +jdom-*.jar,\ +jetty-*.jar,\ +jmx-tools.jar,\ +jmx.jar,\ +jsp-api.jar,\ +jstl.jar,\ +jta*.jar,\ +junit-*.jar,\ +junit.jar,\ +log4j*.jar,\ +mail*.jar,\ +objenesis-*.jar,\ +oraclepki.jar,\ +oro-*.jar,\ +servlet-api-*.jar,\ +servlet-api.jar,\ +slf4j*.jar,\ +taglibs-standard-spec-*.jar,\ +tagsoup-*.jar,\ +tomcat-api.jar,\ +tomcat-coyote.jar,\ +tomcat-dbcp.jar,\ +tomcat-i18n-*.jar,\ +tomcat-jdbc.jar,\ +tomcat-jni.jar,\ +tomcat-juli-adapters.jar,\ +tomcat-juli.jar,\ +tomcat-util-scan.jar,\ +tomcat-util.jar,\ +tomcat-websocket.jar,\ +tools.jar,\ +websocket-api.jar,\ +wsdl4j*.jar,\ +xercesImpl.jar,\ +xml-apis.jar,\ +xmlParserAPIs-*.jar,\ +xmlParserAPIs.jar,\ +xom-*.jar + +# Default list of JAR files that should be scanned that overrides the default +# jarsToSkip list above. This is typically used to include a specific JAR that +# has been excluded by a broad file name pattern in the jarsToSkip list. +# The list of JARs to scan may be over-ridden at a Context level for individual +# scan types by configuring a JarScanner with a nested JarScanFilter. +tomcat.util.scan.StandardJarScanFilter.jarsToScan=\ +log4j-taglib*.jar,\ +log4j-web*.jar,\ +log4javascript*.jar,\ +slf4j-taglib*.jar + +# String cache configuration. +tomcat.util.buf.StringCache.byte.enabled=true +#tomcat.util.buf.StringCache.char.enabled=true +#tomcat.util.buf.StringCache.trainThreshold=500000 +#tomcat.util.buf.StringCache.cacheSize=5000 diff --git a/apache-tomcat/sso/res/conf/context.xml b/apache-tomcat/sso/res/conf/context.xml new file mode 100644 index 0000000000..0a7cfaca8e --- /dev/null +++ b/apache-tomcat/sso/res/conf/context.xml @@ -0,0 +1,31 @@ + + + + + + + + WEB-INF/web.xml + WEB-INF/tomcat-web.xml + ${catalina.base}/conf/web.xml + + + + diff --git a/apache-tomcat/sso/res/conf/jaspic-providers.xml b/apache-tomcat/sso/res/conf/jaspic-providers.xml new file mode 100644 index 0000000000..cdebf87253 --- /dev/null +++ b/apache-tomcat/sso/res/conf/jaspic-providers.xml @@ -0,0 +1,23 @@ + + + + + diff --git a/apache-tomcat/sso/res/conf/jaspic-providers.xsd b/apache-tomcat/sso/res/conf/jaspic-providers.xsd new file mode 100644 index 0000000000..1004a11914 --- /dev/null +++ b/apache-tomcat/sso/res/conf/jaspic-providers.xsd @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apache-tomcat/sso/res/conf/logging.properties b/apache-tomcat/sso/res/conf/logging.properties new file mode 100644 index 0000000000..9413465201 --- /dev/null +++ b/apache-tomcat/sso/res/conf/logging.properties @@ -0,0 +1,90 @@ +# 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. + +handlers = 1catalina.org.apache.juli.AsyncFileHandler, 2localhost.org.apache.juli.AsyncFileHandler, 3manager.org.apache.juli.AsyncFileHandler, 4host-manager.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler + +.handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler + +############################################################ +# Handler specific properties. +# Describes specific configuration info for Handlers. +############################################################ + +1catalina.org.apache.juli.AsyncFileHandler.level = ALL +1catalina.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs +1catalina.org.apache.juli.AsyncFileHandler.prefix = catalina. +1catalina.org.apache.juli.AsyncFileHandler.maxDays = 90 +1catalina.org.apache.juli.AsyncFileHandler.encoding = UTF-8 + +2localhost.org.apache.juli.AsyncFileHandler.level = FINE +2localhost.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs +2localhost.org.apache.juli.AsyncFileHandler.prefix = localhost. +2localhost.org.apache.juli.AsyncFileHandler.maxDays = 90 +2localhost.org.apache.juli.AsyncFileHandler.encoding = UTF-8 + +3manager.org.apache.juli.AsyncFileHandler.level = FINE +3manager.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs +3manager.org.apache.juli.AsyncFileHandler.prefix = manager. +3manager.org.apache.juli.AsyncFileHandler.maxDays = 90 +3manager.org.apache.juli.AsyncFileHandler.encoding = UTF-8 + +4host-manager.org.apache.juli.AsyncFileHandler.level = FINE +4host-manager.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs +4host-manager.org.apache.juli.AsyncFileHandler.prefix = host-manager. +4host-manager.org.apache.juli.AsyncFileHandler.maxDays = 90 +4host-manager.org.apache.juli.AsyncFileHandler.encoding = UTF-8 + +java.util.logging.ConsoleHandler.level = FINE +java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter +java.util.logging.ConsoleHandler.encoding = UTF-8 + +org.apache.catalina.authenticator.level = ALL +org.apache.catalina.authenticator.formatter = org.apache.juli.OneLineFormatter +org.apache.catalina.authenticator.encoding = UTF-8 + +org.apache.catalina.Realm.level = ALL +org.apache.catalina.Realm.formatter = org.apache.juli.OneLineFormatter +org.apache.catalina.Realm.encoding = UTF-8 + +org.apache.catalina.realm.level = ALL +org.apache.catalina.realm.formatter = org.apache.juli.OneLineFormatter +org.apache.catalina.realm.encoding = UTF-8 + +############################################################ +# Facility specific properties. +# Provides extra control for each logger. +############################################################ + +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = ALL +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.AsyncFileHandler + +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.AsyncFileHandler + +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.AsyncFileHandler + +# For example, set the org.apache.catalina.util.LifecycleBase logger to log +# each component that extends LifecycleBase changing state: +# org.apache.catalina.util.LifecycleBase.level = FINE + +# To see debug messages in TldLocationsCache, uncomment the following line: +#org.apache.jasper.compiler.TldLocationsCache.level = FINE + +# To see debug messages for HTTP/2 handling, uncomment the following line: +#org.apache.coyote.http2.level = FINE + +# To see debug messages for WebSocket handling, uncomment the following line: +#org.apache.tomcat.websocket.level = FINE diff --git a/apache-tomcat/sso/res/conf/server.xml b/apache-tomcat/sso/res/conf/server.xml new file mode 100644 index 0000000000..35027c9b5f --- /dev/null +++ b/apache-tomcat/sso/res/conf/server.xml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apache-tomcat/sso/res/conf/tomcat-users.xml b/apache-tomcat/sso/res/conf/tomcat-users.xml new file mode 100644 index 0000000000..2372af6e2b --- /dev/null +++ b/apache-tomcat/sso/res/conf/tomcat-users.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + diff --git a/apache-tomcat/sso/res/conf/tomcat-users.xsd b/apache-tomcat/sso/res/conf/tomcat-users.xsd new file mode 100644 index 0000000000..6a3446c0ef --- /dev/null +++ b/apache-tomcat/sso/res/conf/tomcat-users.xsd @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apache-tomcat/sso/res/conf/web.xml b/apache-tomcat/sso/res/conf/web.xml new file mode 100644 index 0000000000..130a49dcdb --- /dev/null +++ b/apache-tomcat/sso/res/conf/web.xml @@ -0,0 +1,4742 @@ + + + + + + + + + + + + + + + + + UTF-8 + UTF-8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default + org.apache.catalina.servlets.DefaultServlet + + debug + 0 + + + listings + false + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jsp + org.apache.jasper.servlet.JspServlet + + fork + false + + + xpoweredBy + false + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default + / + + + + + jsp + *.jsp + *.jspx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + 123 + application/vnd.lotus-1-2-3 + + + 3dml + text/vnd.in3d.3dml + + + 3ds + image/x-3ds + + + 3g2 + video/3gpp2 + + + 3gp + video/3gpp + + + 7z + application/x-7z-compressed + + + aab + application/x-authorware-bin + + + aac + audio/x-aac + + + aam + application/x-authorware-map + + + aas + application/x-authorware-seg + + + abs + audio/x-mpeg + + + abw + application/x-abiword + + + ac + application/pkix-attr-cert + + + acc + application/vnd.americandynamics.acc + + + ace + application/x-ace-compressed + + + acu + application/vnd.acucobol + + + acutc + application/vnd.acucorp + + + adp + audio/adpcm + + + aep + application/vnd.audiograph + + + afm + application/x-font-type1 + + + afp + application/vnd.ibm.modcap + + + ahead + application/vnd.ahead.space + + + ai + application/postscript + + + aif + audio/x-aiff + + + aifc + audio/x-aiff + + + aiff + audio/x-aiff + + + aim + application/x-aim + + + air + application/vnd.adobe.air-application-installer-package+zip + + + ait + application/vnd.dvb.ait + + + ami + application/vnd.amiga.ami + + + anx + application/annodex + + + apk + application/vnd.android.package-archive + + + appcache + text/cache-manifest + + + application + application/x-ms-application + + + apr + application/vnd.lotus-approach + + + arc + application/x-freearc + + + art + image/x-jg + + + asc + application/pgp-signature + + + asf + video/x-ms-asf + + + asm + text/x-asm + + + aso + application/vnd.accpac.simply.aso + + + asx + video/x-ms-asf + + + atc + application/vnd.acucorp + + + atom + application/atom+xml + + + atomcat + application/atomcat+xml + + + atomsvc + application/atomsvc+xml + + + atx + application/vnd.antix.game-component + + + au + audio/basic + + + avi + video/x-msvideo + + + avx + video/x-rad-screenplay + + + aw + application/applixware + + + axa + audio/annodex + + + axv + video/annodex + + + azf + application/vnd.airzip.filesecure.azf + + + azs + application/vnd.airzip.filesecure.azs + + + azw + application/vnd.amazon.ebook + + + bat + application/x-msdownload + + + bcpio + application/x-bcpio + + + bdf + application/x-font-bdf + + + bdm + application/vnd.syncml.dm+wbxml + + + bed + application/vnd.realvnc.bed + + + bh2 + application/vnd.fujitsu.oasysprs + + + bin + application/octet-stream + + + blb + application/x-blorb + + + blorb + application/x-blorb + + + bmi + application/vnd.bmi + + + bmp + image/bmp + + + body + text/html + + + book + application/vnd.framemaker + + + box + application/vnd.previewsystems.box + + + boz + application/x-bzip2 + + + bpk + application/octet-stream + + + btif + image/prs.btif + + + bz + application/x-bzip + + + bz2 + application/x-bzip2 + + + c + text/x-c + + + c11amc + application/vnd.cluetrust.cartomobile-config + + + c11amz + application/vnd.cluetrust.cartomobile-config-pkg + + + c4d + application/vnd.clonk.c4group + + + c4f + application/vnd.clonk.c4group + + + c4g + application/vnd.clonk.c4group + + + c4p + application/vnd.clonk.c4group + + + c4u + application/vnd.clonk.c4group + + + cab + application/vnd.ms-cab-compressed + + + caf + audio/x-caf + + + cap + application/vnd.tcpdump.pcap + + + car + application/vnd.curl.car + + + cat + application/vnd.ms-pki.seccat + + + cb7 + application/x-cbr + + + cba + application/x-cbr + + + cbr + application/x-cbr + + + cbt + application/x-cbr + + + cbz + application/x-cbr + + + cc + text/x-c + + + cct + application/x-director + + + ccxml + application/ccxml+xml + + + cdbcmsg + application/vnd.contact.cmsg + + + cdf + application/x-cdf + + + cdkey + application/vnd.mediastation.cdkey + + + cdmia + application/cdmi-capability + + + cdmic + application/cdmi-container + + + cdmid + application/cdmi-domain + + + cdmio + application/cdmi-object + + + cdmiq + application/cdmi-queue + + + cdx + chemical/x-cdx + + + cdxml + application/vnd.chemdraw+xml + + + cdy + application/vnd.cinderella + + + cer + application/pkix-cert + + + cfs + application/x-cfs-compressed + + + cgm + image/cgm + + + chat + application/x-chat + + + chm + application/vnd.ms-htmlhelp + + + chrt + application/vnd.kde.kchart + + + cif + chemical/x-cif + + + cii + application/vnd.anser-web-certificate-issue-initiation + + + cil + application/vnd.ms-artgalry + + + cla + application/vnd.claymore + + + class + application/java + + + clkk + application/vnd.crick.clicker.keyboard + + + clkp + application/vnd.crick.clicker.palette + + + clkt + application/vnd.crick.clicker.template + + + clkw + application/vnd.crick.clicker.wordbank + + + clkx + application/vnd.crick.clicker + + + clp + application/x-msclip + + + cmc + application/vnd.cosmocaller + + + cmdf + chemical/x-cmdf + + + cml + chemical/x-cml + + + cmp + application/vnd.yellowriver-custom-menu + + + cmx + image/x-cmx + + + cod + application/vnd.rim.cod + + + com + application/x-msdownload + + + conf + text/plain + + + cpio + application/x-cpio + + + cpp + text/x-c + + + cpt + application/mac-compactpro + + + crd + application/x-mscardfile + + + crl + application/pkix-crl + + + crt + application/x-x509-ca-cert + + + cryptonote + application/vnd.rig.cryptonote + + + csh + application/x-csh + + + csml + chemical/x-csml + + + csp + application/vnd.commonspace + + + css + text/css + + + cst + application/x-director + + + csv + text/csv + + + cu + application/cu-seeme + + + curl + text/vnd.curl + + + cww + application/prs.cww + + + cxt + application/x-director + + + cxx + text/x-c + + + dae + model/vnd.collada+xml + + + daf + application/vnd.mobius.daf + + + dart + application/vnd.dart + + + dataless + application/vnd.fdsn.seed + + + davmount + application/davmount+xml + + + dbk + application/docbook+xml + + + dcr + application/x-director + + + dcurl + text/vnd.curl.dcurl + + + dd2 + application/vnd.oma.dd2+xml + + + ddd + application/vnd.fujixerox.ddd + + + deb + application/x-debian-package + + + def + text/plain + + + deploy + application/octet-stream + + + der + application/x-x509-ca-cert + + + dfac + application/vnd.dreamfactory + + + dgc + application/x-dgc-compressed + + + dib + image/bmp + + + dic + text/x-c + + + dir + application/x-director + + + dis + application/vnd.mobius.dis + + + dist + application/octet-stream + + + distz + application/octet-stream + + + djv + image/vnd.djvu + + + djvu + image/vnd.djvu + + + dll + application/x-msdownload + + + dmg + application/x-apple-diskimage + + + dmp + application/vnd.tcpdump.pcap + + + dms + application/octet-stream + + + dna + application/vnd.dna + + + doc + application/msword + + + docm + application/vnd.ms-word.document.macroenabled.12 + + + docx + application/vnd.openxmlformats-officedocument.wordprocessingml.document + + + dot + application/msword + + + dotm + application/vnd.ms-word.template.macroenabled.12 + + + dotx + application/vnd.openxmlformats-officedocument.wordprocessingml.template + + + dp + application/vnd.osgi.dp + + + dpg + application/vnd.dpgraph + + + dra + audio/vnd.dra + + + dsc + text/prs.lines.tag + + + dssc + application/dssc+der + + + dtb + application/x-dtbook+xml + + + dtd + application/xml-dtd + + + dts + audio/vnd.dts + + + dtshd + audio/vnd.dts.hd + + + dump + application/octet-stream + + + dv + video/x-dv + + + dvb + video/vnd.dvb.file + + + dvi + application/x-dvi + + + dwf + model/vnd.dwf + + + dwg + image/vnd.dwg + + + dxf + image/vnd.dxf + + + dxp + application/vnd.spotfire.dxp + + + dxr + application/x-director + + + ecelp4800 + audio/vnd.nuera.ecelp4800 + + + ecelp7470 + audio/vnd.nuera.ecelp7470 + + + ecelp9600 + audio/vnd.nuera.ecelp9600 + + + ecma + application/ecmascript + + + edm + application/vnd.novadigm.edm + + + edx + application/vnd.novadigm.edx + + + efif + application/vnd.picsel + + + ei6 + application/vnd.pg.osasli + + + elc + application/octet-stream + + + emf + application/x-msmetafile + + + eml + message/rfc822 + + + emma + application/emma+xml + + + emz + application/x-msmetafile + + + eol + audio/vnd.digital-winds + + + eot + application/vnd.ms-fontobject + + + eps + application/postscript + + + epub + application/epub+zip + + + es3 + application/vnd.eszigno3+xml + + + esa + application/vnd.osgi.subsystem + + + esf + application/vnd.epson.esf + + + et3 + application/vnd.eszigno3+xml + + + etx + text/x-setext + + + eva + application/x-eva + + + evy + application/x-envoy + + + exe + application/octet-stream + + + exi + application/exi + + + ext + application/vnd.novadigm.ext + + + ez + application/andrew-inset + + + ez2 + application/vnd.ezpix-album + + + ez3 + application/vnd.ezpix-package + + + f + text/x-fortran + + + f4v + video/x-f4v + + + f77 + text/x-fortran + + + f90 + text/x-fortran + + + fbs + image/vnd.fastbidsheet + + + fcdt + application/vnd.adobe.formscentral.fcdt + + + fcs + application/vnd.isac.fcs + + + fdf + application/vnd.fdf + + + fe_launch + application/vnd.denovo.fcselayout-link + + + fg5 + application/vnd.fujitsu.oasysgp + + + fgd + application/x-director + + + fh + image/x-freehand + + + fh4 + image/x-freehand + + + fh5 + image/x-freehand + + + fh7 + image/x-freehand + + + fhc + image/x-freehand + + + fig + application/x-xfig + + + flac + audio/flac + + + fli + video/x-fli + + + flo + application/vnd.micrografx.flo + + + flv + video/x-flv + + + flw + application/vnd.kde.kivio + + + flx + text/vnd.fmi.flexstor + + + fly + text/vnd.fly + + + fm + application/vnd.framemaker + + + fnc + application/vnd.frogans.fnc + + + for + text/x-fortran + + + fpx + image/vnd.fpx + + + frame + application/vnd.framemaker + + + fsc + application/vnd.fsc.weblaunch + + + fst + image/vnd.fst + + + ftc + application/vnd.fluxtime.clip + + + fti + application/vnd.anser-web-funds-transfer-initiation + + + fvt + video/vnd.fvt + + + fxp + application/vnd.adobe.fxp + + + fxpl + application/vnd.adobe.fxp + + + fzs + application/vnd.fuzzysheet + + + g2w + application/vnd.geoplan + + + g3 + image/g3fax + + + g3w + application/vnd.geospace + + + gac + application/vnd.groove-account + + + gam + application/x-tads + + + gbr + application/rpki-ghostbusters + + + gca + application/x-gca-compressed + + + gdl + model/vnd.gdl + + + geo + application/vnd.dynageo + + + gex + application/vnd.geometry-explorer + + + ggb + application/vnd.geogebra.file + + + ggt + application/vnd.geogebra.tool + + + ghf + application/vnd.groove-help + + + gif + image/gif + + + gim + application/vnd.groove-identity-message + + + gml + application/gml+xml + + + gmx + application/vnd.gmx + + + gnumeric + application/x-gnumeric + + + gph + application/vnd.flographit + + + gpx + application/gpx+xml + + + gqf + application/vnd.grafeq + + + gqs + application/vnd.grafeq + + + gram + application/srgs + + + gramps + application/x-gramps-xml + + + gre + application/vnd.geometry-explorer + + + grv + application/vnd.groove-injector + + + grxml + application/srgs+xml + + + gsf + application/x-font-ghostscript + + + gtar + application/x-gtar + + + gtm + application/vnd.groove-tool-message + + + gtw + model/vnd.gtw + + + gv + text/vnd.graphviz + + + gxf + application/gxf + + + gxt + application/vnd.geonext + + + gz + application/x-gzip + + + h + text/x-c + + + h261 + video/h261 + + + h263 + video/h263 + + + h264 + video/h264 + + + hal + application/vnd.hal+xml + + + hbci + application/vnd.hbci + + + hdf + application/x-hdf + + + hh + text/x-c + + + hlp + application/winhlp + + + hpgl + application/vnd.hp-hpgl + + + hpid + application/vnd.hp-hpid + + + hps + application/vnd.hp-hps + + + hqx + application/mac-binhex40 + + + htc + text/x-component + + + htke + application/vnd.kenameaapp + + + htm + text/html + + + html + text/html + + + hvd + application/vnd.yamaha.hv-dic + + + hvp + application/vnd.yamaha.hv-voice + + + hvs + application/vnd.yamaha.hv-script + + + i2g + application/vnd.intergeo + + + icc + application/vnd.iccprofile + + + ice + x-conference/x-cooltalk + + + icm + application/vnd.iccprofile + + + ico + image/x-icon + + + ics + text/calendar + + + ief + image/ief + + + ifb + text/calendar + + + ifm + application/vnd.shana.informed.formdata + + + iges + model/iges + + + igl + application/vnd.igloader + + + igm + application/vnd.insors.igm + + + igs + model/iges + + + igx + application/vnd.micrografx.igx + + + iif + application/vnd.shana.informed.interchange + + + imp + application/vnd.accpac.simply.imp + + + ims + application/vnd.ms-ims + + + in + text/plain + + + ink + application/inkml+xml + + + inkml + application/inkml+xml + + + install + application/x-install-instructions + + + iota + application/vnd.astraea-software.iota + + + ipfix + application/ipfix + + + ipk + application/vnd.shana.informed.package + + + irm + application/vnd.ibm.rights-management + + + irp + application/vnd.irepository.package+xml + + + iso + application/x-iso9660-image + + + itp + application/vnd.shana.informed.formtemplate + + + ivp + application/vnd.immervision-ivp + + + ivu + application/vnd.immervision-ivu + + + jad + text/vnd.sun.j2me.app-descriptor + + + jam + application/vnd.jam + + + jar + application/java-archive + + + java + text/x-java-source + + + jisp + application/vnd.jisp + + + jlt + application/vnd.hp-jlyt + + + jnlp + application/x-java-jnlp-file + + + joda + application/vnd.joost.joda-archive + + + jpe + image/jpeg + + + jpeg + image/jpeg + + + jpg + image/jpeg + + + jpgm + video/jpm + + + jpgv + video/jpeg + + + jpm + video/jpm + + + js + application/javascript + + + jsf + text/plain + + + json + application/json + + + jsonml + application/jsonml+json + + + jspf + text/plain + + + kar + audio/midi + + + karbon + application/vnd.kde.karbon + + + kfo + application/vnd.kde.kformula + + + kia + application/vnd.kidspiration + + + kml + application/vnd.google-earth.kml+xml + + + kmz + application/vnd.google-earth.kmz + + + kne + application/vnd.kinar + + + knp + application/vnd.kinar + + + kon + application/vnd.kde.kontour + + + kpr + application/vnd.kde.kpresenter + + + kpt + application/vnd.kde.kpresenter + + + kpxx + application/vnd.ds-keypoint + + + ksp + application/vnd.kde.kspread + + + ktr + application/vnd.kahootz + + + ktx + image/ktx + + + ktz + application/vnd.kahootz + + + kwd + application/vnd.kde.kword + + + kwt + application/vnd.kde.kword + + + lasxml + application/vnd.las.las+xml + + + latex + application/x-latex + + + lbd + application/vnd.llamagraphics.life-balance.desktop + + + lbe + application/vnd.llamagraphics.life-balance.exchange+xml + + + les + application/vnd.hhe.lesson-player + + + lha + application/x-lzh-compressed + + + link66 + application/vnd.route66.link66+xml + + + list + text/plain + + + list3820 + application/vnd.ibm.modcap + + + listafp + application/vnd.ibm.modcap + + + lnk + application/x-ms-shortcut + + + log + text/plain + + + lostxml + application/lost+xml + + + lrf + application/octet-stream + + + lrm + application/vnd.ms-lrm + + + ltf + application/vnd.frogans.ltf + + + lvp + audio/vnd.lucent.voice + + + lwp + application/vnd.lotus-wordpro + + + lzh + application/x-lzh-compressed + + + m13 + application/x-msmediaview + + + m14 + application/x-msmediaview + + + m1v + video/mpeg + + + m21 + application/mp21 + + + m2a + audio/mpeg + + + m2v + video/mpeg + + + m3a + audio/mpeg + + + m3u + audio/x-mpegurl + + + m3u8 + application/vnd.apple.mpegurl + + + m4a + audio/mp4 + + + m4b + audio/mp4 + + + m4r + audio/mp4 + + + m4u + video/vnd.mpegurl + + + m4v + video/mp4 + + + ma + application/mathematica + + + mac + image/x-macpaint + + + mads + application/mads+xml + + + mag + application/vnd.ecowin.chart + + + maker + application/vnd.framemaker + + + man + text/troff + + + mar + application/octet-stream + + + mathml + application/mathml+xml + + + mb + application/mathematica + + + mbk + application/vnd.mobius.mbk + + + mbox + application/mbox + + + mc1 + application/vnd.medcalcdata + + + mcd + application/vnd.mcd + + + mcurl + text/vnd.curl.mcurl + + + mdb + application/x-msaccess + + + mdi + image/vnd.ms-modi + + + me + text/troff + + + mesh + model/mesh + + + meta4 + application/metalink4+xml + + + metalink + application/metalink+xml + + + mets + application/mets+xml + + + mfm + application/vnd.mfmp + + + mft + application/rpki-manifest + + + mgp + application/vnd.osgeo.mapguide.package + + + mgz + application/vnd.proteus.magazine + + + mid + audio/midi + + + midi + audio/midi + + + mie + application/x-mie + + + mif + application/x-mif + + + mime + message/rfc822 + + + mj2 + video/mj2 + + + mjp2 + video/mj2 + + + mk3d + video/x-matroska + + + mka + audio/x-matroska + + + mks + video/x-matroska + + + mkv + video/x-matroska + + + mlp + application/vnd.dolby.mlp + + + mmd + application/vnd.chipnuts.karaoke-mmd + + + mmf + application/vnd.smaf + + + mmr + image/vnd.fujixerox.edmics-mmr + + + mng + video/x-mng + + + mny + application/x-msmoney + + + mobi + application/x-mobipocket-ebook + + + mods + application/mods+xml + + + mov + video/quicktime + + + movie + video/x-sgi-movie + + + mp1 + audio/mpeg + + + mp2 + audio/mpeg + + + mp21 + application/mp21 + + + mp2a + audio/mpeg + + + mp3 + audio/mpeg + + + mp4 + video/mp4 + + + mp4a + audio/mp4 + + + mp4s + application/mp4 + + + mp4v + video/mp4 + + + mpa + audio/mpeg + + + mpc + application/vnd.mophun.certificate + + + mpe + video/mpeg + + + mpeg + video/mpeg + + + mpega + audio/x-mpeg + + + mpg + video/mpeg + + + mpg4 + video/mp4 + + + mpga + audio/mpeg + + + mpkg + application/vnd.apple.installer+xml + + + mpm + application/vnd.blueice.multipass + + + mpn + application/vnd.mophun.application + + + mpp + application/vnd.ms-project + + + mpt + application/vnd.ms-project + + + mpv2 + video/mpeg2 + + + mpy + application/vnd.ibm.minipay + + + mqy + application/vnd.mobius.mqy + + + mrc + application/marc + + + mrcx + application/marcxml+xml + + + ms + text/troff + + + mscml + application/mediaservercontrol+xml + + + mseed + application/vnd.fdsn.mseed + + + mseq + application/vnd.mseq + + + msf + application/vnd.epson.msf + + + msh + model/mesh + + + msi + application/x-msdownload + + + msl + application/vnd.mobius.msl + + + msty + application/vnd.muvee.style + + + mts + model/vnd.mts + + + mus + application/vnd.musician + + + musicxml + application/vnd.recordare.musicxml+xml + + + mvb + application/x-msmediaview + + + mwf + application/vnd.mfer + + + mxf + application/mxf + + + mxl + application/vnd.recordare.musicxml + + + mxml + application/xv+xml + + + mxs + application/vnd.triscape.mxs + + + mxu + video/vnd.mpegurl + + + n-gage + application/vnd.nokia.n-gage.symbian.install + + + n3 + text/n3 + + + nb + application/mathematica + + + nbp + application/vnd.wolfram.player + + + nc + application/x-netcdf + + + ncx + application/x-dtbncx+xml + + + nfo + text/x-nfo + + + ngdat + application/vnd.nokia.n-gage.data + + + nitf + application/vnd.nitf + + + nlu + application/vnd.neurolanguage.nlu + + + nml + application/vnd.enliven + + + nnd + application/vnd.noblenet-directory + + + nns + application/vnd.noblenet-sealer + + + nnw + application/vnd.noblenet-web + + + npx + image/vnd.net-fpx + + + nsc + application/x-conference + + + nsf + application/vnd.lotus-notes + + + ntf + application/vnd.nitf + + + nzb + application/x-nzb + + + oa2 + application/vnd.fujitsu.oasys2 + + + oa3 + application/vnd.fujitsu.oasys3 + + + oas + application/vnd.fujitsu.oasys + + + obd + application/x-msbinder + + + obj + application/x-tgif + + + oda + application/oda + + + + odb + application/vnd.oasis.opendocument.database + + + + odc + application/vnd.oasis.opendocument.chart + + + + odf + application/vnd.oasis.opendocument.formula + + + odft + application/vnd.oasis.opendocument.formula-template + + + + odg + application/vnd.oasis.opendocument.graphics + + + + odi + application/vnd.oasis.opendocument.image + + + + odm + application/vnd.oasis.opendocument.text-master + + + + odp + application/vnd.oasis.opendocument.presentation + + + + ods + application/vnd.oasis.opendocument.spreadsheet + + + + odt + application/vnd.oasis.opendocument.text + + + oga + audio/ogg + + + ogg + audio/ogg + + + ogv + video/ogg + + + + ogx + application/ogg + + + omdoc + application/omdoc+xml + + + onepkg + application/onenote + + + onetmp + application/onenote + + + onetoc + application/onenote + + + onetoc2 + application/onenote + + + opf + application/oebps-package+xml + + + opml + text/x-opml + + + oprc + application/vnd.palm + + + org + application/vnd.lotus-organizer + + + osf + application/vnd.yamaha.openscoreformat + + + osfpvg + application/vnd.yamaha.openscoreformat.osfpvg+xml + + + otc + application/vnd.oasis.opendocument.chart-template + + + otf + font/otf + + + + otg + application/vnd.oasis.opendocument.graphics-template + + + + oth + application/vnd.oasis.opendocument.text-web + + + oti + application/vnd.oasis.opendocument.image-template + + + + otp + application/vnd.oasis.opendocument.presentation-template + + + + ots + application/vnd.oasis.opendocument.spreadsheet-template + + + + ott + application/vnd.oasis.opendocument.text-template + + + oxps + application/oxps + + + oxt + application/vnd.openofficeorg.extension + + + p + text/x-pascal + + + p10 + application/pkcs10 + + + p12 + application/x-pkcs12 + + + p7b + application/x-pkcs7-certificates + + + p7c + application/pkcs7-mime + + + p7m + application/pkcs7-mime + + + p7r + application/x-pkcs7-certreqresp + + + p7s + application/pkcs7-signature + + + p8 + application/pkcs8 + + + pas + text/x-pascal + + + paw + application/vnd.pawaafile + + + pbd + application/vnd.powerbuilder6 + + + pbm + image/x-portable-bitmap + + + pcap + application/vnd.tcpdump.pcap + + + pcf + application/x-font-pcf + + + pcl + application/vnd.hp-pcl + + + pclxl + application/vnd.hp-pclxl + + + pct + image/pict + + + pcurl + application/vnd.curl.pcurl + + + pcx + image/x-pcx + + + pdb + application/vnd.palm + + + pdf + application/pdf + + + pfa + application/x-font-type1 + + + pfb + application/x-font-type1 + + + pfm + application/x-font-type1 + + + pfr + application/font-tdpfr + + + pfx + application/x-pkcs12 + + + pgm + image/x-portable-graymap + + + pgn + application/x-chess-pgn + + + pgp + application/pgp-encrypted + + + pic + image/pict + + + pict + image/pict + + + pkg + application/octet-stream + + + pki + application/pkixcmp + + + pkipath + application/pkix-pkipath + + + plb + application/vnd.3gpp.pic-bw-large + + + plc + application/vnd.mobius.plc + + + plf + application/vnd.pocketlearn + + + pls + audio/x-scpls + + + pml + application/vnd.ctc-posml + + + png + image/png + + + pnm + image/x-portable-anymap + + + pnt + image/x-macpaint + + + portpkg + application/vnd.macports.portpkg + + + pot + application/vnd.ms-powerpoint + + + potm + application/vnd.ms-powerpoint.template.macroenabled.12 + + + potx + application/vnd.openxmlformats-officedocument.presentationml.template + + + ppam + application/vnd.ms-powerpoint.addin.macroenabled.12 + + + ppd + application/vnd.cups-ppd + + + ppm + image/x-portable-pixmap + + + pps + application/vnd.ms-powerpoint + + + ppsm + application/vnd.ms-powerpoint.slideshow.macroenabled.12 + + + ppsx + application/vnd.openxmlformats-officedocument.presentationml.slideshow + + + ppt + application/vnd.ms-powerpoint + + + pptm + application/vnd.ms-powerpoint.presentation.macroenabled.12 + + + pptx + application/vnd.openxmlformats-officedocument.presentationml.presentation + + + pqa + application/vnd.palm + + + prc + application/x-mobipocket-ebook + + + pre + application/vnd.lotus-freelance + + + prf + application/pics-rules + + + ps + application/postscript + + + psb + application/vnd.3gpp.pic-bw-small + + + psd + image/vnd.adobe.photoshop + + + psf + application/x-font-linux-psf + + + pskcxml + application/pskc+xml + + + ptid + application/vnd.pvi.ptid1 + + + pub + application/x-mspublisher + + + pvb + application/vnd.3gpp.pic-bw-var + + + pwn + application/vnd.3m.post-it-notes + + + pya + audio/vnd.ms-playready.media.pya + + + pyv + video/vnd.ms-playready.media.pyv + + + qam + application/vnd.epson.quickanime + + + qbo + application/vnd.intu.qbo + + + qfx + application/vnd.intu.qfx + + + qps + application/vnd.publishare-delta-tree + + + qt + video/quicktime + + + qti + image/x-quicktime + + + qtif + image/x-quicktime + + + qwd + application/vnd.quark.quarkxpress + + + qwt + application/vnd.quark.quarkxpress + + + qxb + application/vnd.quark.quarkxpress + + + qxd + application/vnd.quark.quarkxpress + + + qxl + application/vnd.quark.quarkxpress + + + qxt + application/vnd.quark.quarkxpress + + + ra + audio/x-pn-realaudio + + + ram + audio/x-pn-realaudio + + + rar + application/x-rar-compressed + + + ras + image/x-cmu-raster + + + rcprofile + application/vnd.ipunplugged.rcprofile + + + rdf + application/rdf+xml + + + rdz + application/vnd.data-vision.rdz + + + rep + application/vnd.businessobjects + + + res + application/x-dtbresource+xml + + + rgb + image/x-rgb + + + rif + application/reginfo+xml + + + rip + audio/vnd.rip + + + ris + application/x-research-info-systems + + + rl + application/resource-lists+xml + + + rlc + image/vnd.fujixerox.edmics-rlc + + + rld + application/resource-lists-diff+xml + + + rm + application/vnd.rn-realmedia + + + rmi + audio/midi + + + rmp + audio/x-pn-realaudio-plugin + + + rms + application/vnd.jcp.javame.midlet-rms + + + rmvb + application/vnd.rn-realmedia-vbr + + + rnc + application/relax-ng-compact-syntax + + + roa + application/rpki-roa + + + roff + text/troff + + + rp9 + application/vnd.cloanto.rp9 + + + rpss + application/vnd.nokia.radio-presets + + + rpst + application/vnd.nokia.radio-preset + + + rq + application/sparql-query + + + rs + application/rls-services+xml + + + rsd + application/rsd+xml + + + rss + application/rss+xml + + + rtf + application/rtf + + + rtx + text/richtext + + + s + text/x-asm + + + s3m + audio/s3m + + + saf + application/vnd.yamaha.smaf-audio + + + sbml + application/sbml+xml + + + sc + application/vnd.ibm.secure-container + + + scd + application/x-msschedule + + + scm + application/vnd.lotus-screencam + + + scq + application/scvp-cv-request + + + scs + application/scvp-cv-response + + + scurl + text/vnd.curl.scurl + + + sda + application/vnd.stardivision.draw + + + sdc + application/vnd.stardivision.calc + + + sdd + application/vnd.stardivision.impress + + + sdkd + application/vnd.solent.sdkm+xml + + + sdkm + application/vnd.solent.sdkm+xml + + + sdp + application/sdp + + + sdw + application/vnd.stardivision.writer + + + see + application/vnd.seemail + + + seed + application/vnd.fdsn.seed + + + sema + application/vnd.sema + + + semd + application/vnd.semd + + + semf + application/vnd.semf + + + ser + application/java-serialized-object + + + setpay + application/set-payment-initiation + + + setreg + application/set-registration-initiation + + + sfd-hdstx + application/vnd.hydrostatix.sof-data + + + sfs + application/vnd.spotfire.sfs + + + sfv + text/x-sfv + + + sgi + image/sgi + + + sgl + application/vnd.stardivision.writer-global + + + sgm + text/sgml + + + sgml + text/sgml + + + sh + application/x-sh + + + shar + application/x-shar + + + shf + application/shf+xml + + + + sid + image/x-mrsid-image + + + sig + application/pgp-signature + + + sil + audio/silk + + + silo + model/mesh + + + sis + application/vnd.symbian.install + + + sisx + application/vnd.symbian.install + + + sit + application/x-stuffit + + + sitx + application/x-stuffitx + + + skd + application/vnd.koan + + + skm + application/vnd.koan + + + skp + application/vnd.koan + + + skt + application/vnd.koan + + + sldm + application/vnd.ms-powerpoint.slide.macroenabled.12 + + + sldx + application/vnd.openxmlformats-officedocument.presentationml.slide + + + slt + application/vnd.epson.salt + + + sm + application/vnd.stepmania.stepchart + + + smf + application/vnd.stardivision.math + + + smi + application/smil+xml + + + smil + application/smil+xml + + + smv + video/x-smv + + + smzip + application/vnd.stepmania.package + + + snd + audio/basic + + + snf + application/x-font-snf + + + so + application/octet-stream + + + spc + application/x-pkcs7-certificates + + + spf + application/vnd.yamaha.smaf-phrase + + + spl + application/x-futuresplash + + + spot + text/vnd.in3d.spot + + + spp + application/scvp-vp-response + + + spq + application/scvp-vp-request + + + spx + audio/ogg + + + sql + application/x-sql + + + src + application/x-wais-source + + + srt + application/x-subrip + + + sru + application/sru+xml + + + srx + application/sparql-results+xml + + + ssdl + application/ssdl+xml + + + sse + application/vnd.kodak-descriptor + + + ssf + application/vnd.epson.ssf + + + ssml + application/ssml+xml + + + st + application/vnd.sailingtracker.track + + + stc + application/vnd.sun.xml.calc.template + + + std + application/vnd.sun.xml.draw.template + + + stf + application/vnd.wt.stf + + + sti + application/vnd.sun.xml.impress.template + + + stk + application/hyperstudio + + + stl + application/vnd.ms-pki.stl + + + str + application/vnd.pg.format + + + stw + application/vnd.sun.xml.writer.template + + + sub + text/vnd.dvb.subtitle + + + sus + application/vnd.sus-calendar + + + susp + application/vnd.sus-calendar + + + sv4cpio + application/x-sv4cpio + + + sv4crc + application/x-sv4crc + + + svc + application/vnd.dvb.service + + + svd + application/vnd.svd + + + svg + image/svg+xml + + + svgz + image/svg+xml + + + swa + application/x-director + + + swf + application/x-shockwave-flash + + + swi + application/vnd.aristanetworks.swi + + + sxc + application/vnd.sun.xml.calc + + + sxd + application/vnd.sun.xml.draw + + + sxg + application/vnd.sun.xml.writer.global + + + sxi + application/vnd.sun.xml.impress + + + sxm + application/vnd.sun.xml.math + + + sxw + application/vnd.sun.xml.writer + + + t + text/troff + + + t3 + application/x-t3vm-image + + + taglet + application/vnd.mynfc + + + tao + application/vnd.tao.intent-module-archive + + + tar + application/x-tar + + + tcap + application/vnd.3gpp2.tcap + + + tcl + application/x-tcl + + + teacher + application/vnd.smart.teacher + + + tei + application/tei+xml + + + teicorpus + application/tei+xml + + + tex + application/x-tex + + + texi + application/x-texinfo + + + texinfo + application/x-texinfo + + + text + text/plain + + + tfi + application/thraud+xml + + + tfm + application/x-tex-tfm + + + tga + image/x-tga + + + thmx + application/vnd.ms-officetheme + + + tif + image/tiff + + + tiff + image/tiff + + + tmo + application/vnd.tmobile-livetv + + + torrent + application/x-bittorrent + + + tpl + application/vnd.groove-tool-template + + + tpt + application/vnd.trid.tpt + + + tr + text/troff + + + tra + application/vnd.trueapp + + + trm + application/x-msterminal + + + tsd + application/timestamped-data + + + tsv + text/tab-separated-values + + + ttc + font/collection + + + ttf + font/ttf + + + ttl + text/turtle + + + twd + application/vnd.simtech-mindmapper + + + twds + application/vnd.simtech-mindmapper + + + txd + application/vnd.genomatix.tuxedo + + + txf + application/vnd.mobius.txf + + + txt + text/plain + + + u32 + application/x-authorware-bin + + + udeb + application/x-debian-package + + + ufd + application/vnd.ufdl + + + ufdl + application/vnd.ufdl + + + ulw + audio/basic + + + ulx + application/x-glulx + + + umj + application/vnd.umajin + + + unityweb + application/vnd.unity + + + uoml + application/vnd.uoml+xml + + + uri + text/uri-list + + + uris + text/uri-list + + + urls + text/uri-list + + + ustar + application/x-ustar + + + utz + application/vnd.uiq.theme + + + uu + text/x-uuencode + + + uva + audio/vnd.dece.audio + + + uvd + application/vnd.dece.data + + + uvf + application/vnd.dece.data + + + uvg + image/vnd.dece.graphic + + + uvh + video/vnd.dece.hd + + + uvi + image/vnd.dece.graphic + + + uvm + video/vnd.dece.mobile + + + uvp + video/vnd.dece.pd + + + uvs + video/vnd.dece.sd + + + uvt + application/vnd.dece.ttml+xml + + + uvu + video/vnd.uvvu.mp4 + + + uvv + video/vnd.dece.video + + + uvva + audio/vnd.dece.audio + + + uvvd + application/vnd.dece.data + + + uvvf + application/vnd.dece.data + + + uvvg + image/vnd.dece.graphic + + + uvvh + video/vnd.dece.hd + + + uvvi + image/vnd.dece.graphic + + + uvvm + video/vnd.dece.mobile + + + uvvp + video/vnd.dece.pd + + + uvvs + video/vnd.dece.sd + + + uvvt + application/vnd.dece.ttml+xml + + + uvvu + video/vnd.uvvu.mp4 + + + uvvv + video/vnd.dece.video + + + uvvx + application/vnd.dece.unspecified + + + uvvz + application/vnd.dece.zip + + + uvx + application/vnd.dece.unspecified + + + uvz + application/vnd.dece.zip + + + vcard + text/vcard + + + vcd + application/x-cdlink + + + vcf + text/x-vcard + + + vcg + application/vnd.groove-vcard + + + vcs + text/x-vcalendar + + + vcx + application/vnd.vcx + + + vis + application/vnd.visionary + + + viv + video/vnd.vivo + + + vob + video/x-ms-vob + + + vor + application/vnd.stardivision.writer + + + vox + application/x-authorware-bin + + + vrml + model/vrml + + + vsd + application/vnd.visio + + + vsf + application/vnd.vsf + + + vss + application/vnd.visio + + + vst + application/vnd.visio + + + vsw + application/vnd.visio + + + vtu + model/vnd.vtu + + + vxml + application/voicexml+xml + + + w3d + application/x-director + + + wad + application/x-doom + + + wasm + application/wasm + + + wav + audio/x-wav + + + wax + audio/x-ms-wax + + + + wbmp + image/vnd.wap.wbmp + + + wbs + application/vnd.criticaltools.wbs+xml + + + wbxml + application/vnd.wap.wbxml + + + wcm + application/vnd.ms-works + + + wdb + application/vnd.ms-works + + + wdp + image/vnd.ms-photo + + + weba + audio/webm + + + webm + video/webm + + + webp + image/webp + + + wg + application/vnd.pmi.widget + + + wgt + application/widget + + + wks + application/vnd.ms-works + + + wm + video/x-ms-wm + + + wma + audio/x-ms-wma + + + wmd + application/x-ms-wmd + + + wmf + application/x-msmetafile + + + + wml + text/vnd.wap.wml + + + + wmlc + application/vnd.wap.wmlc + + + + wmls + text/vnd.wap.wmlscript + + + + wmlsc + application/vnd.wap.wmlscriptc + + + wmv + video/x-ms-wmv + + + wmx + video/x-ms-wmx + + + wmz + application/x-msmetafile + + + woff + font/woff + + + woff2 + font/woff2 + + + wpd + application/vnd.wordperfect + + + wpl + application/vnd.ms-wpl + + + wps + application/vnd.ms-works + + + wqd + application/vnd.wqd + + + wri + application/x-mswrite + + + wrl + model/vrml + + + wsdl + application/wsdl+xml + + + wspolicy + application/wspolicy+xml + + + wtb + application/vnd.webturbo + + + wvx + video/x-ms-wvx + + + x32 + application/x-authorware-bin + + + x3d + model/x3d+xml + + + x3db + model/x3d+binary + + + x3dbz + model/x3d+binary + + + x3dv + model/x3d+vrml + + + x3dvz + model/x3d+vrml + + + x3dz + model/x3d+xml + + + xaml + application/xaml+xml + + + xap + application/x-silverlight-app + + + xar + application/vnd.xara + + + xbap + application/x-ms-xbap + + + xbd + application/vnd.fujixerox.docuworks.binder + + + xbm + image/x-xbitmap + + + xdf + application/xcap-diff+xml + + + xdm + application/vnd.syncml.dm+xml + + + xdp + application/vnd.adobe.xdp+xml + + + xdssc + application/dssc+xml + + + xdw + application/vnd.fujixerox.docuworks + + + xenc + application/xenc+xml + + + xer + application/patch-ops-error+xml + + + xfdf + application/vnd.adobe.xfdf + + + xfdl + application/vnd.xfdl + + + xht + application/xhtml+xml + + + xhtml + application/xhtml+xml + + + xhvml + application/xv+xml + + + xif + image/vnd.xiff + + + xla + application/vnd.ms-excel + + + xlam + application/vnd.ms-excel.addin.macroenabled.12 + + + xlc + application/vnd.ms-excel + + + xlf + application/x-xliff+xml + + + xlm + application/vnd.ms-excel + + + xls + application/vnd.ms-excel + + + xlsb + application/vnd.ms-excel.sheet.binary.macroenabled.12 + + + xlsm + application/vnd.ms-excel.sheet.macroenabled.12 + + + xlsx + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + + xlt + application/vnd.ms-excel + + + xltm + application/vnd.ms-excel.template.macroenabled.12 + + + xltx + application/vnd.openxmlformats-officedocument.spreadsheetml.template + + + xlw + application/vnd.ms-excel + + + xm + audio/xm + + + xml + application/xml + + + xo + application/vnd.olpc-sugar + + + xop + application/xop+xml + + + xpi + application/x-xpinstall + + + xpl + application/xproc+xml + + + xpm + image/x-xpixmap + + + xpr + application/vnd.is-xpr + + + xps + application/vnd.ms-xpsdocument + + + xpw + application/vnd.intercon.formnet + + + xpx + application/vnd.intercon.formnet + + + xsl + application/xml + + + xslt + application/xslt+xml + + + xsm + application/vnd.syncml+xml + + + xspf + application/xspf+xml + + + xul + application/vnd.mozilla.xul+xml + + + xvm + application/xv+xml + + + xvml + application/xv+xml + + + xwd + image/x-xwindowdump + + + xyz + chemical/x-xyz + + + xz + application/x-xz + + + yang + application/yang + + + yin + application/yin+xml + + + z + application/x-compress + + + z1 + application/x-zmachine + + + z2 + application/x-zmachine + + + z3 + application/x-zmachine + + + z4 + application/x-zmachine + + + z5 + application/x-zmachine + + + z6 + application/x-zmachine + + + z7 + application/x-zmachine + + + z8 + application/x-zmachine + + + zaz + application/vnd.zzazz.deck+xml + + + zip + application/zip + + + zir + application/vnd.zul + + + zirz + application/vnd.zul + + + zmm + application/vnd.handheld-entertainment+xml + + + + + + + + + + + + + + + + + + index.html + index.htm + index.jsp + + + diff --git a/apache-tomcat/sso/webapps/ping/WEB-INF/web.xml b/apache-tomcat/sso/webapps/ping/WEB-INF/web.xml new file mode 100644 index 0000000000..afe0e87bcc --- /dev/null +++ b/apache-tomcat/sso/webapps/ping/WEB-INF/web.xml @@ -0,0 +1,50 @@ + + + Ping + + + Ping Login Auth + + Restricted Access + /private/* + + + admin + + + NONE + + + + + admin + + + + FORM + + /logging.html + /logging_error.html + + + + + ExpiresFilter + org.apache.catalina.filters.ExpiresFilter + + ExpiresByType text/html + access plus 0 seconds + + + + + ExpiresFilter + /private/* + REQUEST + + \ No newline at end of file diff --git a/apache-tomcat/sso/webapps/ping/index.html b/apache-tomcat/sso/webapps/ping/index.html new file mode 100644 index 0000000000..b9c1a889e9 --- /dev/null +++ b/apache-tomcat/sso/webapps/ping/index.html @@ -0,0 +1,9 @@ + + + + Ping + + + Start pinging + + \ No newline at end of file diff --git a/apache-tomcat/sso/webapps/ping/logging.html b/apache-tomcat/sso/webapps/ping/logging.html new file mode 100644 index 0000000000..53699e61ff --- /dev/null +++ b/apache-tomcat/sso/webapps/ping/logging.html @@ -0,0 +1,26 @@ + + + + Ping - Login + + +
+ + + + + + + + + +
User name:
Password:
+

+ +   + +
+ + \ No newline at end of file diff --git a/apache-tomcat/sso/webapps/ping/logging_error.html b/apache-tomcat/sso/webapps/ping/logging_error.html new file mode 100644 index 0000000000..16270326e2 --- /dev/null +++ b/apache-tomcat/sso/webapps/ping/logging_error.html @@ -0,0 +1,10 @@ + + + + Ping + + + Error logging in! + Try again + + \ No newline at end of file diff --git a/apache-tomcat/sso/webapps/ping/private/index.html b/apache-tomcat/sso/webapps/ping/private/index.html new file mode 100644 index 0000000000..89eb346be4 --- /dev/null +++ b/apache-tomcat/sso/webapps/ping/private/index.html @@ -0,0 +1,9 @@ + + + + Ping - Pinging + + + Pong! + + \ No newline at end of file diff --git a/apache-tomcat/sso/webapps/pong/WEB-INF/web.xml b/apache-tomcat/sso/webapps/pong/WEB-INF/web.xml new file mode 100644 index 0000000000..69728f77dc --- /dev/null +++ b/apache-tomcat/sso/webapps/pong/WEB-INF/web.xml @@ -0,0 +1,51 @@ + + + Pong + + index.html + + + + + Pong Login Auth + + Restricted Access + /private/* + + + admin + + + NONE + + + + + admin + + + + + FORM + + /logging.html + /logging_error.html + + + + + ExpiresFilter + org.apache.catalina.filters.ExpiresFilter + + ExpiresByType text/html + access plus 0 seconds + + + + + ExpiresFilter + /private/* + REQUEST + + + \ No newline at end of file diff --git a/apache-tomcat/sso/webapps/pong/index.html b/apache-tomcat/sso/webapps/pong/index.html new file mode 100644 index 0000000000..9c45629b85 --- /dev/null +++ b/apache-tomcat/sso/webapps/pong/index.html @@ -0,0 +1,9 @@ + + + + Pong + + + Start ponging + + \ No newline at end of file diff --git a/apache-tomcat/sso/webapps/pong/logging.html b/apache-tomcat/sso/webapps/pong/logging.html new file mode 100644 index 0000000000..ba2ad05c1f --- /dev/null +++ b/apache-tomcat/sso/webapps/pong/logging.html @@ -0,0 +1,26 @@ + + + + Pong - Login + + +
+ + + + + + + + + +
User name:
Password:
+

+ +   + +
+ + \ No newline at end of file diff --git a/apache-tomcat/sso/webapps/pong/logging_error.html b/apache-tomcat/sso/webapps/pong/logging_error.html new file mode 100644 index 0000000000..b5619a5094 --- /dev/null +++ b/apache-tomcat/sso/webapps/pong/logging_error.html @@ -0,0 +1,10 @@ + + + + Pong + + + Error logging in! + Try again + + \ No newline at end of file diff --git a/apache-tomcat/sso/webapps/pong/private/index.html b/apache-tomcat/sso/webapps/pong/private/index.html new file mode 100644 index 0000000000..d2f096f6aa --- /dev/null +++ b/apache-tomcat/sso/webapps/pong/private/index.html @@ -0,0 +1,9 @@ + + + + Pong - Ponging + + + Ping! + + \ No newline at end of file From 3c8bf25c07cde5169c57525e775a8ee201dbd0fc Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Mon, 28 Feb 2022 10:15:29 +0530 Subject: [PATCH 065/249] Using property for dependencies versions --- .../spring-hibernate-5/pom.xml | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/persistence-modules/spring-hibernate-5/pom.xml b/persistence-modules/spring-hibernate-5/pom.xml index bb8c4e8228..ba18c5a221 100644 --- a/persistence-modules/spring-hibernate-5/pom.xml +++ b/persistence-modules/spring-hibernate-5/pom.xml @@ -107,27 +107,22 @@ com.h2database h2 ${h2.version} -
+ - jakarta.xml.bind - jakarta.xml.bind-api - 2.3.2 - - - com.sun.xml.bind - jaxb-core - 2.3.0.1 - - - javax.xml.bind - jaxb-api - 2.3.1 - - - com.sun.xml.bind - jaxb-impl - 2.3.1 - + com.sun.xml.bind + jaxb-core + ${com.sun.xml.version} + + + javax.xml.bind + jaxb-api + ${javax.xml.bind.version} + + + com.sun.xml.bind + jaxb-impl + ${com.sun.xml.version} +
@@ -142,6 +137,8 @@ 9.0.0.M26 1.1 2.3.4 + 2.3.0.1 + 2.3.1 \ No newline at end of file From 55826111075ef9ba56c43e3cd2fb69537b98d661 Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Tue, 1 Mar 2022 02:44:16 +0100 Subject: [PATCH 066/249] file to map article (#11838) * file to map article * add aggregateByKeys method --- .../com/baeldung/filetomap/FileToHashMap.java | 83 +++++++++++++++++++ .../filetomap/FileToHashMapUnitTest.java | 66 +++++++++++++++ .../resources/filetomap/theLordOfRings.txt | 6 ++ 3 files changed, 155 insertions(+) create mode 100644 core-java-modules/core-java-io-4/src/main/java/com/baeldung/filetomap/FileToHashMap.java create mode 100644 core-java-modules/core-java-io-4/src/test/java/com/baeldung/filetomap/FileToHashMapUnitTest.java create mode 100644 core-java-modules/core-java-io-4/src/test/resources/filetomap/theLordOfRings.txt diff --git a/core-java-modules/core-java-io-4/src/main/java/com/baeldung/filetomap/FileToHashMap.java b/core-java-modules/core-java-io-4/src/main/java/com/baeldung/filetomap/FileToHashMap.java new file mode 100644 index 0000000000..f88404a1a4 --- /dev/null +++ b/core-java-modules/core-java-io-4/src/main/java/com/baeldung/filetomap/FileToHashMap.java @@ -0,0 +1,83 @@ +package com.baeldung.filetomap; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class FileToHashMap { + + enum DupKeyOption { + OVERWRITE, DISCARD + } + + public static Map byBufferedReader(String filePath, DupKeyOption dupKeyOption) { + HashMap map = new HashMap<>(); + String line; + try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { + while ((line = reader.readLine()) != null) { + String[] keyValuePair = line.split(":", 2); + if (keyValuePair.length > 1) { + String key = keyValuePair[0]; + String value = keyValuePair[1]; + if (DupKeyOption.OVERWRITE == dupKeyOption) { + map.put(key, value); + } else if (DupKeyOption.DISCARD == dupKeyOption) { + map.putIfAbsent(key, value); + } + } else { + System.out.println("No Key:Value found in line, ignoring: " + line); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return map; + } + + public static Map byStream(String filePath, DupKeyOption dupKeyOption) { + Map map = new HashMap<>(); + try (Stream lines = Files.lines(Paths.get(filePath))) { + lines.filter(line -> line.contains(":")) + .forEach(line -> { + String[] keyValuePair = line.split(":", 2); + String key = keyValuePair[0]; + String value = keyValuePair[1]; + if (DupKeyOption.OVERWRITE == dupKeyOption) { + map.put(key, value); + } else if (DupKeyOption.DISCARD == dupKeyOption) { + map.putIfAbsent(key, value); + } + }); + } catch (IOException e) { + e.printStackTrace(); + } + return map; + } + + public static Map> aggregateByKeys(String filePath) { + Map> map = new HashMap<>(); + try (Stream lines = Files.lines(Paths.get(filePath))) { + lines.filter(line -> line.contains(":")) + .forEach(line -> { + String[] keyValuePair = line.split(":", 2); + String key = keyValuePair[0]; + String value = keyValuePair[1]; + if (map.containsKey(key)) { + map.get(key).add(value); + } else { + map.put(key, Stream.of(value).collect(Collectors.toList())); + } + }); + } catch (IOException e) { + e.printStackTrace(); + } + return map; + } +} diff --git a/core-java-modules/core-java-io-4/src/test/java/com/baeldung/filetomap/FileToHashMapUnitTest.java b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/filetomap/FileToHashMapUnitTest.java new file mode 100644 index 0000000000..c89f26de69 --- /dev/null +++ b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/filetomap/FileToHashMapUnitTest.java @@ -0,0 +1,66 @@ +package com.baeldung.filetomap; + +import org.junit.Before; +import org.junit.Test; + +import java.net.URISyntaxException; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FileToHashMapUnitTest { + + private String filePath; + + private static final Map EXPECTED_MAP_DISCARD = Stream.of(new String[][]{ + {"title", "The Lord of the Rings: The Return of the King"}, + {"director", "Peter Jackson"}, + {"actor", "Sean Astin"} + }).collect(Collectors.toMap(data -> data[0], data -> data[1])); + + private static final Map EXPECTED_MAP_OVERWRITE = Stream.of(new String[][]{ + {"title", "The Lord of the Rings: The Return of the King"}, + {"director", "Peter Jackson"}, + {"actor", "Ian McKellen"} + }).collect(Collectors.toMap(data -> data[0], data -> data[1])); + + private static final Map> EXPECTED_MAP_AGGREGATE = Stream.of(new String[][]{ + {"title", "The Lord of the Rings: The Return of the King"}, + {"director", "Peter Jackson"}, + {"actor", "Sean Astin", "Ian McKellen"} + }).collect(Collectors.toMap(arr -> arr[0], arr -> Arrays.asList(Arrays.copyOfRange(arr, 1, arr.length)))); + + @Before + public void setPath() throws URISyntaxException { + if (filePath == null) { + filePath = Paths.get(ClassLoader.getSystemResource("filetomap/theLordOfRings.txt").toURI()).toString(); + } + } + + @Test + public void givenInputFile_whenInvokeByBufferedReaderPriorToJava8_shouldGetExpectedMap() { + Map mapOverwrite = FileToHashMap.byBufferedReader(filePath, FileToHashMap.DupKeyOption.OVERWRITE); + Map mapDiscard = FileToHashMap.byBufferedReader(filePath, FileToHashMap.DupKeyOption.DISCARD); + assertThat(mapOverwrite).isEqualTo(EXPECTED_MAP_OVERWRITE); + assertThat(mapDiscard).isEqualTo(EXPECTED_MAP_DISCARD); + } + + @Test + public void givenInputFile_whenInvokeByStream_shouldGetExpectedMap() { + Map mapOverwrite = FileToHashMap.byStream(filePath, FileToHashMap.DupKeyOption.OVERWRITE); + Map mapDiscard = FileToHashMap.byStream(filePath, FileToHashMap.DupKeyOption.DISCARD); + assertThat(mapOverwrite).isEqualTo(EXPECTED_MAP_OVERWRITE); + assertThat(mapDiscard).isEqualTo(EXPECTED_MAP_DISCARD); + } + + @Test + public void givenInputFile_whenInvokeAggregateByKeys_shouldGetExpectedMap() { + Map> mapAgg = FileToHashMap.aggregateByKeys(filePath); + assertThat(mapAgg).isEqualTo(EXPECTED_MAP_AGGREGATE); + } +} diff --git a/core-java-modules/core-java-io-4/src/test/resources/filetomap/theLordOfRings.txt b/core-java-modules/core-java-io-4/src/test/resources/filetomap/theLordOfRings.txt new file mode 100644 index 0000000000..1ab069e533 --- /dev/null +++ b/core-java-modules/core-java-io-4/src/test/resources/filetomap/theLordOfRings.txt @@ -0,0 +1,6 @@ +title:The Lord of the Rings: The Return of the King +director:Peter Jackson +actor:Sean Astin +actor:Ian McKellen +Gandalf and Aragorn lead the World of Men against Sauron's +army to draw his gaze from Frodo and Sam as they approach Mount Doom with the One Ring. \ No newline at end of file From ca1feef04f8c1bf099a465d33958f77474ce51e1 Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Tue, 1 Mar 2022 09:13:20 +0500 Subject: [PATCH 067/249] Updated README.md Added link back to the article: https://www.baeldung.com/java-producer-consumer-problem --- core-java-modules/core-java-concurrency-advanced-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-concurrency-advanced-4/README.md b/core-java-modules/core-java-concurrency-advanced-4/README.md index 446a553b88..ba838dbc72 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/README.md +++ b/core-java-modules/core-java-concurrency-advanced-4/README.md @@ -4,3 +4,4 @@ - [Bad Practices With Synchronization](https://www.baeldung.com/java-synchronization-bad-practices) - [Start Two Threads at the Exact Same Time in Java](https://www.baeldung.com/java-start-two-threads-at-same-time) - [Volatile Variables and Thread Safety](https://www.baeldung.com/java-volatile-variables-thread-safety) +- [Producer-Consumer Problem With Example in Java](https://www.baeldung.com/java-producer-consumer-problem) From a48620e5eb1228f789f300b3eba212c1dc622a0d Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Tue, 1 Mar 2022 09:16:24 +0500 Subject: [PATCH 068/249] Updated README.md added link back to the article: https://www.baeldung.com/spring-cloud-gateway-url-rewriting --- spring-cloud/spring-cloud-gateway/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-cloud/spring-cloud-gateway/README.md b/spring-cloud/spring-cloud-gateway/README.md index 6b199977e3..808536ce80 100644 --- a/spring-cloud/spring-cloud-gateway/README.md +++ b/spring-cloud/spring-cloud-gateway/README.md @@ -9,3 +9,4 @@ This module contains articles about Spring Cloud Gateway - [Spring Cloud Gateway Routing Predicate Factories](https://www.baeldung.com/spring-cloud-gateway-routing-predicate-factories) - [Spring Cloud Gateway WebFilter Factories](https://www.baeldung.com/spring-cloud-gateway-webfilter-factories) - [Using Spring Cloud Gateway with OAuth 2.0 Patterns](https://www.baeldung.com/spring-cloud-gateway-oauth2) +- [URL Rewriting With Spring Cloud Gateway](https://www.baeldung.com/spring-cloud-gateway-url-rewriting) From bd175a879c5aab6245feeba0f1098c31c91eb147 Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Tue, 1 Mar 2022 09:21:53 +0500 Subject: [PATCH 069/249] Updated README.md added link back to the article: https://www.baeldung.com/java-map-vs-hashmap --- core-java-modules/core-java-collections-maps-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-maps-4/README.md b/core-java-modules/core-java-collections-maps-4/README.md index 795f0df702..a3f40d5ab7 100644 --- a/core-java-modules/core-java-collections-maps-4/README.md +++ b/core-java-modules/core-java-collections-maps-4/README.md @@ -6,3 +6,4 @@ This module contains articles about Map data structures in Java. - [Using a Custom Class as a Key in a Java HashMap](https://www.baeldung.com/java-custom-class-map-key) - [Nested HashMaps Examples in Java](https://www.baeldung.com/java-nested-hashmaps) - [Java HashMap With Different Value Types](https://www.baeldung.com/java-hashmap-different-value-types) +- [Difference Between Map and HashMap in Java](https://www.baeldung.com/java-map-vs-hashmap) From b3a6dd04b37dea4de24723ad82a835063e149dcb Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Tue, 1 Mar 2022 09:27:58 +0500 Subject: [PATCH 070/249] Updated README.md added link back to the article: https://www.baeldung.com/spring-security-enable-logging --- spring-security-modules/spring-security-web-boot-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-security-modules/spring-security-web-boot-3/README.md b/spring-security-modules/spring-security-web-boot-3/README.md index 45fede7a4c..2f98e0f4a0 100644 --- a/spring-security-modules/spring-security-web-boot-3/README.md +++ b/spring-security-modules/spring-security-web-boot-3/README.md @@ -12,4 +12,5 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com - [Spring Security – Cache Control Headers](https://www.baeldung.com/spring-security-cache-control-headers) - [Fixing 401s with CORS Preflights and Spring Security](https://www.baeldung.com/spring-security-cors-preflight) - [Content Security Policy with Spring Security](https://www.baeldung.com/spring-security-csp) +- [Enable Logging for Spring Security](https://www.baeldung.com/spring-security-enable-logging) - More articles: [[<-- prev]](/spring-security-modules/spring-security-web-boot-2) From 085d41f3e51fe04c8623a8638113a1dacf41169a Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Tue, 1 Mar 2022 09:30:07 +0500 Subject: [PATCH 071/249] Updated README.md added link back to the article: https://www.baeldung.com/java-missing-return-statement --- core-java-modules/core-java-exceptions-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-exceptions-4/README.md b/core-java-modules/core-java-exceptions-4/README.md index 259feb685c..e77787a8a3 100644 --- a/core-java-modules/core-java-exceptions-4/README.md +++ b/core-java-modules/core-java-exceptions-4/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Java ArrayIndexOutOfBoundsException](https://www.baeldung.com/java-arrayindexoutofboundsexception) +- [Java Missing Return Statement](https://www.baeldung.com/java-missing-return-statement) From bc49cacab39d2a8fe6f960d1f0dfe7062d718ec6 Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Tue, 1 Mar 2022 09:32:54 +0500 Subject: [PATCH 072/249] Updated README.md added link back to the article: https://www.baeldung.com/servlets-jsp-check-user-login --- javax-servlets-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/javax-servlets-2/README.md b/javax-servlets-2/README.md index f126f17297..9a7ad02d39 100644 --- a/javax-servlets-2/README.md +++ b/javax-servlets-2/README.md @@ -3,3 +3,4 @@ This module contains articles about Servlets. ### Relevant Articles: +- [Check if a User Is Logged-in With Servlets and JSP](https://www.baeldung.com/servlets-jsp-check-user-login) From 839711825b249addd1bf48aa06b331e7070cd094 Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Tue, 1 Mar 2022 09:50:13 +0500 Subject: [PATCH 073/249] Created/Updated README.md added link back to the article: https://www.baeldung.com/maven-artifact-classifiers --- maven-modules/maven-classifier/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 maven-modules/maven-classifier/README.md diff --git a/maven-modules/maven-classifier/README.md b/maven-modules/maven-classifier/README.md new file mode 100644 index 0000000000..ab8a7f914f --- /dev/null +++ b/maven-modules/maven-classifier/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [A Guide to Maven Artifact Classifiers](https://www.baeldung.com/maven-artifact-classifiers) From 188d5daaf6a66959c4d109b91ccb8701ac5a2760 Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Tue, 1 Mar 2022 09:53:30 +0500 Subject: [PATCH 074/249] Updated README.md added link back to the article: https://www.baeldung.com/java-map-new-entry --- core-java-modules/core-java-collections-maps-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-maps-4/README.md b/core-java-modules/core-java-collections-maps-4/README.md index a3f40d5ab7..92da12fbf9 100644 --- a/core-java-modules/core-java-collections-maps-4/README.md +++ b/core-java-modules/core-java-collections-maps-4/README.md @@ -7,3 +7,4 @@ This module contains articles about Map data structures in Java. - [Nested HashMaps Examples in Java](https://www.baeldung.com/java-nested-hashmaps) - [Java HashMap With Different Value Types](https://www.baeldung.com/java-hashmap-different-value-types) - [Difference Between Map and HashMap in Java](https://www.baeldung.com/java-map-vs-hashmap) +- [How to Create a New Entry in a Map](https://www.baeldung.com/java-map-new-entry) From db7b5b1fd57f2c379e849414703b60fb4acadc59 Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Tue, 1 Mar 2022 10:04:30 +0500 Subject: [PATCH 075/249] Updated README.md added link back to the article: https://www.baeldung.com/ops/docker-cache-maven-dependencies --- docker/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/README.md b/docker/README.md index 0adf1c9b51..b2ae5d56c9 100644 --- a/docker/README.md +++ b/docker/README.md @@ -7,3 +7,4 @@ - [Dockerfile Strategies for Git](https://www.baeldung.com/ops/dockerfile-git-strategies) - [How to Get Docker-Compose to Always Use the Latest Image](https://www.baeldung.com/ops/docker-compose-latest-image) - [How to Include Files Outside of Docker’s Build Context](https://www.baeldung.com/ops/docker-include-files-outside-build-context) +- [Caching Maven Dependencies with Docker](https://www.baeldung.com/ops/docker-cache-maven-dependencies) From 786138fd9bc341fd69e69902a64dcdd434acfe11 Mon Sep 17 00:00:00 2001 From: maibin Date: Mon, 28 Feb 2022 21:22:53 -0800 Subject: [PATCH 076/249] Revert "Added a new Class and few test cases to the core-java-modules (#11867)" (#11874) This reverts commit e10e20a24be601c031dc677001043f01b075f93a. --- .../VariableMightNotHaveBeenInitialized.java | 45 ------------------- ...leMightNotHaveBeenInitializedUnitTest.java | 24 ---------- 2 files changed, 69 deletions(-) delete mode 100644 core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitialized.java delete mode 100644 core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitializedUnitTest.java diff --git a/core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitialized.java b/core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitialized.java deleted file mode 100644 index 64118e6307..0000000000 --- a/core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitialized.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.baeldung.exception.variablemightnothavebeeninitialized; - -public class VariableMightNotHaveBeenInitialized { - - private static int instanceVariableCount; - - /** - * Method would not compile if lines 14 and 18 are uncommented. - */ - public static void countEven() { - //uninstantiated - int count; - int[] arr = new int[]{23, 56, 89, 12, 23}; - for (int i = 0; i < arr.length; i++) { - if ((arr[i] % 2) == 0) { - // count++; - } - - } - // System.out.println("Total Even Numbers : " + count); - } - - public static int countEvenUsingInstanceVariable(int[] arr) { - - for (int i = 0; i < arr.length; i++) { - if ((arr[i] % 2) == 0) { - instanceVariableCount++; - } - - } - return instanceVariableCount; - } - - public static int countEvenUsingIfElse(int[] arr, int args) { - int count; - count = args > 0 ? args : 0; - for (int i = 0; i < arr.length; i++) { - if ((arr[i] % 2) == 0) { - count++; - } - - } - return count; - } -} diff --git a/core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitializedUnitTest.java b/core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitializedUnitTest.java deleted file mode 100644 index c4773d6442..0000000000 --- a/core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitializedUnitTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.baeldung.exception.variablemightnothavebeeninitialized; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class VariableMightNotHaveBeenInitializedUnitTest { - - @Test - public void usingInstanceVariable_returnCount() { - int[] arr = new int[]{1, 2, 3, 4, 5, 6}; - int value = VariableMightNotHaveBeenInitialized.countEvenUsingInstanceVariable(arr); - - assertEquals(3, value); - } - - @Test - public void usingArgumentsAndIfElse_returnCount() { - int[] arr = new int[]{1, 2, 3, 4, 5, 6}; - int value = VariableMightNotHaveBeenInitialized.countEvenUsingIfElse(arr, 2); - - assertEquals(5, value); - } -} From c87c79e035b37e92f334f11741ddfb5f08ea342a Mon Sep 17 00:00:00 2001 From: Daniel Strmecki Date: Tue, 1 Mar 2022 10:07:50 +0100 Subject: [PATCH 077/249] BAEL-5307: Move code from new module to existing (#11868) --- graphql/graphql-java/pom.xml | 119 ++++++++++++++++++ .../graphql/clients/AmericanExpressNodes.java | 24 ++++ .../graphql/clients/ApacheHttpClient.java | 25 ++++ .../com/baeldung/graphql/data/Author.java | 31 +++++ .../java/com/baeldung/graphql/data/Book.java | 25 ++++ .../baeldung/graphql/data/BookRepository.java | 19 +++ .../java/com/baeldung/graphql/data/Data.java | 22 ++++ .../com/baeldung/graphql/data/Response.java | 19 +++ .../graphql/server/GraphQLEndpoint.java | 36 ++++++ .../baeldung/graphql/server/GraphQLQuery.java | 21 ++++ .../src/main/resources/schema.graphqls | 17 +++ .../baeldung/graphql/GraphQLMockServer.java | 85 +++++++++++++ .../clients/AmericanExpressNodesUnitTest.java | 39 ++++++ .../clients/ApacheHttpClientUnitTest.java | 49 ++++++++ 14 files changed, 531 insertions(+) create mode 100644 graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/AmericanExpressNodes.java create mode 100644 graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/ApacheHttpClient.java create mode 100644 graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Author.java create mode 100644 graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Book.java create mode 100644 graphql/graphql-java/src/main/java/com/baeldung/graphql/data/BookRepository.java create mode 100644 graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Data.java create mode 100644 graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Response.java create mode 100644 graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLEndpoint.java create mode 100644 graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLQuery.java create mode 100644 graphql/graphql-java/src/main/resources/schema.graphqls create mode 100644 graphql/graphql-java/src/test/java/com/baeldung/graphql/GraphQLMockServer.java create mode 100644 graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/AmericanExpressNodesUnitTest.java create mode 100644 graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/ApacheHttpClientUnitTest.java diff --git a/graphql/graphql-java/pom.xml b/graphql/graphql-java/pom.xml index 4e2444c1fb..f2733bf671 100644 --- a/graphql/graphql-java/pom.xml +++ b/graphql/graphql-java/pom.xml @@ -12,8 +12,24 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ + + + jitpack.io + https://jitpack.io + + + + false + + central + Central Repository + https://repo.maven.apache.org/maven2 + + + com.graphql-java @@ -25,11 +41,114 @@ ratpack-core ${ratpack-core.version} + + com.github.americanexpress.nodes + nodes + 0.5.0 + + + com.graphql-java + graphql-java + 9.2 + + + com.graphql-java + graphql-java-tools + 5.2.4 + + + com.graphql-java + graphql-java-servlet + 6.1.3 + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + org.apache.commons + commons-lang3 + 3.12.0 + + + org.mock-server + mockserver-netty + 5.11.2 + + + org.mock-server + mockserver-client-java + 5.11.2 + + + com.graphql-java-generator + graphql-java-runtime + ${graphql.java.generator.version} + + + org.junit.jupiter + junit-jupiter-engine + 5.8.2 + test + + + org.assertj + assertj-core + 3.22.0 + test + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + org.eclipse.jetty + jetty-maven-plugin + 10.0.7 + + + maven-war-plugin + 3.1.0 + + + com.graphql-java-generator + graphql-maven-plugin + ${graphql.java.generator.version} + + + + generateClientCode + + + + + com.baeldung.graphql.generated + false + false + true + + + + + 3.0.3 1.4.6 + 3.1 + 1.8 + 1.8 + 1.18 \ No newline at end of file diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/AmericanExpressNodes.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/AmericanExpressNodes.java new file mode 100644 index 0000000000..446dbd416e --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/AmericanExpressNodes.java @@ -0,0 +1,24 @@ +package com.baeldung.graphql.clients; + +import com.baeldung.graphql.data.Data; +import io.aexp.nodes.graphql.GraphQLRequestEntity; +import io.aexp.nodes.graphql.GraphQLResponseEntity; +import io.aexp.nodes.graphql.GraphQLTemplate; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; + +public class AmericanExpressNodes { + + public static GraphQLResponseEntity callGraphQLService(String url, String query) throws IOException { + GraphQLTemplate graphQLTemplate = new GraphQLTemplate(); + + GraphQLRequestEntity requestEntity = GraphQLRequestEntity.Builder() + .url(StringUtils.join(url, "?query=", query)) + .request(Data.class) + .build(); + + return graphQLTemplate.query(requestEntity, Data.class); + } + +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/ApacheHttpClient.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/ApacheHttpClient.java new file mode 100644 index 0000000000..d4f88e62f5 --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/ApacheHttpClient.java @@ -0,0 +1,25 @@ +package com.baeldung.graphql.clients; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClientBuilder; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +public class ApacheHttpClient { + + public static HttpResponse callGraphQLService(String url, String query) throws URISyntaxException, IOException { + HttpClient client = HttpClientBuilder.create().build(); + HttpGet request = new HttpGet(url); + URI uri = new URIBuilder(request.getURI()) + .addParameter("query", query) + .build(); + request.setURI(uri); + return client.execute(request); + } + +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Author.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Author.java new file mode 100644 index 0000000000..876df27769 --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Author.java @@ -0,0 +1,31 @@ +package com.baeldung.graphql.data; + +import org.apache.commons.lang3.StringUtils; + +public class Author { + + private String name; + private String surname; + + public Author() { + + } + + public Author(String name, String surname) { + this.name = name; + this.surname = surname; + } + + public String getName() { + return name; + } + + public String getSurname() { + return surname; + } + + public String getFullName() { + return StringUtils.join(getName(), " ", getSurname()); + } + +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Book.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Book.java new file mode 100644 index 0000000000..6e6188368b --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Book.java @@ -0,0 +1,25 @@ +package com.baeldung.graphql.data; + +public class Book { + + private String title; + private Author author; + + public Book() { + + } + + public Book(String title, Author author) { + this.title = title; + this.author = author; + } + + public String getTitle() { + return title; + } + + public Author getAuthor() { + return author; + } + +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/BookRepository.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/BookRepository.java new file mode 100644 index 0000000000..f812ed088d --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/BookRepository.java @@ -0,0 +1,19 @@ +package com.baeldung.graphql.data; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class BookRepository { + + private static final List books = Stream.of( + new Book("Title 1", new Author("Pero", "Peric")), + new Book("Title 2", new Author("Marko", "Maric")) + ).collect(Collectors.toList()); + + public List getAllBooks() { + return Collections.unmodifiableList(books); + } + +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Data.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Data.java new file mode 100644 index 0000000000..63263a496b --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Data.java @@ -0,0 +1,22 @@ +package com.baeldung.graphql.data; + +import java.util.Collections; +import java.util.List; + +public class Data { + + private List allBooks; + + public Data() { + + } + + public Data(List allBooks) { + this.allBooks = allBooks; + } + + public List getAllBooks() { + return Collections.unmodifiableList(allBooks); + } + +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Response.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Response.java new file mode 100644 index 0000000000..eedd13e04e --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Response.java @@ -0,0 +1,19 @@ +package com.baeldung.graphql.data; + +public class Response { + + private Data data; + + public Response() { + + } + + public Response(Data data) { + this.data = data; + } + + public Data getData() { + return data; + } + +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLEndpoint.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLEndpoint.java new file mode 100644 index 0000000000..c69144c9f5 --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLEndpoint.java @@ -0,0 +1,36 @@ +package com.baeldung.graphql.server; + +import com.baeldung.graphql.data.BookRepository; +import com.coxautodev.graphql.tools.SchemaParser; +import graphql.schema.GraphQLSchema; +import graphql.servlet.SimpleGraphQLHttpServlet; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@WebServlet(urlPatterns = "/graphql") +public class GraphQLEndpoint extends HttpServlet { + + private SimpleGraphQLHttpServlet graphQLServlet; + + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + graphQLServlet.service(req, resp); + } + + @Override + public void init() { + GraphQLSchema schema = SchemaParser.newParser() + .resolvers(new GraphQLQuery(new BookRepository())) + .file("schema.graphqls") + .build() + .makeExecutableSchema(); + graphQLServlet = SimpleGraphQLHttpServlet + .newBuilder(schema) + .build(); + } +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLQuery.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLQuery.java new file mode 100644 index 0000000000..8ba9fa25c5 --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLQuery.java @@ -0,0 +1,21 @@ +package com.baeldung.graphql.server; + +import com.baeldung.graphql.data.Book; +import com.baeldung.graphql.data.BookRepository; +import com.coxautodev.graphql.tools.GraphQLQueryResolver; + +import java.util.List; + +public class GraphQLQuery implements GraphQLQueryResolver { + + private final BookRepository repository; + + public GraphQLQuery(BookRepository repository) { + this.repository = repository; + } + + public List allBooks() { + return repository.getAllBooks(); + } + +} diff --git a/graphql/graphql-java/src/main/resources/schema.graphqls b/graphql/graphql-java/src/main/resources/schema.graphqls new file mode 100644 index 0000000000..b0834e04b7 --- /dev/null +++ b/graphql/graphql-java/src/main/resources/schema.graphqls @@ -0,0 +1,17 @@ +type Book { + title: String! + author: Author +} + +type Author { + name: String! + surname: String! +} + +type Query { + allBooks: [Book] +} + +schema { + query: Query +} \ No newline at end of file diff --git a/graphql/graphql-java/src/test/java/com/baeldung/graphql/GraphQLMockServer.java b/graphql/graphql-java/src/test/java/com/baeldung/graphql/GraphQLMockServer.java new file mode 100644 index 0000000000..fb5a789428 --- /dev/null +++ b/graphql/graphql-java/src/test/java/com/baeldung/graphql/GraphQLMockServer.java @@ -0,0 +1,85 @@ +package com.baeldung.graphql; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.mockserver.client.MockServerClient; +import org.mockserver.integration.ClientAndServer; +import org.mockserver.model.HttpStatusCode; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.URISyntaxException; + +import static org.mockserver.integration.ClientAndServer.startClientAndServer; +import static org.mockserver.matchers.Times.exactly; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + +public class GraphQLMockServer { + + public static ClientAndServer mockServer; + public static String serviceUrl; + + private static int serverPort; + + public static final String SERVER_ADDRESS = "127.0.0.1"; + public static final String HTTP_GET_POST = "GET"; + public static final String PATH = "/graphql"; + + @BeforeAll + static void startServer() throws IOException, URISyntaxException { + serverPort = getFreePort(); + serviceUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH; + mockServer = startClientAndServer(serverPort); + mockAllBooksTitleRequest(); + mockAllBooksTitleAuthorRequest(); + } + + @AfterAll + static void stopServer() { + mockServer.stop(); + } + + private static void mockAllBooksTitleAuthorRequest() { + String requestQuery = "{allBooks{title,author{name,surname}}}"; + String responseJson = "{\"data\":{\"allBooks\":[{\"title\":\"Title 1\",\"author\":{\"name\":\"Pero\",\"surname\":\"Peric\"}},{\"title\":\"Title 2\",\"author\":{\"name\":\"Marko\",\"surname\":\"Maric\"}}]}}"; + + new MockServerClient(SERVER_ADDRESS, serverPort) + .when( + request() + .withPath(PATH) + .withQueryStringParameter("query", requestQuery), + exactly(1) + ) + .respond( + response() + .withStatusCode(HttpStatusCode.OK_200.code()) + .withBody(responseJson) + ); + } + + private static void mockAllBooksTitleRequest() { + String requestQuery = "{allBooks{title}}"; + String responseJson = "{\"data\":{\"allBooks\":[{\"title\":\"Title 1\"},{\"title\":\"Title 2\"}]}}"; + + new MockServerClient(SERVER_ADDRESS, serverPort) + .when( + request() + .withPath(PATH) + .withQueryStringParameter("query", requestQuery), + exactly(1) + ) + .respond( + response() + .withStatusCode(HttpStatusCode.OK_200.code()) + .withBody(responseJson) + ); + } + + private static int getFreePort () throws IOException { + try (ServerSocket serverSocket = new ServerSocket(0)) { + return serverSocket.getLocalPort(); + } + } + +} diff --git a/graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/AmericanExpressNodesUnitTest.java b/graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/AmericanExpressNodesUnitTest.java new file mode 100644 index 0000000000..8466cdee76 --- /dev/null +++ b/graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/AmericanExpressNodesUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.graphql.clients; + +import com.baeldung.graphql.GraphQLMockServer; +import com.baeldung.graphql.data.Data; +import io.aexp.nodes.graphql.GraphQLResponseEntity; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +class AmericanExpressNodesUnitTest extends GraphQLMockServer { + + @Test + void givenGraphQLEndpoint_whenRequestingAllBooksWithTitle_thenExpectedJsonIsReturned() throws IOException { + GraphQLResponseEntity responseEntity = AmericanExpressNodes.callGraphQLService(serviceUrl, "{allBooks{title}}"); + + assertAll( + () -> assertThat(responseEntity.getResponse().getAllBooks()).hasSize(2), + () -> assertThat(responseEntity.getResponse().getAllBooks().get(0).getTitle()).isEqualTo("Title 1"), + () -> assertThat(responseEntity.getResponse().getAllBooks().get(1).getTitle()).isEqualTo("Title 2") + ); + } + + @Test + void givenGraphQLEndpoint_whenRequestingAllBooksWithTitleAndAuthor_thenExpectedJsonIsReturned() throws IOException { + GraphQLResponseEntity responseEntity = AmericanExpressNodes.callGraphQLService(serviceUrl, "{allBooks{title,author{name,surname}}}"); + + assertAll( + () -> assertThat(responseEntity.getResponse().getAllBooks()).hasSize(2), + () -> assertThat(responseEntity.getResponse().getAllBooks().get(0).getTitle()).isEqualTo("Title 1"), + () -> assertThat(responseEntity.getResponse().getAllBooks().get(0).getAuthor().getFullName()).isEqualTo("Pero Peric"), + () -> assertThat(responseEntity.getResponse().getAllBooks().get(1).getTitle()).isEqualTo("Title 2"), + () -> assertThat(responseEntity.getResponse().getAllBooks().get(1).getAuthor().getFullName()).isEqualTo("Marko Maric") + ); + } + +} diff --git a/graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/ApacheHttpClientUnitTest.java b/graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/ApacheHttpClientUnitTest.java new file mode 100644 index 0000000000..17d97e0d14 --- /dev/null +++ b/graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/ApacheHttpClientUnitTest.java @@ -0,0 +1,49 @@ +package com.baeldung.graphql.clients; + +import com.baeldung.graphql.GraphQLMockServer; +import com.baeldung.graphql.data.Response; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +class ApacheHttpClientUnitTest extends GraphQLMockServer { + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + @Test + void givenGraphQLEndpoint_whenRequestingAllBooksWithTitle_thenExpectedJsonIsReturned() throws IOException, URISyntaxException { + HttpResponse httpResponse = ApacheHttpClient.callGraphQLService(serviceUrl, "{allBooks{title}}"); + String actualResponse = IOUtils.toString(httpResponse.getEntity().getContent(), StandardCharsets.UTF_8.name()); + Response parsedResponse = objectMapper.readValue(actualResponse, Response.class); + + assertAll( + () -> assertThat(parsedResponse.getData().getAllBooks()).hasSize(2), + () -> assertThat(parsedResponse.getData().getAllBooks().get(0).getTitle()).isEqualTo("Title 1"), + () -> assertThat(parsedResponse.getData().getAllBooks().get(1).getTitle()).isEqualTo("Title 2") + ); + } + + @Test + void givenGraphQLEndpoint_whenRequestingAllBooksWithTitleAndAuthor_thenExpectedJsonIsReturned() throws IOException, URISyntaxException { + HttpResponse httpResponse = ApacheHttpClient.callGraphQLService(serviceUrl, "{allBooks{title,author{name,surname}}}"); + String actualResponse = IOUtils.toString(httpResponse.getEntity().getContent(), StandardCharsets.UTF_8.name()); + Response parsedResponse = objectMapper.readValue(actualResponse, Response.class); + + assertAll( + () -> assertThat(parsedResponse.getData().getAllBooks()).hasSize(2), + () -> assertThat(parsedResponse.getData().getAllBooks().get(0).getTitle()).isEqualTo("Title 1"), + () -> assertThat(parsedResponse.getData().getAllBooks().get(0).getAuthor().getFullName()).isEqualTo("Pero Peric"), + () -> assertThat(parsedResponse.getData().getAllBooks().get(1).getTitle()).isEqualTo("Title 2"), + () -> assertThat(parsedResponse.getData().getAllBooks().get(1).getAuthor().getFullName()).isEqualTo("Marko Maric") + ); + } + +} From 36899fd0e354792587282f6fc8741d4e59c1f595 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 1 Mar 2022 18:13:26 +0530 Subject: [PATCH 078/249] JAVA-10379 Fix tests in hibernate-mapping-2 module --- .../hibernate-mapping-2/pom.xml | 2 +- ...notationJavaConfigMainIntegrationTest.java | 7 ++ ...nyToManyAnnotationMainIntegrationTest.java | 92 ++++++++++--------- 3 files changed, 57 insertions(+), 44 deletions(-) diff --git a/persistence-modules/hibernate-mapping-2/pom.xml b/persistence-modules/hibernate-mapping-2/pom.xml index 10c07c95eb..06a1535442 100644 --- a/persistence-modules/hibernate-mapping-2/pom.xml +++ b/persistence-modules/hibernate-mapping-2/pom.xml @@ -3,7 +3,7 @@ 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"> 4.0.0 - hibernate-mapping-2y + hibernate-mapping-2 0.1-SNAPSHOT hibernate-mapping-2 diff --git a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java index 19d1a5ff50..69b791b4d4 100644 --- a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java +++ b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java @@ -45,6 +45,13 @@ public class HibernateManyToManyAnnotationJavaConfigMainIntegrationTest { projects.add(new Project("Networking Project")); session.persist(new Employee("Peter", "Oven", projects)); session.persist(new Employee("Allan", "Norman", projects)); + + Set employees = new HashSet(); + employees.add(new Employee("Sam", "Curran")); + employees.add(new Employee("Tom", "Curran")); + Project project = new Project("Database Project"); + project.setEmployees(employees); + session.persist(project); } } diff --git a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java index bfa158d43f..71051c821c 100644 --- a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java +++ b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java @@ -1,7 +1,7 @@ package com.baeldung.hibernate.manytomany; -import static junit.framework.TestCase.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.HashSet; import java.util.List; @@ -23,60 +23,66 @@ import com.baeldung.manytomany.util.HibernateUtil; * Configured in: manytomany.cfg.xml */ public class HibernateManyToManyAnnotationMainIntegrationTest { - private static SessionFactory sessionFactory; + private static SessionFactory sessionFactory; - private Session session; + private Session session; - @BeforeClass - public static void beforeTests() { - sessionFactory = HibernateUtil.getSessionFactory(); - } + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(); + } - @Before - public void setUp() { - session = sessionFactory.openSession(); - session.beginTransaction(); - } + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } - @Test - public void givenData_whenInsert_thenCreatesMtoMrelationship() { - String[] employeeData = { "Peter Oven", "Allan Norman" }; - String[] projectData = { "IT Project", "Networking Project" }; - Set projects = new HashSet(); - - for (String proj : projectData) { - projects.add(new Project(proj)); - } - - for (String emp : employeeData) { - Employee employee = new Employee(emp.split(" ")[0], emp.split(" ")[1]); - assertEquals(0, employee.getProjects().size()); - employee.setProjects(projects); - session.persist(employee); - assertNotNull(employee); - } - } - - @Test + @Test public void givenSession_whenRead_thenReturnsMtoMdata() { + prepareData(); + @SuppressWarnings("unchecked") + List employeeList = session.createQuery("FROM Employee").list(); @SuppressWarnings("unchecked") - List employeeList = session.createQuery("FROM Employee").list(); + List projectList = session.createQuery("FROM Project").list(); assertNotNull(employeeList); + assertNotNull(projectList); + assertEquals(2, employeeList.size()); + assertEquals(2, projectList.size()); + for(Employee employee : employeeList) { assertNotNull(employee.getProjects()); } + for(Project project : projectList) { + assertNotNull(project.getEmployees()); + } } - @After - public void tearDown() { - session.getTransaction() - .commit(); - session.close(); - } + private void prepareData() { + String[] employeeData = { "Peter Oven", "Allan Norman" }; + String[] projectData = { "IT Project", "Networking Project" }; + Set projects = new HashSet(); - @AfterClass - public static void afterTests() { - sessionFactory.close(); - } + for (String proj : projectData) { + projects.add(new Project(proj)); + } + + for (String emp : employeeData) { + Employee employee = new Employee(emp.split(" ")[0], emp.split(" ")[1]); + employee.setProjects(projects); + session.persist(employee); + } + } + + @After + public void tearDown() { + session.getTransaction().commit(); + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } } From 5aa5da657bd8a9b26b0c9db7e7cc43cfa4f24259 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Wed, 2 Mar 2022 12:26:29 +0000 Subject: [PATCH 079/249] [JAVA-10320] Run Cassandra test with a single fork --- persistence-modules/java-cassandra/pom.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/persistence-modules/java-cassandra/pom.xml b/persistence-modules/java-cassandra/pom.xml index 6df75edc56..b0b98b040a 100644 --- a/persistence-modules/java-cassandra/pom.xml +++ b/persistence-modules/java-cassandra/pom.xml @@ -50,6 +50,25 @@ + + + integration-lite-first + + + + + org.apache.maven.plugins + maven-surefire-plugin + + 1 + true + + + + + + + 3.1.2 From aa7680545728145abe648091613c46d7a5ccb7e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor?= Date: Thu, 3 Mar 2022 01:24:41 +0100 Subject: [PATCH 080/249] BAEL-4626 Adjusted traces levels. Adjusted web.xml from webapps. Allows to see clearly the security constraints being applied. Pong: Changed authentication method to DIGEST. This is to check that SSO works with different authentication mechanisms. --- apache-tomcat/sso/res/conf/logging.properties | 6 ++--- .../sso/webapps/ping/WEB-INF/web.xml | 6 ++--- .../sso/webapps/pong/WEB-INF/web.xml | 12 +++------ apache-tomcat/sso/webapps/pong/logging.html | 26 ------------------- .../sso/webapps/pong/logging_error.html | 10 ------- 5 files changed, 10 insertions(+), 50 deletions(-) delete mode 100644 apache-tomcat/sso/webapps/pong/logging.html delete mode 100644 apache-tomcat/sso/webapps/pong/logging_error.html diff --git a/apache-tomcat/sso/res/conf/logging.properties b/apache-tomcat/sso/res/conf/logging.properties index 9413465201..16e37906c9 100644 --- a/apache-tomcat/sso/res/conf/logging.properties +++ b/apache-tomcat/sso/res/conf/logging.properties @@ -50,15 +50,15 @@ java.util.logging.ConsoleHandler.level = FINE java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter java.util.logging.ConsoleHandler.encoding = UTF-8 -org.apache.catalina.authenticator.level = ALL +org.apache.catalina.authenticator.level = FINE org.apache.catalina.authenticator.formatter = org.apache.juli.OneLineFormatter org.apache.catalina.authenticator.encoding = UTF-8 -org.apache.catalina.Realm.level = ALL +org.apache.catalina.Realm.level = FINE org.apache.catalina.Realm.formatter = org.apache.juli.OneLineFormatter org.apache.catalina.Realm.encoding = UTF-8 -org.apache.catalina.realm.level = ALL +org.apache.catalina.realm.level = FINE org.apache.catalina.realm.formatter = org.apache.juli.OneLineFormatter org.apache.catalina.realm.encoding = UTF-8 diff --git a/apache-tomcat/sso/webapps/ping/WEB-INF/web.xml b/apache-tomcat/sso/webapps/ping/WEB-INF/web.xml index afe0e87bcc..7e8a76e5e9 100644 --- a/apache-tomcat/sso/webapps/ping/WEB-INF/web.xml +++ b/apache-tomcat/sso/webapps/ping/WEB-INF/web.xml @@ -10,7 +10,7 @@ Ping Login Auth - Restricted Access + PingRestrictedAccess /private/* @@ -34,7 +34,7 @@ - ExpiresFilter + PingExpiresFilter org.apache.catalina.filters.ExpiresFilter ExpiresByType text/html @@ -43,7 +43,7 @@ - ExpiresFilter + PingExpiresFilter /private/* REQUEST diff --git a/apache-tomcat/sso/webapps/pong/WEB-INF/web.xml b/apache-tomcat/sso/webapps/pong/WEB-INF/web.xml index 69728f77dc..9db95f88c4 100644 --- a/apache-tomcat/sso/webapps/pong/WEB-INF/web.xml +++ b/apache-tomcat/sso/webapps/pong/WEB-INF/web.xml @@ -9,7 +9,7 @@ Pong Login Auth - Restricted Access + PongRestrictedAccess /private/* @@ -26,15 +26,11 @@ - FORM - - /logging.html - /logging_error.html - + DIGEST - ExpiresFilter + PongExpiresFilter org.apache.catalina.filters.ExpiresFilter ExpiresByType text/html @@ -43,7 +39,7 @@ - ExpiresFilter + PongExpiresFilter /private/* REQUEST diff --git a/apache-tomcat/sso/webapps/pong/logging.html b/apache-tomcat/sso/webapps/pong/logging.html deleted file mode 100644 index ba2ad05c1f..0000000000 --- a/apache-tomcat/sso/webapps/pong/logging.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - Pong - Login - - -
- - - - - - - - - -
User name:
Password:
-

- -   - -
- - \ No newline at end of file diff --git a/apache-tomcat/sso/webapps/pong/logging_error.html b/apache-tomcat/sso/webapps/pong/logging_error.html deleted file mode 100644 index b5619a5094..0000000000 --- a/apache-tomcat/sso/webapps/pong/logging_error.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - Pong - - - Error logging in! - Try again - - \ No newline at end of file From 304f5fa74d1f24ab798bd0d96451be0351127e69 Mon Sep 17 00:00:00 2001 From: Mateusz Szablak Date: Thu, 3 Mar 2022 04:52:25 +0100 Subject: [PATCH 081/249] BAEL-5201 Finding the Last Row in an Excel Spreadsheet From Java (#11873) --- .../poi/excel/lastrow/LastRowUnitTest.java | 67 ++++++++++++++++++ .../src/test/resources/lastRowTest.xlsx | Bin 0 -> 8949 bytes 2 files changed, 67 insertions(+) create mode 100644 apache-poi-2/src/test/java/com/baeldung/poi/excel/lastrow/LastRowUnitTest.java create mode 100644 apache-poi-2/src/test/resources/lastRowTest.xlsx diff --git a/apache-poi-2/src/test/java/com/baeldung/poi/excel/lastrow/LastRowUnitTest.java b/apache-poi-2/src/test/java/com/baeldung/poi/excel/lastrow/LastRowUnitTest.java new file mode 100644 index 0000000000..ea838be4ce --- /dev/null +++ b/apache-poi-2/src/test/java/com/baeldung/poi/excel/lastrow/LastRowUnitTest.java @@ -0,0 +1,67 @@ +package com.baeldung.poi.excel.lastrow; + +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Paths; + +import static org.junit.jupiter.api.Assertions.*; + +public class LastRowUnitTest { + private static final String FILE_NAME = "lastRowTest.xlsx"; + private String fileLocation; + + @Before + public void setup() throws URISyntaxException { + fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString(); + } + + @Test + public void givenExampleGrid_whenGetRow_thenReturnRowObjectIfModified() throws IOException { + Workbook workbook = new XSSFWorkbook(fileLocation); + Sheet sheet = workbook.getSheetAt(0); + + assertEquals(7, sheet.getLastRowNum()); + assertEquals(6, sheet.getPhysicalNumberOfRows()); + + assertNotNull(sheet.getRow(0)); + assertNotNull(sheet.getRow(1)); + assertNotNull(sheet.getRow(2)); + assertNotNull(sheet.getRow(3)); + assertNull(sheet.getRow(4)); + assertNull(sheet.getRow(5)); + assertNotNull(sheet.getRow(6)); + assertNotNull(sheet.getRow(7)); + assertNull(sheet.getRow(8)); + + assertSame(sheet.getRow(7), getLastRowFromSheet(sheet)); + } + + @Test + public void givenEmptySheet_whenGetRow_thenReturnNull() throws IOException { + Workbook workbook = new XSSFWorkbook(fileLocation); + Sheet sheet = workbook.getSheetAt(1); + + assertEquals(-1, sheet.getLastRowNum()); + assertEquals(0, sheet.getPhysicalNumberOfRows()); + + assertNull(sheet.getRow(0)); + + assertSame(sheet.getRow(0), getLastRowFromSheet(sheet)); + } + + public static Row getLastRowFromSheet(Sheet sheet) { + Row lastRow = null; + int lastRowNum = sheet.getLastRowNum(); + if (lastRowNum >= 0) { + lastRow = sheet.getRow(lastRowNum); + } + return lastRow; + } +} diff --git a/apache-poi-2/src/test/resources/lastRowTest.xlsx b/apache-poi-2/src/test/resources/lastRowTest.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..3980ceb1f2f6a7bbb2f2e2a184b453234f717d71 GIT binary patch literal 8949 zcmeHMg`$apu+2l z+S|F9+PUbfc{rFlzhr%7YeSiX2+x=efQMcG-|auR2cU_=b{*`%?!$x&4D~Wq(l6}t zxIqZ>(WGND2qt0gu`O}B{M+Y;ANqpi$x)RpQzUFx53gsVz-0DT38hroZnY-2IX#@^ zV@$S$bk}cN)-j)SGJe46)@Ga~h>eo0`OZ%dpEY_Fz+V4*$s(@Li<6=$giJ7gUxhQt--FLOvG=;O4;8XqZ=#T}3zoi(@O zNpHxl64fD>?=EMF4fAPI`+3Ir^H)3jWzCuM=CM1ejH>U~qe?ES-c1OOe-Rj?ec-_N z$xsb6+Q2}Cs@&iC08mpSiKKMG64?_<;aW`Ug^L)Y)myVBseR z10p&MsrpW)HqLCUKac-K=zlOQ|Mu!1;^h@P*@3}_Qa2&Jmy?UJSR%6S!ct9CYCe9_ z3z#)gxwNEuh8`Tjt$sLv{X*L|xT_&$8So z(}|zjL*K;a)2Uc`8}6+)i^98J6>1R973Z*I4_)@TuTC}SxIe=K%JZNT(tFew5J6G2 z1S?wq2Fab}jwTxH%m4xaKmtI8du7A+Cr;e$ove-Q?X7I-j9>@DD~^5=awmNST@G3)S=)pWE$x+qh6noKn=HyPnMTjOGpA^ zmYQ9+uH@dV_XdqBg^*~s^ZG<+;|L39n)gndTpg`Q5yY8COH=dNozT7A%Q7TLpZ)N_ z*v0zM2fKxZ0a_MrrzUztZSr#O6)ZMCvshe@2ODPUM33fPIgE$oJKlw*Fz{%3|2C37 zHyeyzz|KHnk%S2g5m+SsJ%&Cc$j8jFV+9{3eW!S`ENX;X>4yqYDGFCpha?|lMy+9? z`-;_ehLqeMX3&044)1^DSqbLySxP;Ab^K}+E#uAUSQ=S^azGsW0>K!W(~b2dU7FE4 z0vD3%R4AE#P)|&M33Xt(#SxJ4GZv<%q|Gs!6js7TA{o{ zQv|WpD2-P8Ln^4AVPMgVsP+jRp>;ngi`*8K0wV$CYyG}COwizR;P?P}I{&K1wBL*@ zU1v?8QQkLiFZQX5mVin&6V6yeuaK$uXS=q<5`N*=w1+!%(sEMzCr-*TbeY$+G#b;( zsdnmk65-#j2-bu%q0#&EPlOm-m3Pblcun}JWfxidFN9h%Y|+2w6E!rviJB)MUtvvK5(`|_ z1?`_9V-Mkl3{}fU&=F_EIg(PbuB2lwhLbQj-=ydD6^583OZ1rugpF-SN{qY6JQ=hk+X9vEfDEDPQJNO>YD+@m_K0YDjZ$~tO zF#|E`k5+mKl-_>#@cL4@GNInOu4XZTPKIA#oof56d2PUpQbv`D6E7pEmnJ6>A74JW zbpij5%wx_#*^nNoZzR*gC9};p#j47D-Ay+17$C9*w2iV%5zg*sS<%YsOGf1_&R?DR zq`~cPhu@x58^epf%Ki?COx54>4IP_4d`Cs&a*Yp@N5sQLC5gc$L#mjR{#^;FARb_m z+bCX&9^s&x_t6(Q#di)m%*Cd*LjX{$tGw(<;x4roV!Z$r+}?a_4lU~1^CN-MeD=A= zUlra0wKJ2?PV{>1bIK*NAMDtFExtPd8z3j6B6;Y@&?lKw&SF8TPzR)a*KoKRl_&Hd z9ECQ^>BiO$-+`CBK{ndP1|H2z!$CQ3!MphjM)~iblC8Yrq~LRG1@Y!al8a`|Ft*1Q zW|vUO;FTW-pD(rs5h39jV6Gk9uDRtNJr7Sv5gdsh{ak6m`qE6js!vJz%?h)e2znJU zMp2QJWC?Jv0OPgT4E0V%BB?45;$Ryse#9% zVqjLo*GxnJ(8cMtvqkVJr7(1_VQ_2yvO%&X{8(2VQ}zq@6R&0;_#QS=!?W+VJVB?Hy*OcHqygN zJrU$hB3ttobH!VGrqI`1xX~L0B{+MPTzb@8pW5!a`=S2V+amt-mzc9{63W7*?$JvQ zKY+ECVN~vW`E?)&#$&1ADigV<4cE98V|l4_+sJw@Ha1cn!eAG$6n4y8fi*6}>EY+> zm15Lqg(Y8Y5$w5#?edDSx7E(9e%uYO68>&<7SYUn@{s|6Vv?T%z#nza#lqCqlfKi^;jf$OecM?r=Xh7TFVU7c6oNTG=8|fc9P`9;TrAm z`GM@5-MLDas{^MQZv4R9LFr2NgbO*V5~pw?UHv{QhxYC38%W0ZB=)}T2% zTBtYV#fGtk#0^gR8e*%wHVF;f$L$XS(xV((QI-uF#fV>t;-IcLc!6_Z`sAJ=GIE?J z1Vd5ViIEjeEjxLN?+e8oX4wn2{rBKEHi9!(3!Twl@T?S;hA}elu_e@lx>7NZGRT% zQ$AG)un-7_Gq2s^zqNzRpE`d){``og(JM-?#p(<9?fJv>XRSBHuaG{Ud68bVQzEjF zz`h@~b}>ZhZ2kQEs2#ag8CD8{{WY^gxnfD^{pwb1v8&)V43&rl|%go_ecMD}C&WFy@RiU2PN8@zAZ%}~%nO(2g zd^0^&qJ?#dEXT$K*hB3>(p6;775ZLOFDeQ{Ai|k~UT!Bx+kKt-ijTnj9#_swbtR=Rhx*U&_;Dc z0%P*&O?YZ>XCmM2gN+4xXPTg6E8#X|pfTq4qnF+EocQY_1VnT>xZh=s5!(}vzuO0iTlho|yUq_~8a z8xb?YA?Nqd@}(>*ay0!IW^c;KW%C=~4_^)%e8yBURGgto=0k8G*t-C(mb&1OOCJ1u z?q4s6Rd?OSa8R{z(lzedJ|eW#75|du%i8JGp{mHXzm`gK|0GVPs7D$wTiKRl!p*s* zG+pxOtvv~F;fc6Rw{+@NWat*9h_lwF=Hzp?Zs$p^g8|}@uWeQuO{U&5b#r1*R>4pE z+&)g0EEJoOb;L2wJ-%xsuO*`vMTs(!tkw8_LzOY}ZJ-SSOxFm~D(foJE&i4l>m5Y%GBOqVXJ zr+8+dv_qPycv%HU1bLT&>@epAx4=eB6mw&ceUs|UU8k`?$ij-#V#F3uVXB*Ykp5<# zy;mzkWGicG=3B$bB&QGsV# zOk;hyxFd1A%%{1?iP2ip<*l~m0lPYn%L2t}G{T%q4y^GI2di_qIzg7l z^bci+hIHk}SsjG4J*as*?RQBG&!O`gKC#a-YAS_3B&RSRPnL%I7`98e`wMtF5H)89 zK$JSbV&Mj(DH+V>)o`lonZ47YN9#{i#@r4yZ=wmOZpzgxzu(4dUNYwwEElKnx9Weq zxV6fkE(QB_Q0LU|nDcNV@W$ly-{?uy*e?u1AvATe#sn#;jkZjWJ0}#>*tMwDvyDU`FdDSJp=W&cyt3%%AE5)=@mZm6mHW- zD>2kM2?z(Z%`$U0>y)l>^AEO8d&IIC8>|z*UT+0lGB?%!fYq*lQ*#J25#$EOIf4=Y zU(WGIX-iDhjY((63R-@AE~w?B51f4luVI;^eyUVlGS~Xd4Dh&BXwiE6vfV}?1O)N=BM$(owblv zi^U;#fInsXRlFP38K1G9OLl{z4JL9HXv*@D!>-PT7fSOZy|HkXv9oAP)`#Q|8k*i1 zrc0n{=~he|bf7wBzY@A_O=!uo(0LIszOa9Bn^fK?3DsaGRzOI^VL6ev{;;MS)T&=e z%1VDx?h!Pt!n3e&9kpJe8WX4#7qe%$XW4ehG%a#TZhUi%c;vhRVeUvHg%EGEna z1fV&ry~&ftGrr~}xa4KgB^|k{-aTqXc=}A9y{&tW-F8*_lrZl*Y_9h2h_U6voX>&r zpFY@*_a_f>wlH)uHBohOva~b*V@@X)EsWOjlc5HPmEXRTM{nPLI1B|$Fbx9>riPi=8!I{4J2xeGaU0JRT~oT>LS%ueqb64Elx_huQ6D&+(B)ZG{eV+j9qy zvI>lHlY;Px`($9L|^5-7Yliu7+j0aR;nFI($O2XNEvx;_khS~I11ltky-KztxBoy-pq3W%MpeO zkUxD(w5Q$AhcgdfiV2`>6=*t=<>Uhv+nrCsKfygAN$=g8NfW`?c?Q3STQ)1^6!2d&4A@e`B&JM64_2hWvwy;o9;i!PQ zqP+c94Fp5U^U{G=d1|m6%iuV$$S}uhH){qQbj84lx)6 zm0^=#?7u_M*xt$XzZirK>i=%u@yfED?07-TNIyjTywa;(or7x;lE8dedrIEueTy14 zW3ggQw_f9J5ON^JA(&wqd>L=!5$k${(5(^mS(ywQ&u=xVXo6KT-3gyn$$(rnU@|Iz zjJ!R^)X^)!QQpJ&%Or>-67mT-Gw;b)eo3!QP}j@}Sjvp%P)Tp$sRZYyY*lC4FWV4@wNYdRp!2*`zrh|Ps9)YrODqnzOT>zG8TXd zRj`NnrPkgzy{}pQGBw8dzx)16!Mg9|zP9qq3mhz+!5-kg(sJLyeH#1A!8E~dAL9>F zd*91_YV*s>1L8mX;Xcv1@8O?B;+H)Dun6;TpH|$rzMsZ_*=LabasPiL_50TU%%Hz) g0RRK?zuo( literal 0 HcmV?d00001 From 240ba4e0dbec2216715d58f958328a909f3afd2e Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Thu, 3 Mar 2022 13:35:05 +0530 Subject: [PATCH 082/249] JAVA-10352 Updated versions of various libraries and standardised pom version to 1.0.0-SNAPSHOT --- maven-modules/maven-simple/maven-profiles/pom.xml | 2 +- maven-modules/maven-simple/parent-project/core/pom.xml | 2 +- maven-modules/maven-simple/parent-project/pom.xml | 3 +-- maven-modules/maven-simple/parent-project/service/pom.xml | 2 +- maven-modules/maven-simple/parent-project/webapp/pom.xml | 2 +- maven-modules/maven-simple/plugin-management/pom.xml | 6 +++--- .../maven-simple/plugin-management/submodule-1/pom.xml | 2 +- .../maven-simple/plugin-management/submodule-2/pom.xml | 2 +- maven-modules/maven-simple/pom.xml | 1 + 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/maven-modules/maven-simple/maven-profiles/pom.xml b/maven-modules/maven-simple/maven-profiles/pom.xml index 322dada104..ba915038ad 100644 --- a/maven-modules/maven-simple/maven-profiles/pom.xml +++ b/maven-modules/maven-simple/maven-profiles/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.baeldung maven-profiles - 0.0.1-SNAPSHOT + 1.0.0-SNAPSHOT maven-profiles diff --git a/maven-modules/maven-simple/parent-project/core/pom.xml b/maven-modules/maven-simple/parent-project/core/pom.xml index ec25c9ace5..8f7371639f 100644 --- a/maven-modules/maven-simple/parent-project/core/pom.xml +++ b/maven-modules/maven-simple/parent-project/core/pom.xml @@ -10,7 +10,7 @@ parent-project com.baeldung - 1.0-SNAPSHOT + 1.0.0-SNAPSHOT
diff --git a/maven-modules/maven-simple/parent-project/pom.xml b/maven-modules/maven-simple/parent-project/pom.xml index a68f8e63bc..fce9aa3f72 100644 --- a/maven-modules/maven-simple/parent-project/pom.xml +++ b/maven-modules/maven-simple/parent-project/pom.xml @@ -4,14 +4,13 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 parent-project - 1.0-SNAPSHOT parent-project pom com.baeldung maven-simple - 0.0.1-SNAPSHOT + 1.0.0-SNAPSHOT diff --git a/maven-modules/maven-simple/parent-project/service/pom.xml b/maven-modules/maven-simple/parent-project/service/pom.xml index 1953ec8638..39945af248 100644 --- a/maven-modules/maven-simple/parent-project/service/pom.xml +++ b/maven-modules/maven-simple/parent-project/service/pom.xml @@ -10,7 +10,7 @@ parent-project com.baeldung - 1.0-SNAPSHOT + 1.0.0-SNAPSHOT
diff --git a/maven-modules/maven-simple/parent-project/webapp/pom.xml b/maven-modules/maven-simple/parent-project/webapp/pom.xml index bd13c5aeb8..1ab1321b20 100644 --- a/maven-modules/maven-simple/parent-project/webapp/pom.xml +++ b/maven-modules/maven-simple/parent-project/webapp/pom.xml @@ -10,7 +10,7 @@ parent-project com.baeldung - 1.0-SNAPSHOT + 1.0.0-SNAPSHOT
diff --git a/maven-modules/maven-simple/plugin-management/pom.xml b/maven-modules/maven-simple/plugin-management/pom.xml index 2fb2d5ed41..3c4bd886ac 100644 --- a/maven-modules/maven-simple/plugin-management/pom.xml +++ b/maven-modules/maven-simple/plugin-management/pom.xml @@ -9,7 +9,7 @@ maven-simple com.baeldung - 0.0.1-SNAPSHOT + 1.0.0-SNAPSHOT @@ -56,8 +56,8 @@ - 3.8.1 - 3.2.0 + 3.10.0 + 3.3.0
\ No newline at end of file diff --git a/maven-modules/maven-simple/plugin-management/submodule-1/pom.xml b/maven-modules/maven-simple/plugin-management/submodule-1/pom.xml index c36e092254..ff08dec9a6 100644 --- a/maven-modules/maven-simple/plugin-management/submodule-1/pom.xml +++ b/maven-modules/maven-simple/plugin-management/submodule-1/pom.xml @@ -8,7 +8,7 @@ plugin-management com.baeldung - 0.0.1-SNAPSHOT + 1.0.0-SNAPSHOT diff --git a/maven-modules/maven-simple/plugin-management/submodule-2/pom.xml b/maven-modules/maven-simple/plugin-management/submodule-2/pom.xml index e50d3cc26d..5db76cebdb 100644 --- a/maven-modules/maven-simple/plugin-management/submodule-2/pom.xml +++ b/maven-modules/maven-simple/plugin-management/submodule-2/pom.xml @@ -8,7 +8,7 @@ plugin-management com.baeldung - 0.0.1-SNAPSHOT + 1.0.0-SNAPSHOT
\ No newline at end of file diff --git a/maven-modules/maven-simple/pom.xml b/maven-modules/maven-simple/pom.xml index 938e2240f8..fe59259758 100644 --- a/maven-modules/maven-simple/pom.xml +++ b/maven-modules/maven-simple/pom.xml @@ -5,6 +5,7 @@ 4.0.0 maven-simple maven-simple + 1.0.0-SNAPSHOT pom From 95aa9428b45607486cbf7115501f11d5c8ed51a9 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Thu, 3 Mar 2022 21:57:58 +0530 Subject: [PATCH 083/249] JAVA-10083 Create new module hibernate-queries from spring-hibernate-5 module --- .../hibernate-queries-2/.gitignore | 13 +++ .../hibernate-queries-2/README.md | 8 ++ .../hibernate-queries-2/pom.xml | 86 +++++++++++++++++++ .../hibernate/criteria/PersistenceConfig.java | 71 +++++++++++++++ .../hibernate/criteria/model/Item.java | 0 .../criteria/util/HibernateUtil.java | 0 .../criteria/view/ApplicationView.java | 2 +- .../src/main/resources/import-db.sql | 0 .../src/main/resources/logback.xml | 19 ++++ .../main/resources/persistence-h2.properties | 21 +++++ .../java/com/baeldung/SpringContextTest.java | 18 ++++ .../HibernateCriteriaIntegrationTest.java | 0 .../criteria/HibernateCriteriaTestRunner.java | 0 .../criteria/HibernateCriteriaTestSuite.java | 0 .../src/test/resources/.gitignore | 13 +++ .../hibernate/criteria/model/Item.hbm.xml | 0 .../src/test/resources/criteria.cfg.xml | 0 .../src/test/resources/import-db.sql | 0 .../spring-hibernate-5/README.md | 1 - 19 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 persistence-modules/hibernate-queries-2/.gitignore create mode 100644 persistence-modules/hibernate-queries-2/README.md create mode 100644 persistence-modules/hibernate-queries-2/pom.xml create mode 100644 persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/PersistenceConfig.java rename persistence-modules/{spring-hibernate-5 => hibernate-queries-2}/src/main/java/com/baeldung/hibernate/criteria/model/Item.java (100%) rename persistence-modules/{spring-hibernate-5 => hibernate-queries-2}/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java (100%) rename persistence-modules/{spring-hibernate-5 => hibernate-queries-2}/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java (99%) rename persistence-modules/{spring-hibernate-5 => hibernate-queries-2}/src/main/resources/import-db.sql (100%) create mode 100644 persistence-modules/hibernate-queries-2/src/main/resources/logback.xml create mode 100644 persistence-modules/hibernate-queries-2/src/main/resources/persistence-h2.properties create mode 100644 persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/SpringContextTest.java rename persistence-modules/{spring-hibernate-5 => hibernate-queries-2}/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java (100%) rename persistence-modules/{spring-hibernate-5 => hibernate-queries-2}/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java (100%) rename persistence-modules/{spring-hibernate-5 => hibernate-queries-2}/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java (100%) create mode 100644 persistence-modules/hibernate-queries-2/src/test/resources/.gitignore rename persistence-modules/{spring-hibernate-5 => hibernate-queries-2}/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml (100%) rename persistence-modules/{spring-hibernate-5 => hibernate-queries-2}/src/test/resources/criteria.cfg.xml (100%) rename persistence-modules/{spring-hibernate-5 => hibernate-queries-2}/src/test/resources/import-db.sql (100%) diff --git a/persistence-modules/hibernate-queries-2/.gitignore b/persistence-modules/hibernate-queries-2/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/persistence-modules/hibernate-queries-2/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/persistence-modules/hibernate-queries-2/README.md b/persistence-modules/hibernate-queries-2/README.md new file mode 100644 index 0000000000..276e08ef52 --- /dev/null +++ b/persistence-modules/hibernate-queries-2/README.md @@ -0,0 +1,8 @@ +## Hibernate 5 with Spring + +This module contains articles about JPA Criteria Queries. + +### Relevant articles + +- [JPA Criteria Queries](https://www.baeldung.com/hibernate-criteria-queries) + diff --git a/persistence-modules/hibernate-queries-2/pom.xml b/persistence-modules/hibernate-queries-2/pom.xml new file mode 100644 index 0000000000..58b1b23b06 --- /dev/null +++ b/persistence-modules/hibernate-queries-2/pom.xml @@ -0,0 +1,86 @@ + + + 4.0.0 + hibernate-queries-2 + 0.1-SNAPSHOT + hibernate-queries-2 + + + com.baeldung + persistence-modules + 1.0.0-SNAPSHOT + + + + + + org.springframework + spring-context + ${org.springframework.version} + + + org.springframework.data + spring-data-jpa + ${org.springframework.data.version} + + + org.hibernate + hibernate-core + ${hibernate.version} + + + org.apache.tomcat + tomcat-dbcp + ${tomcat-dbcp.version} + + + + + com.google.guava + guava + ${guava.version} + + + + org.springframework + spring-test + ${org.springframework.version} + test + + + com.h2database + h2 + ${h2.version} + + + com.sun.xml.bind + jaxb-core + ${com.sun.xml.version} + + + javax.xml.bind + jaxb-api + ${javax.xml.bind.version} + + + com.sun.xml.bind + jaxb-impl + ${com.sun.xml.version} + + + + + + 5.0.2.RELEASE + 1.10.6.RELEASE + + 5.2.10.Final + 9.0.0.M26 + 2.3.4 + 2.3.0.1 + 2.3.1 + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/PersistenceConfig.java b/persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/PersistenceConfig.java new file mode 100644 index 0000000000..9239697952 --- /dev/null +++ b/persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/PersistenceConfig.java @@ -0,0 +1,71 @@ +package com.baeldung.hibernate.criteria; + +import com.google.common.base.Preconditions; +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.orm.hibernate5.HibernateTransactionManager; +import org.springframework.orm.hibernate5.LocalSessionFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; +import java.util.Properties; + +@Configuration +@EnableTransactionManagement +@PropertySource({ "classpath:persistence-h2.properties" }) +@ComponentScan({ "com.baeldung.hibernate.criteria" }) +public class PersistenceConfig { + + @Autowired + private Environment env; + + @Bean + public LocalSessionFactoryBean sessionFactory() { + final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); + sessionFactory.setDataSource(dataSource()); + sessionFactory.setPackagesToScan(new String[] { "com.baeldung.hibernate.criteria" }); + sessionFactory.setHibernateProperties(hibernateProperties()); + + return sessionFactory; + } + + @Bean + public DataSource dataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); + dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); + + return dataSource; + } + + @Bean + public PlatformTransactionManager hibernateTransactionManager() { + final HibernateTransactionManager transactionManager = new HibernateTransactionManager(); + transactionManager.setSessionFactory(sessionFactory().getObject()); + return transactionManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + private final Properties hibernateProperties() { + final Properties hibernateProperties = new Properties(); + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + hibernateProperties.setProperty("hibernate.show_sql", "false"); + + return hibernateProperties; + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/model/Item.java b/persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/model/Item.java similarity index 100% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/model/Item.java rename to persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/model/Item.java diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java b/persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java similarity index 100% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java rename to persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java b/persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java similarity index 99% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java rename to persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java index c7ca9f1ffd..248f64474a 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java +++ b/persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java @@ -24,7 +24,7 @@ import com.baeldung.hibernate.criteria.model.Item; import com.baeldung.hibernate.criteria.util.HibernateUtil; public class ApplicationView { - + // default Constructor public ApplicationView() { diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/import-db.sql b/persistence-modules/hibernate-queries-2/src/main/resources/import-db.sql similarity index 100% rename from persistence-modules/spring-hibernate-5/src/main/resources/import-db.sql rename to persistence-modules/hibernate-queries-2/src/main/resources/import-db.sql diff --git a/persistence-modules/hibernate-queries-2/src/main/resources/logback.xml b/persistence-modules/hibernate-queries-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..ec0dc2469a --- /dev/null +++ b/persistence-modules/hibernate-queries-2/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-queries-2/src/main/resources/persistence-h2.properties b/persistence-modules/hibernate-queries-2/src/main/resources/persistence-h2.properties new file mode 100644 index 0000000000..e3544d354a --- /dev/null +++ b/persistence-modules/hibernate-queries-2/src/main/resources/persistence-h2.properties @@ -0,0 +1,21 @@ +# jdbc.X +jdbc.driverClassName=org.h2.Driver +jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +jdbc.eventGeneratedId=sa +jdbc.user=sa +jdbc.pass= + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=false +hibernate.hbm2ddl.auto=create-drop +hibernate.cache.use_second_level_cache=true +hibernate.cache.use_query_cache=true +hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory + +# hibernate.search.X +hibernate.search.default.directory_provider = filesystem +hibernate.search.default.indexBase = /data/index/default + +# envers.X +envers.audit_table_suffix=_audit_log diff --git a/persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/SpringContextTest.java new file mode 100644 index 0000000000..6503454abf --- /dev/null +++ b/persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/SpringContextTest.java @@ -0,0 +1,18 @@ +package com.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import com.baeldung.hibernate.criteria.PersistenceConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +public class SpringContextTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java b/persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java similarity index 100% rename from persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java rename to persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java b/persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java similarity index 100% rename from persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java rename to persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java b/persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java similarity index 100% rename from persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java rename to persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java diff --git a/persistence-modules/hibernate-queries-2/src/test/resources/.gitignore b/persistence-modules/hibernate-queries-2/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/persistence-modules/hibernate-queries-2/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/persistence-modules/spring-hibernate-5/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml b/persistence-modules/hibernate-queries-2/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml similarity index 100% rename from persistence-modules/spring-hibernate-5/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml rename to persistence-modules/hibernate-queries-2/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml diff --git a/persistence-modules/spring-hibernate-5/src/test/resources/criteria.cfg.xml b/persistence-modules/hibernate-queries-2/src/test/resources/criteria.cfg.xml similarity index 100% rename from persistence-modules/spring-hibernate-5/src/test/resources/criteria.cfg.xml rename to persistence-modules/hibernate-queries-2/src/test/resources/criteria.cfg.xml diff --git a/persistence-modules/spring-hibernate-5/src/test/resources/import-db.sql b/persistence-modules/hibernate-queries-2/src/test/resources/import-db.sql similarity index 100% rename from persistence-modules/spring-hibernate-5/src/test/resources/import-db.sql rename to persistence-modules/hibernate-queries-2/src/test/resources/import-db.sql diff --git a/persistence-modules/spring-hibernate-5/README.md b/persistence-modules/spring-hibernate-5/README.md index 9770fe95af..124d71a21e 100644 --- a/persistence-modules/spring-hibernate-5/README.md +++ b/persistence-modules/spring-hibernate-5/README.md @@ -5,7 +5,6 @@ This module contains articles about Hibernate 5 with Spring. ### Relevant articles - [Programmatic Transactions in the Spring TestContext Framework](https://www.baeldung.com/spring-test-programmatic-transactions) -- [JPA Criteria Queries](https://www.baeldung.com/hibernate-criteria-queries) - [Introduction to Hibernate Search](https://www.baeldung.com/hibernate-search) - [@DynamicUpdate with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-dynamicupdate) - [Hibernate Second-Level Cache](http://www.baeldung.com/hibernate-second-level-cache) From 2eb49b96cbe156482effd6ecc16238ab0aadbf21 Mon Sep 17 00:00:00 2001 From: Kapil Khandelwal Date: Thu, 3 Mar 2022 23:06:08 +0530 Subject: [PATCH 084/249] BAEL 5359: Update formatting (#11880) * BAEL-5359: Updating Multiple Fields in a MongoDB Document * BAEL-5359: Add test class file * BAEL-5359: Rename UpdateMultipleFieldsUnitTest.java to UpdateMultipleFieldsLiveTest.java * BAEL-5359: Update formatting --- .../mongo/update/MultipleFieldsExample.java | 46 +++++++++---------- .../mongo/update/UpdateMultipleFields.java | 31 ++++++------- .../update/UpdateMultipleFieldsLiveTest.java | 16 +++---- 3 files changed, 45 insertions(+), 48 deletions(-) diff --git a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/MultipleFieldsExample.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/MultipleFieldsExample.java index b2fcddeafb..ebc56cbfd0 100644 --- a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/MultipleFieldsExample.java +++ b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/MultipleFieldsExample.java @@ -10,35 +10,35 @@ import com.mongodb.client.result.UpdateResult; public class MultipleFieldsExample { - public static void main(String[] args) { + public static void main(String[] args) { - // - // Connect to cluster (default is localhost:27017) - // + // + // Connect to cluster (default is localhost:27017) + // - MongoClient mongoClient = new MongoClient("localhost", 27017); - MongoDatabase database = mongoClient.getDatabase("baeldung"); - MongoCollection collection = database.getCollection("employee"); + MongoClient mongoClient = new MongoClient("localhost", 27017); + MongoDatabase database = mongoClient.getDatabase("baeldung"); + MongoCollection collection = database.getCollection("employee"); - // - // Filter on the basis of employee_id - // + // + // Filter on the basis of employee_id + // - BasicDBObject searchQuery = new BasicDBObject("employee_id", 794875); + BasicDBObject searchQuery = new BasicDBObject("employee_id", 794875); - // - // Update the fields in Document - // + // + // Update the fields in Document + // - BasicDBObject updateFields = new BasicDBObject(); - updateFields.append("department_id", 3); - updateFields.append("job", "Sales Manager"); - BasicDBObject setQuery = new BasicDBObject(); - setQuery.append("$set", updateFields); - UpdateResult updateResult = collection.updateMany(searchQuery, setQuery); + BasicDBObject updateFields = new BasicDBObject(); + updateFields.append("department_id", 3); + updateFields.append("job", "Sales Manager"); + BasicDBObject setQuery = new BasicDBObject(); + setQuery.append("$set", updateFields); + UpdateResult updateResult = collection.updateMany(searchQuery, setQuery); - System.out.println("updateResult:- " + updateResult); - System.out.println("updateResult:- " + updateResult.getModifiedCount()); + System.out.println("updateResult:- " + updateResult); + System.out.println("updateResult:- " + updateResult.getModifiedCount()); - } + } } diff --git a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateMultipleFields.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateMultipleFields.java index 20af6d99cb..96dd086ed7 100644 --- a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateMultipleFields.java +++ b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateMultipleFields.java @@ -11,26 +11,25 @@ import com.mongodb.client.result.UpdateResult; public class UpdateMultipleFields { - public static void main(String[] args) { + public static void main(String[] args) { - // - // Connect to cluster - // + // + // Connect to cluster + // - MongoClient mongoClient = new MongoClient("localhost", 27007); - MongoDatabase database = mongoClient.getDatabase("baeldung"); - MongoCollection collection = database.getCollection("employee"); + MongoClient mongoClient = new MongoClient("localhost", 27007); + MongoDatabase database = mongoClient.getDatabase("baeldung"); + MongoCollection collection = database.getCollection("employee"); - // - // Update query - // + // + // Update query + // - UpdateResult updateResult = collection.updateMany(Filters.eq("employee_id", 794875), - Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager"))); + UpdateResult updateResult = collection.updateMany(Filters.eq("employee_id", 794875), Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager"))); - System.out.println("updateResult:- " + updateResult); - System.out.println("updateResult:- " + updateResult.getModifiedCount()); + System.out.println("updateResult:- " + updateResult); + System.out.println("updateResult:- " + updateResult.getModifiedCount()); - } + } -} \ No newline at end of file +} diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateMultipleFieldsLiveTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateMultipleFieldsLiveTest.java index d1538d5312..d06de23423 100644 --- a/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateMultipleFieldsLiveTest.java +++ b/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateMultipleFieldsLiveTest.java @@ -2,8 +2,6 @@ package com.baeldung.update; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; import org.bson.Document; import org.junit.Before; @@ -15,7 +13,6 @@ import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Updates; -import com.mongodb.client.result.UpdateResult; public class UpdateMultipleFieldsLiveTest { @@ -30,8 +27,7 @@ public class UpdateMultipleFieldsLiveTest { db = mongoClient.getDatabase("baeldung"); collection = db.getCollection("employee"); - collection.insertOne(Document.parse( - "{'employee_id':794875,'employee_name': 'David smith','job': 'Sales Representative','department_id': 2,'salary': 20000,'hire_date': NumberLong(\"1643969311817\")}")); + collection.insertOne(Document.parse("{'employee_id':794875,'employee_name': 'David Smith','job': 'Sales Representative','department_id': 2,'salary': 20000,'hire_date': NumberLong(\"1643969311817\")}")); } } @@ -47,7 +43,8 @@ public class UpdateMultipleFieldsLiveTest { collection.updateMany(searchQuery, setQuery); - Document nameDoc = collection.find(Filters.eq("employee_id", 794875)).first(); + Document nameDoc = collection.find(Filters.eq("employee_id", 794875)) + .first(); assertNotNull(nameDoc); assertFalse(nameDoc.isEmpty()); @@ -62,10 +59,10 @@ public class UpdateMultipleFieldsLiveTest { @Test public void updateMultipleFieldsUsingDocument() { - collection.updateMany(Filters.eq("employee_id", 794875), - Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager"))); + collection.updateMany(Filters.eq("employee_id", 794875), Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager"))); - Document nameDoc = collection.find(Filters.eq("employee_id", 794875)).first(); + Document nameDoc = collection.find(Filters.eq("employee_id", 794875)) + .first(); assertNotNull(nameDoc); assertFalse(nameDoc.isEmpty()); @@ -78,3 +75,4 @@ public class UpdateMultipleFieldsLiveTest { } } + From 7c3cbf0d4f1af133e3dd7882358b492d003bc889 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Fri, 4 Mar 2022 03:29:27 +0000 Subject: [PATCH 085/249] [BAEL-5245] Lombok ToString annotation (#11870) --- .../com/baeldung/lombok/tostring/Account.java | 56 ++++++++++++++++ .../baeldung/lombok/tostring/AccountType.java | 9 +++ .../lombok/tostring/RewardAccount.java | 27 ++++++++ .../lombok/tostring/SavingAccount.java | 17 +++++ .../lombok/tostring/ToStringUnitTest.java | 66 +++++++++++++++++++ 5 files changed, 175 insertions(+) create mode 100644 lombok-2/src/main/java/com/baeldung/lombok/tostring/Account.java create mode 100644 lombok-2/src/main/java/com/baeldung/lombok/tostring/AccountType.java create mode 100644 lombok-2/src/main/java/com/baeldung/lombok/tostring/RewardAccount.java create mode 100644 lombok-2/src/main/java/com/baeldung/lombok/tostring/SavingAccount.java create mode 100644 lombok-2/src/test/java/com/baeldung/lombok/tostring/ToStringUnitTest.java diff --git a/lombok-2/src/main/java/com/baeldung/lombok/tostring/Account.java b/lombok-2/src/main/java/com/baeldung/lombok/tostring/Account.java new file mode 100644 index 0000000000..641ad1e1a3 --- /dev/null +++ b/lombok-2/src/main/java/com/baeldung/lombok/tostring/Account.java @@ -0,0 +1,56 @@ +package com.baeldung.lombok.tostring; + +import lombok.ToString; + +@ToString +public class Account { + + private String name; + + // render this field before any others (the highest ranked) + @ToString.Include(rank = 1) + private String id; + + @ToString.Exclude + private String accountNumber; + + // automatically excluded + private String $ignored; + + @ToString.Include + String description() { + return "Account description"; + } + + public String getAccountNumber() { + return accountNumber; + } + + public void setAccountNumber(String accountNumber) { + this.accountNumber = accountNumber; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String get$ignored() { + return $ignored; + } + + public void set$ignored(String value) { + this.$ignored = value; + } +} diff --git a/lombok-2/src/main/java/com/baeldung/lombok/tostring/AccountType.java b/lombok-2/src/main/java/com/baeldung/lombok/tostring/AccountType.java new file mode 100644 index 0000000000..7f99b5ca35 --- /dev/null +++ b/lombok-2/src/main/java/com/baeldung/lombok/tostring/AccountType.java @@ -0,0 +1,9 @@ +package com.baeldung.lombok.tostring; + +import lombok.ToString; + +@ToString +public enum AccountType { + CHECKING, + SAVING +} diff --git a/lombok-2/src/main/java/com/baeldung/lombok/tostring/RewardAccount.java b/lombok-2/src/main/java/com/baeldung/lombok/tostring/RewardAccount.java new file mode 100644 index 0000000000..9ac9c6afa6 --- /dev/null +++ b/lombok-2/src/main/java/com/baeldung/lombok/tostring/RewardAccount.java @@ -0,0 +1,27 @@ +package com.baeldung.lombok.tostring; + +import lombok.ToString; + +@ToString +public class RewardAccount extends Account { + + private String rewardAccountId; + + private Object[] relatedAccounts; + + public String getRewardAccountId() { + return rewardAccountId; + } + + public void setRewardAccountId(String rewardAccountId) { + this.rewardAccountId = rewardAccountId; + } + + public Object[] getRelatedAccounts() { + return relatedAccounts; + } + + public void setRelatedAccounts(Object[] relatedAccounts) { + this.relatedAccounts = relatedAccounts; + } +} diff --git a/lombok-2/src/main/java/com/baeldung/lombok/tostring/SavingAccount.java b/lombok-2/src/main/java/com/baeldung/lombok/tostring/SavingAccount.java new file mode 100644 index 0000000000..dfba31cf27 --- /dev/null +++ b/lombok-2/src/main/java/com/baeldung/lombok/tostring/SavingAccount.java @@ -0,0 +1,17 @@ +package com.baeldung.lombok.tostring; + +import lombok.ToString; + +@ToString(callSuper = true) +public class SavingAccount extends Account { + + private String savingAccountId; + + public String getSavingAccountId() { + return savingAccountId; + } + + public void setSavingAccountId(String savingAccountId) { + this.savingAccountId = savingAccountId; + } +} diff --git a/lombok-2/src/test/java/com/baeldung/lombok/tostring/ToStringUnitTest.java b/lombok-2/src/test/java/com/baeldung/lombok/tostring/ToStringUnitTest.java new file mode 100644 index 0000000000..cb56ad912d --- /dev/null +++ b/lombok-2/src/test/java/com/baeldung/lombok/tostring/ToStringUnitTest.java @@ -0,0 +1,66 @@ +package com.baeldung.lombok.tostring; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ToStringUnitTest { + + @Test + void whenPrintObject_thenOutputIsCorrect() { + Account account = new Account(); + account.setId("12345"); + account.setName("An account"); + account.setAccountNumber("11111"); // should not be present in output + account.set$ignored("ignored value"); // should not be present in output + + assertThat(account.toString()) + .isEqualTo("Account(id=12345, name=An account, description=Account description)"); + } + + @Test + void whenPrintSubclassWithSuper_thenOutputIsCorrect() { + SavingAccount savingAccount = new SavingAccount(); + savingAccount.setSavingAccountId("5678"); + savingAccount.setId("12345"); + savingAccount.setName("An account"); + + assertThat(savingAccount.toString()) + .isEqualTo("SavingAccount(super=Account(id=12345, name=An account, description=Account description), savingAccountId=5678)"); + } + +@Test +void whenPrintArrays_thenOutputIsCorrect() { + RewardAccount account = new RewardAccount(); + account.setRewardAccountId("12345"); + + // circular ref, just for demonstration + Object[] relatedAccounts = new Object[2]; + relatedAccounts[0] = "54321"; + relatedAccounts[1] = relatedAccounts; + + account.setRelatedAccounts(relatedAccounts); + + assertThat(account.toString()) + .isEqualTo("RewardAccount(rewardAccountId=12345, relatedAccounts=[54321, [...]])"); +} + + @Test + void whenPrintSubclassWithoutSuper_thenOutputIsCorrect() { + RewardAccount rewardAccount = new RewardAccount(); + rewardAccount.setRewardAccountId("12345"); + + assertThat(rewardAccount.toString()) + .isEqualTo("RewardAccount(rewardAccountId=12345, relatedAccounts=null)"); + } + + @Test + void whenPrintEnum_thenOutputIsCorrect() { + assertThat(AccountType.CHECKING.toString()) + .isEqualTo("AccountType.CHECKING"); + + assertThat(AccountType.SAVING.toString()) + .isEqualTo("AccountType.SAVING"); + } + +} From cd9147679944ccda9d5f9d77a68c815065d53ef4 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Fri, 4 Mar 2022 15:47:50 +0000 Subject: [PATCH 086/249] [JAVA-10335] Upgrade plugin version to fix muleesb build --- muleesb/pom.xml | 9 +++++---- pom.xml | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/muleesb/pom.xml b/muleesb/pom.xml index f6cfa7d5d1..d78cebada2 100644 --- a/muleesb/pom.xml +++ b/muleesb/pom.xml @@ -108,7 +108,7 @@ org.mule.tools.maven mule-maven-plugin - 2.2.1 + ${mule-maven-plugin.version} standalone ${mule.version} @@ -203,7 +203,7 @@ mulesoft-release mulesoft release repository default - https://repository.mulesoft.org/releases/ + https://repository.mulesoft.org/nexus/content/repositories/public/ false @@ -212,9 +212,10 @@ 3.9.0 - 1.2 + 1.8 1.3.6 - 1.7 + 1.10 + 2.2.1 diff --git a/pom.xml b/pom.xml index edc5302390..1243eb4522 100644 --- a/pom.xml +++ b/pom.xml @@ -518,7 +518,7 @@ micronaut microprofile msf4j - + muleesb mustache mybatis @@ -1001,7 +1001,7 @@ micronaut microprofile msf4j - + muleesb mustache mybatis From ef88a1803f7bd1b163b02dc54e6f93ecdc8c6150 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Fri, 4 Mar 2022 21:17:23 +0000 Subject: [PATCH 087/249] [JAVA-10432] Rename and enable testng-command-line module --- testing-modules/pom.xml | 1 + .../{testng_command_line => testng-command-line}/README.md | 0 .../{testng_command_line => testng-command-line}/pom.xml | 6 +++--- .../java/com/baeldung/testng}/DateSerializerService.java | 2 +- .../com/baeldung/testng}/DateSerializerServiceUnitTest.java | 3 ++- .../{testng_command_line => testng-command-line}/testng.xml | 2 +- 6 files changed, 8 insertions(+), 6 deletions(-) rename testing-modules/{testng_command_line => testng-command-line}/README.md (100%) rename testing-modules/{testng_command_line => testng-command-line}/pom.xml (97%) rename testing-modules/{testng_command_line/src/main/java/com/baeldung/testing_modules/testng_command_line => testng-command-line/src/main/java/com/baeldung/testng}/DateSerializerService.java (82%) rename testing-modules/{testng_command_line/src/test/java/com/baeldung/testing_modules/testng_command_line => testng-command-line/src/test/java/com/baeldung/testng}/DateSerializerServiceUnitTest.java (87%) rename testing-modules/{testng_command_line => testng-command-line}/testng.xml (67%) diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml index 58ea74484e..3d5db76827 100644 --- a/testing-modules/pom.xml +++ b/testing-modules/pom.xml @@ -45,6 +45,7 @@ testing-libraries-2 testing-libraries testng + testng-command-line xmlunit-2 zerocode diff --git a/testing-modules/testng_command_line/README.md b/testing-modules/testng-command-line/README.md similarity index 100% rename from testing-modules/testng_command_line/README.md rename to testing-modules/testng-command-line/README.md diff --git a/testing-modules/testng_command_line/pom.xml b/testing-modules/testng-command-line/pom.xml similarity index 97% rename from testing-modules/testng_command_line/pom.xml rename to testing-modules/testng-command-line/pom.xml index 4c3af7621c..efc49b187d 100644 --- a/testing-modules/testng_command_line/pom.xml +++ b/testing-modules/testng-command-line/pom.xml @@ -3,10 +3,10 @@ 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"> 4.0.0 - - com.baeldung.testing_modules - testng_command_line + testng-command-line 1.0.0-SNAPSHOT + testng-command-line + com.baeldung testing-modules diff --git a/testing-modules/testng_command_line/src/main/java/com/baeldung/testing_modules/testng_command_line/DateSerializerService.java b/testing-modules/testng-command-line/src/main/java/com/baeldung/testng/DateSerializerService.java similarity index 82% rename from testing-modules/testng_command_line/src/main/java/com/baeldung/testing_modules/testng_command_line/DateSerializerService.java rename to testing-modules/testng-command-line/src/main/java/com/baeldung/testng/DateSerializerService.java index 2c4c1f3a4b..a9a7cc4ee6 100644 --- a/testing-modules/testng_command_line/src/main/java/com/baeldung/testing_modules/testng_command_line/DateSerializerService.java +++ b/testing-modules/testng-command-line/src/main/java/com/baeldung/testng/DateSerializerService.java @@ -1,4 +1,4 @@ -package com.baeldung.testing_modules.testng_command_line; +package com.baeldung.testng; import java.text.SimpleDateFormat; import java.util.Date; diff --git a/testing-modules/testng_command_line/src/test/java/com/baeldung/testing_modules/testng_command_line/DateSerializerServiceUnitTest.java b/testing-modules/testng-command-line/src/test/java/com/baeldung/testng/DateSerializerServiceUnitTest.java similarity index 87% rename from testing-modules/testng_command_line/src/test/java/com/baeldung/testing_modules/testng_command_line/DateSerializerServiceUnitTest.java rename to testing-modules/testng-command-line/src/test/java/com/baeldung/testng/DateSerializerServiceUnitTest.java index 4deb0297f0..2b9a9a0925 100644 --- a/testing-modules/testng_command_line/src/test/java/com/baeldung/testing_modules/testng_command_line/DateSerializerServiceUnitTest.java +++ b/testing-modules/testng-command-line/src/test/java/com/baeldung/testng/DateSerializerServiceUnitTest.java @@ -1,7 +1,8 @@ -package com.baeldung.testing_modules.testng_command_line; +package com.baeldung.testng; import java.util.Date; +import com.baeldung.testng.DateSerializerService; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; diff --git a/testing-modules/testng_command_line/testng.xml b/testing-modules/testng-command-line/testng.xml similarity index 67% rename from testing-modules/testng_command_line/testng.xml rename to testing-modules/testng-command-line/testng.xml index eca48a6d39..4e029f9dc6 100644 --- a/testing-modules/testng_command_line/testng.xml +++ b/testing-modules/testng-command-line/testng.xml @@ -4,7 +4,7 @@ + name="com.baeldung.testng.DateSerializerServiceUnitTest" /> From 3687b7bc643799f8221bf703a5168c7af36e389a Mon Sep 17 00:00:00 2001 From: andresluzu Date: Fri, 4 Mar 2022 21:25:02 -0500 Subject: [PATCH 088/249] BAEL-5335: Introduction to OAuth2RestTemplate (#11849) --- .../oauth2resttemplate/AppController.java | 32 ++++++++ .../oauth2resttemplate/GithubRepo.java | 22 ++++++ .../oauth2resttemplate/SecurityConfig.java | 73 +++++++++++++++++++ ...SpringSecurityOauth2ClientApplication.java | 15 ++++ ...pplication-oauth2-rest-template.properties | 9 +++ .../templates/oauth2resttemplate/error.html | 9 +++ .../templates/oauth2resttemplate/home.html | 18 +++++ .../templates/oauth2resttemplate/index.html | 16 ++++ .../oauth2resttemplate/repositories.html | 14 ++++ 9 files changed, 208 insertions(+) create mode 100644 spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/AppController.java create mode 100644 spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/GithubRepo.java create mode 100644 spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SecurityConfig.java create mode 100644 spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SpringSecurityOauth2ClientApplication.java create mode 100644 spring-security-modules/spring-5-security-oauth/src/main/resources/application-oauth2-rest-template.properties create mode 100644 spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/error.html create mode 100644 spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/home.html create mode 100644 spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/index.html create mode 100644 spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/repositories.html diff --git a/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/AppController.java b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/AppController.java new file mode 100644 index 0000000000..3c3efd950f --- /dev/null +++ b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/AppController.java @@ -0,0 +1,32 @@ +package com.baeldung.oauth2resttemplate; + +import org.springframework.security.oauth2.client.OAuth2RestTemplate; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; + +import java.security.Principal; +import java.util.Collection; + +@Controller +public class AppController { + + OAuth2RestTemplate restTemplate; + + public AppController(OAuth2RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + @GetMapping("/home") + public String welcome(Model model, Principal principal) { + model.addAttribute("name", principal.getName()); + return "home"; + } + + @GetMapping("/repos") + public String repos(Model model) { + Collection repos = restTemplate.getForObject("https://api.github.com/user/repos", Collection.class); + model.addAttribute("repos", repos); + return "repositories"; + } +} diff --git a/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/GithubRepo.java b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/GithubRepo.java new file mode 100644 index 0000000000..48cc05c1de --- /dev/null +++ b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/GithubRepo.java @@ -0,0 +1,22 @@ +package com.baeldung.oauth2resttemplate; + +public class GithubRepo { + Long id; + String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SecurityConfig.java b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SecurityConfig.java new file mode 100644 index 0000000000..fa274d1c9b --- /dev/null +++ b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SecurityConfig.java @@ -0,0 +1,73 @@ +package com.baeldung.oauth2resttemplate; + +import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties; +import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.oauth2.client.OAuth2ClientContext; +import org.springframework.security.oauth2.client.OAuth2RestTemplate; +import org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter; +import org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter; +import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +import javax.servlet.Filter; + +@Configuration +@EnableOAuth2Client +public class SecurityConfig extends WebSecurityConfigurerAdapter { + OAuth2ClientContext oauth2ClientContext; + + public SecurityConfig(OAuth2ClientContext oauth2ClientContext) { + this.oauth2ClientContext = oauth2ClientContext; + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests().antMatchers("/", "/login**", "/error**") + .permitAll().anyRequest().authenticated() + .and().logout().logoutUrl("/logout").logoutSuccessUrl("/") + .and().addFilterBefore(oauth2ClientFilter(), BasicAuthenticationFilter.class); + } + + @Bean + public FilterRegistrationBean oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) { + FilterRegistrationBean registration = new FilterRegistrationBean<>(); + registration.setFilter(filter); + registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1); + return registration; + } + + @Bean + public OAuth2RestTemplate restTemplate() { + return new OAuth2RestTemplate(githubClient(), oauth2ClientContext); + } + + @Bean + @ConfigurationProperties("github.client") + public AuthorizationCodeResourceDetails githubClient() { + return new AuthorizationCodeResourceDetails(); + } + + private Filter oauth2ClientFilter() { + OAuth2ClientAuthenticationProcessingFilter oauth2ClientFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/github"); + OAuth2RestTemplate restTemplate = restTemplate(); + oauth2ClientFilter.setRestTemplate(restTemplate); + UserInfoTokenServices tokenServices = new UserInfoTokenServices(githubResource().getUserInfoUri(), githubClient().getClientId()); + tokenServices.setRestTemplate(restTemplate); + oauth2ClientFilter.setTokenServices(tokenServices); + return oauth2ClientFilter; + } + + @Bean + @ConfigurationProperties("github.resource") + public ResourceServerProperties githubResource() { + return new ResourceServerProperties(); + } +} diff --git a/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SpringSecurityOauth2ClientApplication.java b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SpringSecurityOauth2ClientApplication.java new file mode 100644 index 0000000000..846169e5bf --- /dev/null +++ b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SpringSecurityOauth2ClientApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.oauth2resttemplate; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:application-oauth2-rest-template.properties") +public class SpringSecurityOauth2ClientApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringSecurityOauth2ClientApplication.class, args); + } + +} diff --git a/spring-security-modules/spring-5-security-oauth/src/main/resources/application-oauth2-rest-template.properties b/spring-security-modules/spring-5-security-oauth/src/main/resources/application-oauth2-rest-template.properties new file mode 100644 index 0000000000..15d34b76be --- /dev/null +++ b/spring-security-modules/spring-5-security-oauth/src/main/resources/application-oauth2-rest-template.properties @@ -0,0 +1,9 @@ +github.client.clientId=[CLIENT_ID] +github.client.clientSecret=[CLIENT_SECRET] +github.client.userAuthorizationUri=https://github.com/login/oauth/authorize +github.client.accessTokenUri=https://github.com/login/oauth/access_token +github.client.clientAuthenticationScheme=form + +github.resource.userInfoUri=https://api.github.com/user + +spring.thymeleaf.prefix=classpath:/templates/oauth2resttemplate/ \ No newline at end of file diff --git a/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/error.html b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/error.html new file mode 100644 index 0000000000..45bcddf654 --- /dev/null +++ b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/error.html @@ -0,0 +1,9 @@ + + + + Error + + +

An error occurred.

+ + \ No newline at end of file diff --git a/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/home.html b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/home.html new file mode 100644 index 0000000000..3eba3615d6 --- /dev/null +++ b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/home.html @@ -0,0 +1,18 @@ + + + + Home + + +

+ Welcome [[${name}]] +

+

+ View Repositories

+

+ +
+ +
+ + \ No newline at end of file diff --git a/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/index.html b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/index.html new file mode 100644 index 0000000000..4db3b78d23 --- /dev/null +++ b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/index.html @@ -0,0 +1,16 @@ + + + + OAuth2Client + + +

+ + Go to Home + + + GitHub Login + +

+ + \ No newline at end of file diff --git a/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/repositories.html b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/repositories.html new file mode 100644 index 0000000000..1eabf2270f --- /dev/null +++ b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/repositories.html @@ -0,0 +1,14 @@ + + + + Repositories + + +

+

Repos

+

+
    +
  • +
+ + \ No newline at end of file From 9da940a252d11c7489101232c76c2f710fa2bbed Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Sun, 6 Mar 2022 00:41:44 +0000 Subject: [PATCH 089/249] [JAVA-10398] Rename intermittent failing test to ManualTest --- ...st.java => IllegalMonitorStateExceptionManualTest.java} | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) rename core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/illegalmonitorstate/{IllegalMonitorStateExceptionUnitTest.java => IllegalMonitorStateExceptionManualTest.java} (91%) diff --git a/core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/illegalmonitorstate/IllegalMonitorStateExceptionUnitTest.java b/core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/illegalmonitorstate/IllegalMonitorStateExceptionManualTest.java similarity index 91% rename from core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/illegalmonitorstate/IllegalMonitorStateExceptionUnitTest.java rename to core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/illegalmonitorstate/IllegalMonitorStateExceptionManualTest.java index 857ab02c13..31807255e8 100644 --- a/core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/illegalmonitorstate/IllegalMonitorStateExceptionUnitTest.java +++ b/core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/illegalmonitorstate/IllegalMonitorStateExceptionManualTest.java @@ -7,7 +7,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -public class IllegalMonitorStateExceptionUnitTest { +/** + * Needs to be run manually in order to demonstrate the IllegalMonitorStateException scenarios. + * + * There are some intermittent test failures in Jenkins that require further investigation. + */ +public class IllegalMonitorStateExceptionManualTest { @Test void whenSyncSenderAndSyncReceiverAreUsed_thenIllegalMonitorExceptionShouldNotBeThrown() throws InterruptedException { From dafb4d1f580dfb30b3c85f7b7c9bb7c62449e260 Mon Sep 17 00:00:00 2001 From: Kapil Khandelwal Date: Sun, 6 Mar 2022 09:59:16 +0530 Subject: [PATCH 090/249] BAEL-5401: Update Fields of Documents in MongoDB Using the Java Driver (#11889) --- .../baeldung/mongo/update/UpdateFields.java | 128 ++++++++++++++++ .../baeldung/update/UpdateFieldLiveTest.java | 143 ++++++++++++++++++ 2 files changed, 271 insertions(+) create mode 100644 persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateFields.java create mode 100644 persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateFieldLiveTest.java diff --git a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateFields.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateFields.java new file mode 100644 index 0000000000..a1b051e74c --- /dev/null +++ b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateFields.java @@ -0,0 +1,128 @@ +package com.baeldung.mongo.update; + +import org.bson.Document; + +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.FindOneAndReplaceOptions; +import com.mongodb.client.model.FindOneAndUpdateOptions; +import com.mongodb.client.model.ReturnDocument; +import com.mongodb.client.model.Updates; +import com.mongodb.client.result.UpdateResult; + +public class UpdateFields { + + private static MongoClient mongoClient; + private static MongoDatabase database; + private static MongoCollection collection; + + public static void updateOne() { + + UpdateResult updateResult = collection.updateOne(Filters.eq("student_name", "Paul Starc"), Updates.set("address", "Hostel 2")); + + System.out.println("updateResult:- " + updateResult); + } + + public static void updateMany() { + + UpdateResult updateResult = collection.updateMany(Filters.lt("age", 20), Updates.set("Review", true)); + + System.out.println("updateResult:- " + updateResult); + + } + + public static void replaceOne() { + + Document replaceDocument = new Document(); + replaceDocument.append("student_id", 8764) + .append("student_name", "Paul Starc") + .append("address", "Hostel 3") + .append("age", 18) + .append("roll_no", 199406); + + UpdateResult updateResult = collection.replaceOne(Filters.eq("student_id", 8764), replaceDocument); + + System.out.println("updateResult:- " + updateResult); + + } + + public static void findOneAndReplace() { + + Document replaceDocument = new Document(); + replaceDocument.append("student_id", 8764) + .append("student_name", "Paul Starc") + .append("address", "Hostel 4") + .append("age", 18) + .append("roll_no", 199406); + Document sort = new Document("roll_no", 1); + Document projection = new Document("_id", 0).append("student_id", 1) + .append("address", 1); + Document resultDocument = collection.findOneAndReplace(Filters.eq("student_id", 8764), replaceDocument, new FindOneAndReplaceOptions().upsert(true) + .sort(sort) + .projection(projection) + .returnDocument(ReturnDocument.AFTER)); + + System.out.println("resultDocument:- " + resultDocument); + + } + + public static void findOneAndUpdate() { + + Document sort = new Document("roll_no", 1); + Document projection = new Document("_id", 0).append("student_id", 1) + .append("address", 1); + Document resultDocument = collection.findOneAndUpdate(Filters.eq("student_id", 8764), Updates.inc("roll_no", 5), new FindOneAndUpdateOptions().upsert(true) + .sort(sort) + .projection(projection) + .returnDocument(ReturnDocument.AFTER)); + + System.out.println("resultDocument:- " + resultDocument); + } + + public static void setup() { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + database = mongoClient.getDatabase("baeldung"); + collection = database.getCollection("student"); + + } + } + + public static void main(String[] args) { + + // + // Connect to cluster (default is localhost:27017) + // + setup(); + + // + // Update a document using updateOne method + // + updateOne(); + + // + // Update documents using updateMany method + // + updateMany(); + + // + // replace a document using replaceOne method + // + replaceOne(); + + // + // replace a document using findOneAndReplace method + // + findOneAndReplace(); + + // + // Update a document using findOneAndUpdate method + // + findOneAndUpdate(); + + } + +} + diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateFieldLiveTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateFieldLiveTest.java new file mode 100644 index 0000000000..47114e1f1a --- /dev/null +++ b/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateFieldLiveTest.java @@ -0,0 +1,143 @@ +package com.baeldung.update; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import org.bson.Document; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.FindOneAndReplaceOptions; +import com.mongodb.client.model.FindOneAndUpdateOptions; +import com.mongodb.client.model.ReturnDocument; +import com.mongodb.client.model.Updates; +import com.mongodb.client.result.UpdateResult; + +public class UpdateFieldLiveTest { + + private static MongoClient mongoClient; + private static MongoDatabase db; + private static MongoCollection collection; + + @BeforeClass + public static void setup() { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + db = mongoClient.getDatabase("baeldung"); + collection = db.getCollection("student"); + + collection.insertOne(Document.parse("{ \"student_id\": 8764,\"student_name\": \"Paul Starc\",\"address\": \"Hostel 1\",\"age\": 16,\"roll_no\":199406}")); + } + } + + @Test + public void updateOne() { + + UpdateResult updateResult = collection.updateOne(Filters.eq("student_name", "Paul Starc"), Updates.set("address", "Hostel 2")); + + Document studentDetail = collection.find(Filters.eq("student_name", "Paul Starc")) + .first(); + assertNotNull(studentDetail); + assertFalse(studentDetail.isEmpty()); + + String address = studentDetail.getString("address"); + String expectedAdderess = "Hostel 2"; + + assertEquals(expectedAdderess, address); + } + + @Test + public void updateMany() { + + UpdateResult updateResult = collection.updateMany(Filters.lt("age", 20), Updates.set("Review", true)); + + Document studentDetail = collection.find(Filters.eq("student_name", "Paul Starc")) + .first(); + assertNotNull(studentDetail); + assertFalse(studentDetail.isEmpty()); + + Boolean review = studentDetail.getBoolean("Review"); + Boolean expectedAdderess = true; + + assertEquals(expectedAdderess, review); + + } + + @Test + public void replaceOne() { + + Document replaceDocument = new Document(); + replaceDocument.append("student_id", 8764) + .append("student_name", "Paul Starc") + .append("address", "Hostel 3") + .append("age", 18) + .append("roll_no", 199406); + + UpdateResult updateResult = collection.replaceOne(Filters.eq("student_id", 8764), replaceDocument); + + Document studentDetail = collection.find(Filters.eq("student_name", "Paul Starc")) + .first(); + assertNotNull(studentDetail); + assertFalse(studentDetail.isEmpty()); + + Integer age = studentDetail.getInteger("age"); + Integer expectedAge = 18; + + assertEquals(expectedAge, age); + + } + + @Test + public void findOneAndReplace() { + + Document replaceDocument = new Document(); + replaceDocument.append("student_id", 8764) + .append("student_name", "Paul Starc") + .append("address", "Hostel 4") + .append("age", 18) + .append("roll_no", 199406); + Document sort = new Document("roll_no", 1); + Document projection = new Document("_id", 0).append("student_id", 1) + .append("address", 1); + Document resultDocument = collection.findOneAndReplace(Filters.eq("student_id", 8764), replaceDocument, new FindOneAndReplaceOptions().upsert(true) + .sort(sort) + .projection(projection) + .returnDocument(ReturnDocument.AFTER)); + + Document studentDetail = collection.find(Filters.eq("student_name", "Paul Starc")) + .first(); + assertNotNull(studentDetail); + assertFalse(studentDetail.isEmpty()); + + Integer age = studentDetail.getInteger("age"); + Integer expectedAge = 18; + + assertEquals(expectedAge, age); + + } + + @Test + public void findOneAndUpdate() { + + Document sort = new Document("roll_no", 1); + Document projection = new Document("_id", 0).append("student_id", 1) + .append("address", 1); + Document resultDocument = collection.findOneAndUpdate(Filters.eq("student_id", 8764), Updates.inc("roll_no", 5), new FindOneAndUpdateOptions().upsert(true) + .sort(sort) + .projection(projection) + .returnDocument(ReturnDocument.AFTER)); + + Document studentDetail = collection.find(Filters.eq("student_name", "Paul Starc")) + .first(); + assertNotNull(studentDetail); + assertFalse(studentDetail.isEmpty()); + + } + +} + From f0d831095be920798663ede3d8a1a10dbc23280f Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Sun, 6 Mar 2022 11:56:55 +0500 Subject: [PATCH 091/249] Updated README.md Fixed link for Introduction to Awaitility, from https://www.baeldung.com/awaitlity-testing to https://www.baeldung.com/awaitility-testing --- libraries-testing/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries-testing/README.md b/libraries-testing/README.md index 5498c73094..880c3dd2e6 100644 --- a/libraries-testing/README.md +++ b/libraries-testing/README.md @@ -8,7 +8,7 @@ This module contains articles about test libraries. - [Introduction to JSONassert](https://www.baeldung.com/jsonassert) - [Serenity BDD and Screenplay](https://www.baeldung.com/serenity-screenplay) - [Serenity BDD with Spring and JBehave](https://www.baeldung.com/serenity-spring-jbehave) -- [Introduction to Awaitility](https://www.baeldung.com/awaitlity-testing) +- [Introduction to Awaitility](https://www.baeldung.com/awaitility-testing) - [Introduction to Hoverfly in Java](https://www.baeldung.com/hoverfly) - [Testing with Hamcrest](https://www.baeldung.com/java-junit-hamcrest-guide) - [Introduction To DBUnit](https://www.baeldung.com/java-dbunit) From 20b50e8bea8f6966ec507e6c0444204464c4fcce Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Sun, 6 Mar 2022 12:54:13 +0500 Subject: [PATCH 092/249] Updated README.md For Enabling Logging for Apache HttpClient, Correct URL from https://www.baeldung.com/java-httpclient-enable-logging to https://www.baeldung.com/apache-httpclient-enable-logging --- httpclient-2/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient-2/README.md b/httpclient-2/README.md index 7c2d5862bd..4f9805063c 100644 --- a/httpclient-2/README.md +++ b/httpclient-2/README.md @@ -11,5 +11,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [How to Set TLS Version in Apache HttpClient](https://www.baeldung.com/apache-httpclient-tls) - [Reading an HTTP Response Body as a String in Java](https://www.baeldung.com/java-http-response-body-as-string) - [How To Get Cookies From the Apache HttpClient Response](https://www.baeldung.com/java-apache-httpclient-cookies) -- [Enabling Logging for Apache HttpClient](https://www.baeldung.com/java-httpclient-enable-logging) +- [Enabling Logging for Apache HttpClient](https://www.baeldung.com/apache-httpclient-enable-logging) - More articles: [[<-- prev]](../httpclient) From 612bb329e572003a08d1cc028e3fc0ff8a87730d Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Sun, 6 Mar 2022 13:04:52 +0500 Subject: [PATCH 093/249] Updated README.md For Adding Parameters to HttpClient Requests, corrected link from https://www.baeldung.com/java-httpclient-parameters to https://www.baeldung.com/apache-httpclient-parameters --- httpclient-simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient-simple/README.md b/httpclient-simple/README.md index 93fb22ac1e..8875af1ea0 100644 --- a/httpclient-simple/README.md +++ b/httpclient-simple/README.md @@ -11,7 +11,7 @@ This module contains articles about HTTPClient that are part of the HTTPClient E - [Custom HTTP Header with the HttpClient](https://www.baeldung.com/httpclient-custom-http-header) - [HttpClient Basic Authentication](https://www.baeldung.com/httpclient-4-basic-authentication) - [Posting with HttpClient](https://www.baeldung.com/httpclient-post-http-request) -- [Adding Parameters to HttpClient Requests](https://www.baeldung.com/java-httpclient-parameters) +- [Adding Parameters to HttpClient Requests](https://www.baeldung.com/apache-httpclient-parameters) ### Running the Tests From 3fbad0691d0276daa18c613c30e970c64b0b98ab Mon Sep 17 00:00:00 2001 From: alemoles Date: Mon, 7 Mar 2022 01:34:14 -0500 Subject: [PATCH 094/249] BAEL-5418 - Convert long to int type in Java (#8) (#11895) --- java-numbers-4/pom.xml | 5 +++ .../convertLongToInt/ConvertLongToInt.java | 44 +++++++++++++++++++ .../ConvertLongToIntUnitTest.java | 23 ++++++++++ 3 files changed, 72 insertions(+) create mode 100644 java-numbers-4/src/main/java/com/baeldung/convertLongToInt/ConvertLongToInt.java create mode 100644 java-numbers-4/src/test/java/com/baeldung/convertLongToInt/ConvertLongToIntUnitTest.java diff --git a/java-numbers-4/pom.xml b/java-numbers-4/pom.xml index 9b2e799840..40fe17cc0d 100644 --- a/java-numbers-4/pom.xml +++ b/java-numbers-4/pom.xml @@ -25,6 +25,11 @@ ${commons-lang3.version} test + + com.google.guava + guava + ${guava.version} + diff --git a/java-numbers-4/src/main/java/com/baeldung/convertLongToInt/ConvertLongToInt.java b/java-numbers-4/src/main/java/com/baeldung/convertLongToInt/ConvertLongToInt.java new file mode 100644 index 0000000000..0638505c2d --- /dev/null +++ b/java-numbers-4/src/main/java/com/baeldung/convertLongToInt/ConvertLongToInt.java @@ -0,0 +1,44 @@ +package com.baeldung.convertLongToInt; + +import java.math.BigDecimal; +import java.util.Optional; +import java.util.function.Function; + +import com.google.common.primitives.Ints; + +public class ConvertLongToInt { + + static Function convert = val -> Optional.ofNullable(val) + .map(Long::intValue) + .orElse(null); + + public static int longToIntCast(long number) { + return (int) number; + } + + public static int longToIntJavaWithMath(long number) { + return Math.toIntExact(number); + } + + public static int longToIntJavaWithLambda(long number) { + return convert.apply(number); + } + + public static int longToIntBoxingValues(long number) { + return Long.valueOf(number) + .intValue(); + } + + public static int longToIntGuava(long number) { + return Ints.checkedCast(number); + } + + public static int longToIntGuavaSaturated(long number) { + return Ints.saturatedCast(number); + } + + public static int longToIntWithBigDecimal(long number) { + return new BigDecimal(number).intValueExact(); + } + +} diff --git a/java-numbers-4/src/test/java/com/baeldung/convertLongToInt/ConvertLongToIntUnitTest.java b/java-numbers-4/src/test/java/com/baeldung/convertLongToInt/ConvertLongToIntUnitTest.java new file mode 100644 index 0000000000..38fa37b664 --- /dev/null +++ b/java-numbers-4/src/test/java/com/baeldung/convertLongToInt/ConvertLongToIntUnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung.convertLongToInt; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class ConvertLongToIntUnitTest { + + @Test + void longToInt() { + long number = 186762L; + int expected = 186762; + + assertEquals(expected, ConvertLongToInt.longToIntCast(number)); + assertEquals(expected, ConvertLongToInt.longToIntJavaWithMath(number)); + assertEquals(expected, ConvertLongToInt.longToIntJavaWithLambda(number)); + assertEquals(expected, ConvertLongToInt.longToIntBoxingValues(number)); + assertEquals(expected, ConvertLongToInt.longToIntGuava(number)); + assertEquals(expected, ConvertLongToInt.longToIntGuavaSaturated(number)); + assertEquals(expected, ConvertLongToInt.longToIntWithBigDecimal(number)); + } + +} \ No newline at end of file From 08e84780bfcd9170d5fb207a5de0c6d6328cc16a Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Mon, 7 Mar 2022 17:50:33 +0500 Subject: [PATCH 095/249] Updated README.md added link back to the article: https://www.baeldung.com/java-read-file-into-map --- core-java-modules/core-java-io-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-io-4/README.md b/core-java-modules/core-java-io-4/README.md index be58338fd8..39b820b3ba 100644 --- a/core-java-modules/core-java-io-4/README.md +++ b/core-java-modules/core-java-io-4/README.md @@ -7,4 +7,5 @@ This module contains articles about core Java input and output (IO) - [Java File Separator vs File Path Separator](https://www.baeldung.com/java-file-vs-file-path-separator) - [Simulate touch Command in Java](https://www.baeldung.com/java-simulate-touch-command) - [SequenceInputStream Class in Java](https://www.baeldung.com/java-sequenceinputstream) +- [Read a File Into a Map in Java](https://www.baeldung.com/java-read-file-into-map) - [[<-- Prev]](/core-java-modules/core-java-io-3) From 6fe59e7aeab0385c05d423b948d46e0ee06412ea Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Mon, 7 Mar 2022 17:54:47 +0500 Subject: [PATCH 096/249] Updated README.md added link back to the article: https://www.baeldung.com/java-rock-paper-scissors --- core-java-modules/core-java-8-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-8-2/README.md b/core-java-modules/core-java-8-2/README.md index 12a060ccfe..c0bc63f21f 100644 --- a/core-java-modules/core-java-8-2/README.md +++ b/core-java-modules/core-java-8-2/README.md @@ -9,4 +9,5 @@ This module contains articles about Java 8 core features - [Guide to Java BiFunction Interface](https://www.baeldung.com/java-bifunction-interface) - [Interface With Default Methods vs Abstract Class](https://www.baeldung.com/java-interface-default-method-vs-abstract-class) - [Convert Between Byte Array and UUID in Java](https://www.baeldung.com/java-byte-array-to-uuid) +- [Create a Simple “Rock-Paper-Scissors” Game in Java](https://www.baeldung.com/java-rock-paper-scissors) - [[<-- Prev]](/core-java-modules/core-java-8) From 3f71dcc5c757e3a40dd07c56caddb5df3ca22d8f Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Mon, 7 Mar 2022 17:57:11 +0500 Subject: [PATCH 097/249] Updated README.md added link back to the article: https://www.baeldung.com/java-call-graphql-service --- graphql/graphql-java/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/graphql/graphql-java/README.md b/graphql/graphql-java/README.md index e3fd818400..f37506a9fd 100644 --- a/graphql/graphql-java/README.md +++ b/graphql/graphql-java/README.md @@ -5,3 +5,4 @@ This module contains articles about GraphQL with Java ## Relevant articles: - [Introduction to GraphQL](https://www.baeldung.com/graphql) +- [Make a Call to a GraphQL Service from a Java Application](https://www.baeldung.com/java-call-graphql-service) From b86e50ede4ebaac6d1f1f3bfe6ad5b2e73f3a1c8 Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Mon, 7 Mar 2022 18:00:52 +0500 Subject: [PATCH 098/249] Updated README.md added link back to the article: https://www.baeldung.com/java-excel-find-last-row --- apache-poi-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/apache-poi-2/README.md b/apache-poi-2/README.md index 2fd0135b11..f55ec7eb6a 100644 --- a/apache-poi-2/README.md +++ b/apache-poi-2/README.md @@ -9,4 +9,5 @@ This module contains articles about Apache POI. - [Numeric Format Using POI](https://www.baeldung.com/apache-poi-numeric-format) - [Microsoft Word Processing in Java with Apache POI](https://www.baeldung.com/java-microsoft-word-with-apache-poi) - [Creating a MS PowerPoint Presentation in Java](https://www.baeldung.com/apache-poi-slideshow) +- [Finding the Last Row in an Excel Spreadsheet From Java](https://www.baeldung.com/java-excel-find-last-row) - More articles: [[<-- prev]](../apache-poi) From dc6357d98eab194031d35ea7664b4bdfcafe1150 Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Mon, 7 Mar 2022 19:22:54 +0500 Subject: [PATCH 099/249] Updated README.md added link back to the article: https://www.baeldung.com/mongodb-update-multiple-fields --- persistence-modules/java-mongodb/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-mongodb/README.md b/persistence-modules/java-mongodb/README.md index fe30c2999e..2b7fcd3de0 100644 --- a/persistence-modules/java-mongodb/README.md +++ b/persistence-modules/java-mongodb/README.md @@ -13,3 +13,4 @@ This module contains articles about MongoDB in Java. - [BSON to JSON Document Conversion in Java](https://www.baeldung.com/java-convert-bson-to-json) - [How to Check Field Existence in MongoDB?](https://www.baeldung.com/mongodb-check-field-exists) - [Get Last Inserted Document ID in MongoDB With Java Driver](https://www.baeldung.com/java-mongodb-last-inserted-id) +- [Update Multiple Fields in a MongoDB Document](https://www.baeldung.com/mongodb-update-multiple-fields) From db95e7bb6ad8ce3528ec2a1e7cef836b70949b53 Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Mon, 7 Mar 2022 19:27:14 +0500 Subject: [PATCH 100/249] Updated README.md added link back to the article: https://www.baeldung.com/lombok-tostring --- lombok-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/lombok-2/README.md b/lombok-2/README.md index 25d097a7ea..650dc5ddab 100644 --- a/lombok-2/README.md +++ b/lombok-2/README.md @@ -7,4 +7,5 @@ This module contains articles about Project Lombok. - [Using Lombok’s @Accessors Annotation](https://www.baeldung.com/lombok-accessors) - [Declaring Val and Var Variables in Lombok](https://www.baeldung.com/java-lombok-val-var) - [Lombok Using @With Annotations](https://www.baeldung.com/lombok-with-annotations) +- [Lombok's @ToString Annotation](https://www.baeldung.com/lombok-tostring) - More articles: [[<-- prev]](../lombok) From 3d92ca2c4169f0d206d20e8f002f5fc325bf47b3 Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Mon, 7 Mar 2022 19:31:42 +0500 Subject: [PATCH 101/249] Updated README.md added a link back to the article: https://www.baeldung.com/java-bytebuffer --- core-java-modules/core-java-nio-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-nio-2/README.md b/core-java-modules/core-java-nio-2/README.md index 9152a494d8..c405cb7c77 100644 --- a/core-java-modules/core-java-nio-2/README.md +++ b/core-java-modules/core-java-nio-2/README.md @@ -12,4 +12,5 @@ This module contains articles about core Java non-blocking input and output (IO) - [Java NIO DatagramChannel](https://www.baeldung.com/java-nio-datagramchannel) - [Java – Path vs File](https://www.baeldung.com/java-path-vs-file) - [What Is the Difference Between NIO and NIO.2?](https://www.baeldung.com/java-nio-vs-nio-2) +- [Guide to ByteBuffer](https://www.baeldung.com/java-bytebuffer) - [[<-- Prev]](/core-java-modules/core-java-nio) From 32c7041a18d3a649750c9f851710bd7dfb10b099 Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Mon, 7 Mar 2022 19:35:42 +0500 Subject: [PATCH 102/249] Updated README.md added a link back to the article: https://www.baeldung.com/spring-oauth2resttemplate --- spring-security-modules/spring-5-security-oauth/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-security-modules/spring-5-security-oauth/README.md b/spring-security-modules/spring-5-security-oauth/README.md index 35e64da639..e5b149fee6 100644 --- a/spring-security-modules/spring-5-security-oauth/README.md +++ b/spring-security-modules/spring-5-security-oauth/README.md @@ -8,3 +8,4 @@ This module contains articles about Spring 5 OAuth Security - [Extracting Principal and Authorities using Spring Security OAuth](https://www.baeldung.com/spring-security-oauth-principal-authorities-extractor) - [Customizing Authorization and Token Requests with Spring Security 5.1 Client](https://www.baeldung.com/spring-security-custom-oauth-requests) - [Social Login with Spring Security in a Jersey Application](https://www.baeldung.com/spring-security-social-login-jersey) +- [Introduction to OAuth2RestTemplate](https://www.baeldung.com/spring-oauth2resttemplate) From 0f82785c28f01746abd64065d717e261ed260227 Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Mon, 7 Mar 2022 15:40:21 +0100 Subject: [PATCH 103/249] JAVA-10334: Disable failing test --- .../spring/statemachine/StateMachineIntegrationTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spring-state-machine/src/test/java/com/baeldung/spring/statemachine/StateMachineIntegrationTest.java b/spring-state-machine/src/test/java/com/baeldung/spring/statemachine/StateMachineIntegrationTest.java index aab07225a3..5909340a82 100644 --- a/spring-state-machine/src/test/java/com/baeldung/spring/statemachine/StateMachineIntegrationTest.java +++ b/spring-state-machine/src/test/java/com/baeldung/spring/statemachine/StateMachineIntegrationTest.java @@ -3,6 +3,7 @@ package com.baeldung.spring.statemachine; import com.baeldung.spring.statemachine.config.SimpleStateMachineConfiguration; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -36,6 +37,7 @@ public class StateMachineIntegrationTest { assertEquals("S2", stateMachine.getState().getId()); } + @Ignore("Fixing in JAVA-9808") @Test public void whenSimpleStringMachineActionState_thenActionExecuted() { From 53afccfe3a5cfb746e70559d8337b215eb15944b Mon Sep 17 00:00:00 2001 From: Olsi Seferi <72546616+olsiseferi@users.noreply.github.com> Date: Mon, 7 Mar 2022 17:58:13 +0100 Subject: [PATCH 104/249] ADDED FORWARD PROXY CONFIGURATION AND CLIENT (#11708) --- nginx-forward-proxy/forward | 7 + nginx-forward-proxy/package-lock.json | 339 ++++++++++++++++++++++++++ nginx-forward-proxy/package.json | 14 ++ nginx-forward-proxy/proxytest.js | 11 + 4 files changed, 371 insertions(+) create mode 100644 nginx-forward-proxy/forward create mode 100644 nginx-forward-proxy/package-lock.json create mode 100644 nginx-forward-proxy/package.json create mode 100644 nginx-forward-proxy/proxytest.js diff --git a/nginx-forward-proxy/forward b/nginx-forward-proxy/forward new file mode 100644 index 0000000000..4e8ca8b29f --- /dev/null +++ b/nginx-forward-proxy/forward @@ -0,0 +1,7 @@ +server { + listen 8888; + location / { + resolver 8.8.8.8; + proxy_pass http://$http_host$uri$is_args$args; + } +} \ No newline at end of file diff --git a/nginx-forward-proxy/package-lock.json b/nginx-forward-proxy/package-lock.json new file mode 100644 index 0000000000..b70787ec67 --- /dev/null +++ b/nginx-forward-proxy/package-lock.json @@ -0,0 +1,339 @@ +{ + "name": "nginx-forward-proxy", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + }, + "mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "requires": { + "mime-db": "1.51.0" + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + } + } +} diff --git a/nginx-forward-proxy/package.json b/nginx-forward-proxy/package.json new file mode 100644 index 0000000000..4691542900 --- /dev/null +++ b/nginx-forward-proxy/package.json @@ -0,0 +1,14 @@ +{ + "name": "nginx-forward-proxy", + "version": "1.0.0", + "description": "Simple Client for Connecting to a Forward Proxy", + "main": "proxytest.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Olsi Seferi", + "license": "ISC", + "dependencies": { + "request": "^2.88.2" + } +} diff --git a/nginx-forward-proxy/proxytest.js b/nginx-forward-proxy/proxytest.js new file mode 100644 index 0000000000..dc55ef6620 --- /dev/null +++ b/nginx-forward-proxy/proxytest.js @@ -0,0 +1,11 @@ +var request = require('request'); + +request({ + 'url':'http://www.google.com/', + 'method': "GET", + 'proxy':'http://192.168.100.40:8888' +},function (error, response, body) { + if (!error && response.statusCode == 200) { + console.log(body); + } +}) From 2859935089915c46036c7d27b29c6913a2efe156 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Mon, 7 Mar 2022 16:32:43 +0000 Subject: [PATCH 105/249] [JAVA-10463] Split apache-poi module --- apache-poi-2/README.md | 1 + apache-poi-2/pom.xml | 2 +- .../poi/excel/setformula/ExcelFormula.java | 51 ++++--- .../poi/excel/setformula/SetFormulaTest.xlsx | Bin .../setformula/ExcelFormulaUnitTest.java | 11 +- apache-poi/README.md | 1 - .../baeldung/poi/excel/ExcelUtility.java.orig | 128 ------------------ .../poi/excel/ExcelUtilityUnitTest.java.orig | 112 --------------- 8 files changed, 33 insertions(+), 273 deletions(-) rename {apache-poi => apache-poi-2}/src/main/java/com/baeldung/poi/excel/setformula/ExcelFormula.java (88%) rename {apache-poi => apache-poi-2}/src/main/resources/com/baeldung/poi/excel/setformula/SetFormulaTest.xlsx (100%) rename {apache-poi => apache-poi-2}/src/test/java/com/baeldung/poi/excel/setformula/ExcelFormulaUnitTest.java (85%) delete mode 100644 apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java.orig delete mode 100644 apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java.orig diff --git a/apache-poi-2/README.md b/apache-poi-2/README.md index f55ec7eb6a..2c0deec575 100644 --- a/apache-poi-2/README.md +++ b/apache-poi-2/README.md @@ -10,4 +10,5 @@ This module contains articles about Apache POI. - [Microsoft Word Processing in Java with Apache POI](https://www.baeldung.com/java-microsoft-word-with-apache-poi) - [Creating a MS PowerPoint Presentation in Java](https://www.baeldung.com/apache-poi-slideshow) - [Finding the Last Row in an Excel Spreadsheet From Java](https://www.baeldung.com/java-excel-find-last-row) +- [Setting Formulas in Excel with Apache POI](https://www.baeldung.com/java-apache-poi-set-formulas) - More articles: [[<-- prev]](../apache-poi) diff --git a/apache-poi-2/pom.xml b/apache-poi-2/pom.xml index a46365c63c..30270cd7be 100644 --- a/apache-poi-2/pom.xml +++ b/apache-poi-2/pom.xml @@ -22,7 +22,7 @@ - 5.0.0 + 5.2.0 diff --git a/apache-poi/src/main/java/com/baeldung/poi/excel/setformula/ExcelFormula.java b/apache-poi-2/src/main/java/com/baeldung/poi/excel/setformula/ExcelFormula.java similarity index 88% rename from apache-poi/src/main/java/com/baeldung/poi/excel/setformula/ExcelFormula.java rename to apache-poi-2/src/main/java/com/baeldung/poi/excel/setformula/ExcelFormula.java index f5179b19c9..ccff1fa709 100644 --- a/apache-poi/src/main/java/com/baeldung/poi/excel/setformula/ExcelFormula.java +++ b/apache-poi-2/src/main/java/com/baeldung/poi/excel/setformula/ExcelFormula.java @@ -1,26 +1,25 @@ -package com.baeldung.poi.excel.setformula; - -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; - -public class ExcelFormula { - public double setFormula(String fileLocation, XSSFWorkbook wb, String formula) throws IOException { - XSSFSheet sheet = wb.getSheetAt(0); - int lastCellNum = sheet.getRow(0).getLastCellNum(); - XSSFCell formulaCell = sheet.getRow(0).createCell(lastCellNum); - formulaCell.setCellFormula(formula); - XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator(); - formulaEvaluator.evaluateFormulaCell(formulaCell); - FileOutputStream fileOut = new FileOutputStream(new File(fileLocation)); - wb.write(fileOut); - wb.close(); - fileOut.close(); - return formulaCell.getNumericCellValue(); - } -} +package com.baeldung.poi.excel.setformula; + +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.io.FileOutputStream; +import java.io.IOException; + +public class ExcelFormula { + public double setFormula(String fileLocation, XSSFWorkbook wb, String formula) throws IOException { + XSSFSheet sheet = wb.getSheetAt(0); + int lastCellNum = sheet.getRow(0).getLastCellNum(); + XSSFCell formulaCell = sheet.getRow(0).createCell(lastCellNum); + formulaCell.setCellFormula(formula); + XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator(); + formulaEvaluator.evaluateFormulaCell(formulaCell); + FileOutputStream fileOut = new FileOutputStream(fileLocation); + wb.write(fileOut); + wb.close(); + fileOut.close(); + return formulaCell.getNumericCellValue(); + } +} diff --git a/apache-poi/src/main/resources/com/baeldung/poi/excel/setformula/SetFormulaTest.xlsx b/apache-poi-2/src/main/resources/com/baeldung/poi/excel/setformula/SetFormulaTest.xlsx similarity index 100% rename from apache-poi/src/main/resources/com/baeldung/poi/excel/setformula/SetFormulaTest.xlsx rename to apache-poi-2/src/main/resources/com/baeldung/poi/excel/setformula/SetFormulaTest.xlsx diff --git a/apache-poi/src/test/java/com/baeldung/poi/excel/setformula/ExcelFormulaUnitTest.java b/apache-poi-2/src/test/java/com/baeldung/poi/excel/setformula/ExcelFormulaUnitTest.java similarity index 85% rename from apache-poi/src/test/java/com/baeldung/poi/excel/setformula/ExcelFormulaUnitTest.java rename to apache-poi-2/src/test/java/com/baeldung/poi/excel/setformula/ExcelFormulaUnitTest.java index fa5baa37fa..7a0f15b3f7 100644 --- a/apache-poi/src/test/java/com/baeldung/poi/excel/setformula/ExcelFormulaUnitTest.java +++ b/apache-poi-2/src/test/java/com/baeldung/poi/excel/setformula/ExcelFormulaUnitTest.java @@ -3,18 +3,19 @@ package com.baeldung.poi.excel.setformula; import org.apache.poi.ss.util.CellReference; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Assert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Paths; +import static org.junit.jupiter.api.Assertions.assertEquals; + class ExcelFormulaUnitTest { - private static String FILE_NAME = "com/baeldung/poi/excel/setformula/SetFormulaTest.xlsx"; + private static final String FILE_NAME = "com/baeldung/poi/excel/setformula/SetFormulaTest.xlsx"; + private String fileLocation; private ExcelFormula excelFormula; @@ -26,7 +27,7 @@ class ExcelFormulaUnitTest { @Test void givenExcelData_whenSetFormula_thenSuccess() throws IOException { - FileInputStream inputStream = new FileInputStream(new File(fileLocation)); + FileInputStream inputStream = new FileInputStream(fileLocation); XSSFWorkbook wb = new XSSFWorkbook(inputStream); XSSFSheet sheet = wb.getSheetAt(0); double resultColumnA = 0; @@ -46,6 +47,6 @@ class ExcelFormulaUnitTest { double resultValue = excelFormula.setFormula(fileLocation, wb, sumFormulaForColumnA + "-" + sumFormulaForColumnB); - Assert.assertEquals(resultColumnA - resultColumnB, resultValue, 0d); + assertEquals(resultColumnA - resultColumnB, resultValue, 0d); } } diff --git a/apache-poi/README.md b/apache-poi/README.md index ed30d9a4f3..9edf69d67c 100644 --- a/apache-poi/README.md +++ b/apache-poi/README.md @@ -8,7 +8,6 @@ This module contains articles about Apache POI. - [Merge Cells in Excel Using Apache POI](https://www.baeldung.com/java-apache-poi-merge-cells) - [Get String Value of Excel Cell with Apache POI](https://www.baeldung.com/java-apache-poi-cell-string-value) - [Read Excel Cell Value Rather Than Formula With Apache POI](https://www.baeldung.com/apache-poi-read-cell-value-formula) -- [Setting Formulas in Excel with Apache POI](https://www.baeldung.com/java-apache-poi-set-formulas) - [Insert a Row in Excel Using Apache POI](https://www.baeldung.com/apache-poi-insert-excel-row) - [Multiline Text in Excel Cell Using Apache POI](https://www.baeldung.com/apache-poi-write-multiline-text) - [Set Background Color of a Cell with Apache POI](https://www.baeldung.com/apache-poi-background-color) diff --git a/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java.orig b/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java.orig deleted file mode 100644 index c058f3abcf..0000000000 --- a/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java.orig +++ /dev/null @@ -1,128 +0,0 @@ -package com.baeldung.poi.excel; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -public class ExcelUtility { -<<<<<<< HEAD - private static final String ENDLINE = System.getProperty("line.separator"); - - public static String readExcel(String filePath) throws IOException { - File file = new File(filePath); - FileInputStream inputStream = null; - StringBuilder toReturn = new StringBuilder(); - try { - inputStream = new FileInputStream(file); - Workbook baeuldungWorkBook = new XSSFWorkbook(inputStream); - for (Sheet sheet : baeuldungWorkBook) { - toReturn.append("--------------------------------------------------------------------") - .append(ENDLINE); - toReturn.append("Worksheet :") - .append(sheet.getSheetName()) - .append(ENDLINE); - toReturn.append("--------------------------------------------------------------------") - .append(ENDLINE); - int firstRow = sheet.getFirstRowNum(); - int lastRow = sheet.getLastRowNum(); - for (int index = firstRow + 1; index <= lastRow; index++) { - Row row = sheet.getRow(index); - toReturn.append("|| "); - for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) { - Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); - printCellValue(cell, toReturn); - } - toReturn.append(" ||") - .append(ENDLINE); - } - } - inputStream.close(); - - } catch (IOException e) { - throw e; - } - return toReturn.toString(); - } - - public static void printCellValue(Cell cell, StringBuilder toReturn) { - CellType cellType = cell.getCellType() - .equals(CellType.FORMULA) ? cell.getCachedFormulaResultType() : cell.getCellType(); - if (cellType.equals(CellType.STRING)) { - toReturn.append(cell.getStringCellValue()) - .append(" | "); - } - if (cellType.equals(CellType.NUMERIC)) { - if (DateUtil.isCellDateFormatted(cell)) { - toReturn.append(cell.getDateCellValue()) - .append(" | "); - } else { - toReturn.append(cell.getNumericCellValue()) - .append(" | "); - } - } - if (cellType.equals(CellType.BOOLEAN)) { - toReturn.append(cell.getBooleanCellValue()) - .append(" | "); - } - } -======= - private static final String ENDLINE = System.getProperty("line.separator"); - - public static String readExcel(String filePath) throws IOException { - File file = new File(filePath); - FileInputStream inputStream = null; - StringBuilder toReturn = new StringBuilder(); - try { - inputStream = new FileInputStream(file); - Workbook baeuldungWorkBook = new XSSFWorkbook(inputStream); - for (Sheet sheet : baeuldungWorkBook) { - toReturn.append("--------------------------------------------------------------------").append(ENDLINE); - toReturn.append("Worksheet :").append(sheet.getSheetName()).append(ENDLINE); - toReturn.append("--------------------------------------------------------------------").append(ENDLINE); - int firstRow = sheet.getFirstRowNum(); - int lastRow = sheet.getLastRowNum(); - for (int index = firstRow + 1; index <= lastRow; index++) { - Row row = sheet.getRow(index); - toReturn.append("|| "); - for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) { - Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); - printCellValue(cell, toReturn); - } - toReturn.append(" ||").append(ENDLINE); - } - } - inputStream.close(); - - } catch (IOException e) { - throw e; - } - return toReturn.toString(); - } - - public static void printCellValue(Cell cell, StringBuilder toReturn) { - CellType cellType = cell.getCellType().equals(CellType.FORMULA) ? cell.getCachedFormulaResultType() - : cell.getCellType(); - if (cellType.equals(CellType.STRING)) { - toReturn.append(cell.getStringCellValue()).append(" | "); - } - if (cellType.equals(CellType.NUMERIC)) { - if (DateUtil.isCellDateFormatted(cell)) { - toReturn.append(cell.getDateCellValue()).append(" | "); - } else { - toReturn.append(cell.getNumericCellValue()).append(" | "); - } - } - if (cellType.equals(CellType.BOOLEAN)) { - toReturn.append(cell.getBooleanCellValue()).append(" | "); - } - } ->>>>>>> master -} \ No newline at end of file diff --git a/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java.orig b/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java.orig deleted file mode 100644 index cfc3062b5a..0000000000 --- a/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java.orig +++ /dev/null @@ -1,112 +0,0 @@ -package com.baeldung.poi.excel; - -import static org.junit.Assert.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.file.Paths; -import java.text.ParseException; -import java.text.SimpleDateFormat; - -import org.junit.Before; -import org.junit.Test; - -public class ExcelUtilityUnitTest { -<<<<<<< HEAD - private static final String FILE_NAME = "baeldung.xlsx"; - private String fileLocation; - private static final String ENDLINE = System.getProperty("line.separator"); - private StringBuilder output; - - @Before - public void setupUnitTest() throws IOException, URISyntaxException, ParseException { - output = new StringBuilder(); - output.append("--------------------------------------------------------------------") - .append(ENDLINE); - output.append("Worksheet :Sheet1") - .append(ENDLINE); - output.append("--------------------------------------------------------------------") - .append(ENDLINE); - output.append("|| Name1 | Surname1 | 3.55696564113E11 | ") - .append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021") - .toString()) - .append(" | ‡ | ||") - .append(ENDLINE); - output.append("|| Name2 | Surname2 | 5.646513512E9 | ") - .append(new SimpleDateFormat("dd/MM/yyyy").parse("4/12/2021") - .toString()) - .append(" | false | ||") - .append(ENDLINE); - output.append("|| Name3 | Surname3 | 3.55696564113E11 | ") - .append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021") - .toString()) - .append(" | 7.17039641738E11 | ||") - .append(ENDLINE); - output.append("--------------------------------------------------------------------") - .append(ENDLINE); - output.append("Worksheet :Sheet2") - .append(ENDLINE); - output.append("--------------------------------------------------------------------") - .append(ENDLINE); - output.append("|| Name4 | Surname4 | 3.55675623232E11 | 13/04/2021 | ||") - .append(ENDLINE); - - fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME) - .toURI()) - .toString(); - } - - @Test - public void givenStringPath_whenReadExcel_thenReturnStringValue() throws IOException { - assertEquals(output.toString(), ExcelUtility.readExcel(fileLocation)); - - } - - @Test - public void givenStringPath_whenReadExcel_thenThrowException() { - assertThrows(IOException.class, () -> { - ExcelUtility.readExcel("baeldung"); - }); - } -======= - private static final String FILE_NAME = "baeldung.xlsx"; - private String fileLocation; - private static final String ENDLINE = System.getProperty("line.separator"); - private StringBuilder output; - - @Before - public void setupUnitTest() throws IOException, URISyntaxException, ParseException { - output = new StringBuilder(); - output.append("--------------------------------------------------------------------").append(ENDLINE); - output.append("Worksheet :Sheet1").append(ENDLINE); - output.append("--------------------------------------------------------------------").append(ENDLINE); - output.append("|| Name1 | Surname1 | 3.55696564113E11 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021").toString()).append(" | ‡ | ||") - .append(ENDLINE); - output.append("|| Name2 | Surname2 | 5.646513512E9 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/12/2021").toString()).append(" | false | ||") - .append(ENDLINE); - output.append("|| Name3 | Surname3 | 3.55696564113E11 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021").toString()).append(" | 7.17039641738E11 | ||") - .append(ENDLINE); - output.append("--------------------------------------------------------------------").append(ENDLINE); - output.append("Worksheet :Sheet2").append(ENDLINE); - output.append("--------------------------------------------------------------------").append(ENDLINE); - output.append("|| Name4 | Surname4 | 3.55675623232E11 | 13/04/2021 | ||").append(ENDLINE); - - fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString(); - } - - @Test - public void givenStringPath_whenReadExcel_thenReturnStringValue() throws IOException { - assertEquals(output.toString(), ExcelUtility.readExcel(fileLocation)); - - } - - @Test - public void givenStringPath_whenReadExcel_thenThrowException() { - assertThrows(IOException.class, () -> { - ExcelUtility.readExcel("baeldung"); - }); - } ->>>>>>> master - -} From a735229a8433bea1ab0f3076b18a774caddfcd92 Mon Sep 17 00:00:00 2001 From: sanitaso Date: Tue, 8 Mar 2022 15:10:36 +0100 Subject: [PATCH 106/249] change the module directory --- .../SwaggerResponseApiApplication.java | 0 .../controller/ProductController.java | 1 - .../swaggerresponseapi/model/Product.java | 28 +++++++ .../service/ProductService.java | 0 .../swaggerResponseAPI/.gitignore | 33 -------- .../swaggerResponseAPI/pom.xml | 70 ----------------- .../swaggerresponseapi/model/Product.java | 15 ---- .../src/main/resources/application.properties | 1 - .../ProductIntegrationTest.java | 76 ------------------- .../SwaggerResponseApiApplicationTests.java | 13 ---- 10 files changed, 28 insertions(+), 209 deletions(-) rename spring-boot-modules/spring-boot-springdoc/{swaggerResponseAPI => }/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java (100%) rename spring-boot-modules/spring-boot-springdoc/{swaggerResponseAPI => }/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java (92%) create mode 100644 spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java rename spring-boot-modules/spring-boot-springdoc/{swaggerResponseAPI => }/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java (100%) delete mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/.gitignore delete mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/pom.xml delete mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java delete mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/resources/application.properties delete mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/ProductIntegrationTest.java delete mode 100644 spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplicationTests.java diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java rename to spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java similarity index 92% rename from spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java rename to spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java index 3e9a3291d9..364a7e8a66 100644 --- a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java +++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java @@ -24,7 +24,6 @@ public class ProductController { this.productService = productService; } - @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Product successfully added!") }) @PostMapping("/create") public Product addProduct(@RequestBody Product product) { return productService.addProducts(product); diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java new file mode 100644 index 0000000000..036ecbc853 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java @@ -0,0 +1,28 @@ +package com.baeldung.swaggerresponseapi.model; + +public class Product { + String code; + String name; + + public Product(String code, String name) { + this.code = code; + this.name = name; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} + diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java similarity index 100% rename from spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java rename to spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/.gitignore b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/.gitignore deleted file mode 100644 index f60f3beecd..0000000000 --- a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -HELP.md -target/ -.mvn/wrapper/ -!**/src/main/**/target/ -!**/src/test/**/target/ -mvnv* - -### 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/ diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/pom.xml b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/pom.xml deleted file mode 100644 index c168248df2..0000000000 --- a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/pom.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.6.3 - - - com.baeldung - swaggerResponseAPI - 0.0.1-SNAPSHOT - swaggerResponseAPI - swaggerResponseAPI - - 11 - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-test - test - - - org.projectlombok - lombok - true - - - org.springdoc - springdoc-openapi-ui - 1.6.6 - - - junit - junit - 4.13.2 - test - - - com.fasterxml.jackson.core - jackson-databind - 2.13.0 - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.projectlombok - lombok - - - - - - - - diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java deleted file mode 100644 index 0a100582fc..0000000000 --- a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.baeldung.swaggerresponseapi.model; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Getter -@Setter -@AllArgsConstructor -@NoArgsConstructor -public class Product { - String code; - String name; -} diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/resources/application.properties b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/resources/application.properties deleted file mode 100644 index 8b13789179..0000000000 --- a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ - diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/ProductIntegrationTest.java b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/ProductIntegrationTest.java deleted file mode 100644 index ef6a8953e2..0000000000 --- a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/ProductIntegrationTest.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.baeldung.swaggerresponseapi; - -import com.baeldung.swaggerresponseapi.controller.ProductController; -import com.baeldung.swaggerresponseapi.model.Product; -import com.baeldung.swaggerresponseapi.service.ProductService; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.result.MockMvcResultMatchers; - -import java.util.Arrays; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.reset; -import static org.hamcrest.CoreMatchers.is; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@RunWith(SpringRunner.class) -@WebMvcTest(ProductController.class) -public class ProductIntegrationTest { - - @Autowired - MockMvc mock; - - @MockBean - private ProductService productService; - - @Test - public void givenProduct_whenAddNewProduct_thenReturnValidStatusCode() throws Exception { - Product product = new Product("1001", "Milk"); - given(productService.addProducts(any(Product.class))).willReturn(product); - - mock.perform(post("/create").contentType(MediaType.APPLICATION_JSON) - .content(toJsonString(product))) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.code").value("1001")); - - reset(productService); - } - - @Test - public void givenProductsList_whenGetAllProducts_thenReturnValidProducts() throws Exception { - Product product1 = new Product("1001", "Milk"); - Product product2 = new Product("2002", "Butter"); - - given(productService.getProductsList()).willReturn(Arrays.asList(product1, product2)); - - mock.perform(get("/products").contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andDo(print()) - .andExpect(jsonPath("$[0].code", is(product1.getCode()))) - .andExpect(jsonPath("$[1].name", is(product2.getName()))); - - reset(productService); - } - - public String toJsonString(Product product) throws JsonProcessingException { - ObjectMapper om = new ObjectMapper(); - String json = om.writeValueAsString(product); - return json; - } -} diff --git a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplicationTests.java b/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplicationTests.java deleted file mode 100644 index 9e8c6ee0fa..0000000000 --- a/spring-boot-modules/spring-boot-springdoc/swaggerResponseAPI/src/test/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.baeldung.swaggerresponseapi; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class SwaggerResponseApiApplicationTests { - - @Test - void contextLoads() { - } - -} From bc543e9c79f33db2a671a2555fede3dd842ebe38 Mon Sep 17 00:00:00 2001 From: sanitaso Date: Tue, 8 Mar 2022 15:13:42 +0100 Subject: [PATCH 107/249] remove dir --- .../SwaggerResponseApiApplication.java | 13 ------- .../controller/ProductController.java | 38 ------------------- .../swaggerresponseapi/model/Product.java | 28 -------------- .../service/ProductService.java | 21 ---------- 4 files changed, 100 deletions(-) delete mode 100644 spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java delete mode 100644 spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java delete mode 100644 spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java delete mode 100644 spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java deleted file mode 100644 index 913544b459..0000000000 --- a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.baeldung.swaggerresponseapi; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class SwaggerResponseApiApplication { - - public static void main(String[] args) { - SpringApplication.run(SwaggerResponseApiApplication.class, args); - } - -} diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java deleted file mode 100644 index 364a7e8a66..0000000000 --- a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.baeldung.swaggerresponseapi.controller; - -import com.baeldung.swaggerresponseapi.model.Product; -import com.baeldung.swaggerresponseapi.service.ProductService; - -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -import java.util.List; - -@RestController -public class ProductController { - private final ProductService productService; - - public ProductController(ProductService productService) { - this.productService = productService; - } - - @PostMapping("/create") - public Product addProduct(@RequestBody Product product) { - return productService.addProducts(product); - } - - @ApiResponses(value = { @ApiResponse(content = { @Content(mediaType = "application/json", - array = @ArraySchema(schema = @Schema(implementation = Product.class))) }) }) - @GetMapping("/products") - public List getProductsList() { - return productService.getProductsList(); - } -} diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java deleted file mode 100644 index 036ecbc853..0000000000 --- a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.baeldung.swaggerresponseapi.model; - -public class Product { - String code; - String name; - - public Product(String code, String name) { - this.code = code; - this.name = name; - } - - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } -} - diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java deleted file mode 100644 index 5e7533d6f4..0000000000 --- a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.swaggerresponseapi.service; - -import com.baeldung.swaggerresponseapi.model.Product; -import org.springframework.stereotype.Service; - -import java.util.ArrayList; -import java.util.List; - -@Service -public class ProductService { - List productsList = new ArrayList<>(); - - public Product addProducts(Product product) { - productsList.add(product); - return product; - } - - public List getProductsList() { - return productsList; - } -} From e3966f2efde01da3696cb110aefaae9c2e75becd Mon Sep 17 00:00:00 2001 From: sanitaso Date: Tue, 8 Mar 2022 15:15:11 +0100 Subject: [PATCH 108/249] add dir --- .../SwaggerResponseApiApplication.java | 13 +++++++ .../controller/ProductController.java | 38 +++++++++++++++++++ .../swaggerresponseapi/model/Product.java | 28 ++++++++++++++ .../service/ProductService.java | 21 ++++++++++ 4 files changed, 100 insertions(+) create mode 100644 spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java create mode 100644 spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java create mode 100644 spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java create mode 100644 spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java new file mode 100644 index 0000000000..913544b459 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/SwaggerResponseApiApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.swaggerresponseapi; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SwaggerResponseApiApplication { + + public static void main(String[] args) { + SpringApplication.run(SwaggerResponseApiApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java new file mode 100644 index 0000000000..364a7e8a66 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/controller/ProductController.java @@ -0,0 +1,38 @@ +package com.baeldung.swaggerresponseapi.controller; + +import com.baeldung.swaggerresponseapi.model.Product; +import com.baeldung.swaggerresponseapi.service.ProductService; + +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +public class ProductController { + private final ProductService productService; + + public ProductController(ProductService productService) { + this.productService = productService; + } + + @PostMapping("/create") + public Product addProduct(@RequestBody Product product) { + return productService.addProducts(product); + } + + @ApiResponses(value = { @ApiResponse(content = { @Content(mediaType = "application/json", + array = @ArraySchema(schema = @Schema(implementation = Product.class))) }) }) + @GetMapping("/products") + public List getProductsList() { + return productService.getProductsList(); + } +} diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java new file mode 100644 index 0000000000..036ecbc853 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/model/Product.java @@ -0,0 +1,28 @@ +package com.baeldung.swaggerresponseapi.model; + +public class Product { + String code; + String name; + + public Product(String code, String name) { + this.code = code; + this.name = name; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} + diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java new file mode 100644 index 0000000000..5e7533d6f4 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/service/ProductService.java @@ -0,0 +1,21 @@ +package com.baeldung.swaggerresponseapi.service; + +import com.baeldung.swaggerresponseapi.model.Product; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class ProductService { + List productsList = new ArrayList<>(); + + public Product addProducts(Product product) { + productsList.add(product); + return product; + } + + public List getProductsList() { + return productsList; + } +} From c1751dc317e3a363611c5a9306a7521cc9b1ad2a Mon Sep 17 00:00:00 2001 From: Kapil Khandelwal Date: Wed, 9 Mar 2022 02:19:19 +0530 Subject: [PATCH 109/249] BAEL-5360: Check Collection Existence in MongoDB (#11905) * BAEL-5360: Check Collection Existence in MongoDB * BAEL-5360: update test names using the bdd scheme --- .../baeldung/mongo/CollectionExistence.java | 100 ++++++++++++++++++ .../mongo/CollectionExistenceLiveTest.java | 98 +++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/CollectionExistence.java create mode 100644 persistence-modules/java-mongodb/src/test/java/com/baeldung/mongo/CollectionExistenceLiveTest.java diff --git a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/CollectionExistence.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/CollectionExistence.java new file mode 100644 index 0000000000..074913af4e --- /dev/null +++ b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/CollectionExistence.java @@ -0,0 +1,100 @@ +package com.baeldung.mongo; + +import java.util.ArrayList; + +import org.bson.Document; + +import com.mongodb.DB; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; + +public class CollectionExistence { + + private static MongoClient mongoClient; + + private static String testCollectionName; + private static String databaseName; + + public static void setUp() { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + } + databaseName = "baeldung"; + testCollectionName = "student"; + } + + public static void collectionExistsSolution() { + + DB db = mongoClient.getDB(databaseName); + + System.out.println("collectionName " + testCollectionName + db.collectionExists(testCollectionName)); + + } + + public static void createCollectionSolution() { + + MongoDatabase database = mongoClient.getDatabase(databaseName); + + try { + database.createCollection(testCollectionName); + + } catch (Exception exception) { + System.err.println("Collection already Exists"); + } + + } + + public static void listCollectionNamesSolution() { + + MongoDatabase database = mongoClient.getDatabase(databaseName); + boolean collectionExists = database.listCollectionNames() + .into(new ArrayList()) + .contains(testCollectionName); + + System.out.println("collectionExists:- " + collectionExists); + + } + + public static void countSolution() { + + MongoDatabase database = mongoClient.getDatabase(databaseName); + + MongoCollection collection = database.getCollection(testCollectionName); + + System.out.println(collection.count()); + + } + + public static void main(String args[]) { + + // + // Connect to cluster (default is localhost:27017) + // + setUp(); + + // + // Check the db existence using DB class's method + // + collectionExistsSolution(); + + // + // Check the db existence using the createCollection method of MongoDatabase class + // + createCollectionSolution(); + + // + // Check the db existence using the listCollectionNames method of MongoDatabase class + // + listCollectionNamesSolution(); + + // + // Check the db existence using the count method of MongoDatabase class + // + countSolution(); + + } + +} + + diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/mongo/CollectionExistenceLiveTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/mongo/CollectionExistenceLiveTest.java new file mode 100644 index 0000000000..ad839d1219 --- /dev/null +++ b/persistence-modules/java-mongodb/src/test/java/com/baeldung/mongo/CollectionExistenceLiveTest.java @@ -0,0 +1,98 @@ +package com.baeldung.mongo; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; + +import org.bson.Document; +import org.junit.Before; +import org.junit.Test; + +import com.mongodb.DB; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; + +public class CollectionExistenceLiveTest { + + private MongoClient mongoClient; + private String testCollectionName; + private String databaseName; + + @Before + public void setup() { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + databaseName = "baeldung"; + testCollectionName = "student"; + + // Create a new collection if it doesn't exists. + try { + MongoDatabase database = mongoClient.getDatabase(databaseName); + database.createCollection(testCollectionName); + + } catch (Exception exception) { + + System.out.println("Collection already Exists"); + } + + } + } + + @Test + public void givenCreateCollection_whenCollectionAlreadyExists_thenCheckingForCollectionExistence() { + + MongoDatabase database = mongoClient.getDatabase(databaseName); + Boolean collectionStatus = false; + Boolean expectedStatus = true; + + try { + database.createCollection(testCollectionName); + + } catch (Exception exception) { + collectionStatus = true; + System.err.println("Collection already Exists"); + } + + assertEquals(expectedStatus, collectionStatus); + + } + + @Test + public void givenCollectionExists_whenCollectionAlreadyExists_thenCheckingForCollectionExistence() { + + DB db = mongoClient.getDB(databaseName); + Boolean collectionStatus = db.collectionExists(testCollectionName); + + Boolean expectedStatus = true; + assertEquals(expectedStatus, collectionStatus); + + } + + @Test + public void givenListCollectionNames_whenCollectionAlreadyExists_thenCheckingForCollectionExistence() { + + MongoDatabase database = mongoClient.getDatabase(databaseName); + boolean collectionExists = database.listCollectionNames() + .into(new ArrayList()) + .contains(testCollectionName); + + Boolean expectedStatus = true; + assertEquals(expectedStatus, collectionExists); + + } + + @Test + public void givenCount_whenCollectionAlreadyExists_thenCheckingForCollectionExistence() { + + MongoDatabase database = mongoClient.getDatabase(databaseName); + + MongoCollection collection = database.getCollection(testCollectionName); + Boolean collectionExists = collection.count() > 0 ? true : false; + + Boolean expectedStatus = false; + assertEquals(expectedStatus, collectionExists); + + } +} + From c1d1134fb362fa4d61939a0834e48e92cf7db19c Mon Sep 17 00:00:00 2001 From: ACHRAF TAITAI <43656331+achraftt@users.noreply.github.com> Date: Tue, 8 Mar 2022 21:52:10 +0100 Subject: [PATCH 110/249] BAEL-4569: Formatting Email Text (#11910) --- .../src/main/java/com/baeldung/mail/EmailService.java | 5 +++++ .../java/com/baeldung/mail/EmailServiceLiveTest.java | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/EmailService.java b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/EmailService.java index 3d1e25e7a4..3e40cf53f7 100644 --- a/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/EmailService.java +++ b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/EmailService.java @@ -67,12 +67,17 @@ public class EmailService { MimeBodyPart mimeBodyPart = new MimeBodyPart(); mimeBodyPart.setContent(msg, "text/html; charset=utf-8"); + String msgStyled = "This is my bold-red email using JavaMailer"; + MimeBodyPart mimeBodyPartWithStyledText = new MimeBodyPart(); + mimeBodyPartWithStyledText.setContent(msgStyled, "text/html; charset=utf-8"); + MimeBodyPart attachmentBodyPart = new MimeBodyPart(); attachmentBodyPart.attachFile(getFile()); Multipart multipart = new MimeMultipart(); multipart.addBodyPart(mimeBodyPart); + multipart.addBodyPart(mimeBodyPartWithStyledText); multipart.addBodyPart(attachmentBodyPart); message.setContent(multipart); diff --git a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/EmailServiceLiveTest.java b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/EmailServiceLiveTest.java index 7f543bc612..cec4cfcb55 100644 --- a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/EmailServiceLiveTest.java +++ b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/EmailServiceLiveTest.java @@ -36,6 +36,7 @@ public class EmailServiceLiveTest { MimeMessage receivedMessage = receivedMessages[0]; assertEquals("Mail Subject", subjectFromMessage(receivedMessage)); assertEquals("This is my first email using JavaMailer", emailTextFrom(receivedMessage)); + assertEquals("This is my bold-red email using JavaMailer", emailStyledTextFrom(receivedMessage)); assertEquals("sample attachment content", attachmentContentsFrom(receivedMessage)); } @@ -50,9 +51,16 @@ public class EmailServiceLiveTest { .toString(); } + private static String emailStyledTextFrom(MimeMessage receivedMessage) throws IOException, MessagingException { + return ((MimeMultipart) receivedMessage.getContent()) + .getBodyPart(1) + .getContent() + .toString(); + } + private static String attachmentContentsFrom(MimeMessage receivedMessage) throws Exception { return ((MimeMultipart) receivedMessage.getContent()) - .getBodyPart(1) + .getBodyPart(2) .getContent() .toString(); } From 410ccd500b20498c73f384a4569ea92c10dba85d Mon Sep 17 00:00:00 2001 From: kwoyke Date: Wed, 9 Mar 2022 18:08:22 +0100 Subject: [PATCH 111/249] JAVA-10399: Fix assertion to include start date (#11893) --- .../src/test/java/com/baeldung/random/RandomDatesUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/random/RandomDatesUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/random/RandomDatesUnitTest.java index 6005cf93c2..68b4fd4938 100644 --- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/random/RandomDatesUnitTest.java +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/random/RandomDatesUnitTest.java @@ -22,6 +22,6 @@ class RandomDatesUnitTest { LocalDate end = LocalDate.now(); LocalDate random = RandomDates.between(start, end); - assertThat(random).isAfter(start).isBefore(end); + assertThat(random).isAfterOrEqualTo(start).isBefore(end); } } From f0f014b99cce3f6e144f832f7e9edd66e0556402 Mon Sep 17 00:00:00 2001 From: Bhaskara Date: Thu, 10 Mar 2022 03:31:39 +0530 Subject: [PATCH 112/249] Added code for BAEL-1355 (#11908) * Added code for BAEL-1355 * Formatted the code * Added jakarta-ee to parent pom Co-authored-by: Bhaskara Navuluri --- jakarta-ee/pom.xml | 111 +++++++++++++++++ .../java/com/baeldung/eclipse/krazo/User.java | 84 +++++++++++++ .../eclipse/krazo/UserApplication.java | 11 ++ .../eclipse/krazo/UserController.java | 85 +++++++++++++ jakarta-ee/src/main/webapp/WEB-INF/beans.xml | 6 + .../src/main/webapp/WEB-INF/views/success.jsp | 47 +++++++ .../src/main/webapp/WEB-INF/views/user.jsp | 89 ++++++++++++++ jakarta-ee/src/main/webapp/styles.css | 28 +++++ .../com/baeldung/eclipse/krazo/AppTest.java | 16 +++ .../eclipse/krazo/UserControllerUnitTest.java | 116 ++++++++++++++++++ pom.xml | 86 ++++++------- 11 files changed, 637 insertions(+), 42 deletions(-) create mode 100644 jakarta-ee/pom.xml create mode 100644 jakarta-ee/src/main/java/com/baeldung/eclipse/krazo/User.java create mode 100644 jakarta-ee/src/main/java/com/baeldung/eclipse/krazo/UserApplication.java create mode 100644 jakarta-ee/src/main/java/com/baeldung/eclipse/krazo/UserController.java create mode 100644 jakarta-ee/src/main/webapp/WEB-INF/beans.xml create mode 100644 jakarta-ee/src/main/webapp/WEB-INF/views/success.jsp create mode 100644 jakarta-ee/src/main/webapp/WEB-INF/views/user.jsp create mode 100644 jakarta-ee/src/main/webapp/styles.css create mode 100644 jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/AppTest.java create mode 100644 jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java diff --git a/jakarta-ee/pom.xml b/jakarta-ee/pom.xml new file mode 100644 index 0000000000..074ca1eec8 --- /dev/null +++ b/jakarta-ee/pom.xml @@ -0,0 +1,111 @@ + + 4.0.0 + + com.baeldung + mvc-2.0 + 1.0-SNAPSHOT + war + + mvc-2.0 + + + 9.0.0 + 2.0.0 + 2.0.0 + 5.8.2 + C:/glassfish6 + admin + mvn-domain + 1.10.19 + + ${local.glassfish.home}\\domains\\${local.glassfish.domain}\\config\\domain-passwords + + + + + + jakarta.platform + jakarta.jakartaee-web-api + ${jakartaee-api.version} + provided + + + + jakarta.mvc + jakarta.mvc-api + ${jakarta.mvc-api.version} + + + + org.eclipse.krazo + krazo-jersey + ${krazo.version} + + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.version} + test + + + org.mockito + mockito-all + ${mockito.version} + test + + + + + + mvc-2.0 + + + org.glassfish.maven.plugin + maven-glassfish-plugin + 2.1 + + ${local.glassfish.home} + admin + + password + + + ${local.glassfish.domain} + 8080 + 4848 + + + + + ${project.artifactId} + target/${project.build.finalName}.war + + + + true + false + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-war-plugin + + false + + + + + diff --git a/jakarta-ee/src/main/java/com/baeldung/eclipse/krazo/User.java b/jakarta-ee/src/main/java/com/baeldung/eclipse/krazo/User.java new file mode 100644 index 0000000000..a2253b6aa6 --- /dev/null +++ b/jakarta-ee/src/main/java/com/baeldung/eclipse/krazo/User.java @@ -0,0 +1,84 @@ +package com.baeldung.eclipse.krazo; + +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Named; +import jakarta.mvc.RedirectScoped; +import jakarta.mvc.binding.MvcBinding; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Null; +import jakarta.validation.constraints.Size; +import jakarta.ws.rs.FormParam; + +import java.io.Serializable; + +@Named("user") +@RedirectScoped +public class User implements Serializable { + @MvcBinding + @Null + private String id; + + @MvcBinding + @NotNull + @Size(min = 1, message = "Name cannot be blank") + @FormParam("name") + private String name; + + @MvcBinding + @Min(value = 18, message = "The minimum age of the user should be 18 years") + @FormParam("age") + private int age; + + @MvcBinding + @Email(message = "The email cannot be blank and should be in a valid format") + @Size(min=3, message = "Email cannot be empty") + @FormParam("email") + private String email; + + @MvcBinding + @Null + @FormParam("phone") + private String phone; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } +} diff --git a/jakarta-ee/src/main/java/com/baeldung/eclipse/krazo/UserApplication.java b/jakarta-ee/src/main/java/com/baeldung/eclipse/krazo/UserApplication.java new file mode 100644 index 0000000000..5a272806cb --- /dev/null +++ b/jakarta-ee/src/main/java/com/baeldung/eclipse/krazo/UserApplication.java @@ -0,0 +1,11 @@ +package com.baeldung.eclipse.krazo; + +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.core.Application; + +/** + * Default JAX-RS application listening on /app + */ +@ApplicationPath("/app") +public class UserApplication extends Application { +} diff --git a/jakarta-ee/src/main/java/com/baeldung/eclipse/krazo/UserController.java b/jakarta-ee/src/main/java/com/baeldung/eclipse/krazo/UserController.java new file mode 100644 index 0000000000..92ddf73571 --- /dev/null +++ b/jakarta-ee/src/main/java/com/baeldung/eclipse/krazo/UserController.java @@ -0,0 +1,85 @@ +package com.baeldung.eclipse.krazo; + +import jakarta.inject.Inject; +import jakarta.mvc.Controller; +import jakarta.mvc.Models; +import jakarta.mvc.binding.BindingResult; +import jakarta.mvc.security.CsrfProtected; +import jakarta.validation.Valid; +import jakarta.ws.rs.BeanParam; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * The class contains two controllers and a REST API + */ +@Path("users") +public class UserController { + @Inject + private BindingResult bindingResult; + + private static final List users = new ArrayList<>(); + + @Inject + private Models models; + + /** + * This is a controller. It displays a initial form to the user. + * @return The view name + */ + @GET + @Controller + public String showForm() { + return "user.jsp"; + } + + /** + * The method handles the form submits + * Handles HTTP POST and is CSRF protected. The client invoking this controller should provide a CSRF token. + * @param user The user details that has to be stored + * @return Returns a view name + */ + @POST + @Controller + @CsrfProtected + public String saveUser(@Valid @BeanParam User user) { + if (bindingResult.isFailed()) { + models.put("errors", bindingResult.getAllErrors()); + return "user.jsp"; + } + String id = UUID.randomUUID().toString(); + user.setId(id); + users.add(user); + return "redirect:users/success"; + } + + /** + * Handles a redirect view + * @return The view name + */ + @GET + @Controller + @Path("success") + public String saveUserSuccess() { + return "success.jsp"; + } + + /** + * The REST API that returns all the user details in the JSON format + * @return The list of users that are saved. The List is converted into Json Array. + * If no user is present a empty array is returned + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public List getUsers() { + return users; + } + +} diff --git a/jakarta-ee/src/main/webapp/WEB-INF/beans.xml b/jakarta-ee/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000000..d068fbd3e4 --- /dev/null +++ b/jakarta-ee/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,6 @@ + + + diff --git a/jakarta-ee/src/main/webapp/WEB-INF/views/success.jsp b/jakarta-ee/src/main/webapp/WEB-INF/views/success.jsp new file mode 100644 index 0000000000..19d45e46ba --- /dev/null +++ b/jakarta-ee/src/main/webapp/WEB-INF/views/success.jsp @@ -0,0 +1,47 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + MVC 2.0 + + + + + + + + + + +
+
+
+
+ +
+

User created successfully!

+
+
+ +
+ +
+
+ + + + + + \ No newline at end of file diff --git a/jakarta-ee/src/main/webapp/WEB-INF/views/user.jsp b/jakarta-ee/src/main/webapp/WEB-INF/views/user.jsp new file mode 100644 index 0000000000..a36655950d --- /dev/null +++ b/jakarta-ee/src/main/webapp/WEB-INF/views/user.jsp @@ -0,0 +1,89 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + MVC 2.0 + + + + + + + + + + +
+
+
+

+ User Details +

+
+ + + +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+
+ + +
+ +
+ +
+
+ + + + + + \ No newline at end of file diff --git a/jakarta-ee/src/main/webapp/styles.css b/jakarta-ee/src/main/webapp/styles.css new file mode 100644 index 0000000000..9cc9e62f12 --- /dev/null +++ b/jakarta-ee/src/main/webapp/styles.css @@ -0,0 +1,28 @@ +body, html { + font-family: Raleway, serif; + font-weight: 300; +} + +.bg-dark { + background-color: #63b175 !important; + font-weight: 600 !important; +} + +body { + padding-top: 80px; +} + +@media (max-width: 979px) { + body { + padding-top: 0; + } +} + +label { + font-weight: bold; +} + +.hr-dark { + border-top: 2px solid #000; + margin-bottom: 20px; +} \ No newline at end of file diff --git a/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/AppTest.java b/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/AppTest.java new file mode 100644 index 0000000000..6934d1fca2 --- /dev/null +++ b/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/AppTest.java @@ -0,0 +1,16 @@ +package com.baeldung.eclipse.krazo; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Dummy Test + */ +public class AppTest { + + @Test + public void test() { + assertTrue(true); + } +} diff --git a/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java b/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java new file mode 100644 index 0000000000..5e79924ed7 --- /dev/null +++ b/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java @@ -0,0 +1,116 @@ +package com.baeldung.eclipse.krazo; + +import com.baeldung.eclipse.krazo.User; +import com.baeldung.eclipse.krazo.UserController; +import jakarta.mvc.Models; +import jakarta.mvc.binding.BindingResult; +import org.eclipse.krazo.core.ModelsImpl; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.when; + +/** + * The class contains unit tests. We do only unit tests. Most of the classes are mocked + */ +@DisplayName("Eclipse Krazo MVC 2.0 Test Suite") +class UserControllerUnitTest { + + @InjectMocks + UserController userController = new UserController(); + + @Mock + Models models; + + @Mock + BindingResult bindingResult; + + @BeforeEach + public void setUpClass() { + MockitoAnnotations.initMocks(this); + } + + @Test + @DisplayName("Test Show Form") + void whenShowForm_thenReturnViewName() { + assertNotNull(userController.showForm()); + assertEquals("user.jsp", userController.showForm()); + } + + @Test + @DisplayName("Test Save User Success") + void whenSaveUser_thenReturnSuccess() { + when(bindingResult.isFailed()).thenReturn(false); + + User user = new User(); + + assertNotNull(userController.saveUser(user)); + assertDoesNotThrow(() -> userController.saveUser(user)); + assertEquals("redirect:users/success", userController.saveUser(user)); + } + + @Test + @DisplayName("Test Save User Binding Errors") + void whenSaveUser_thenReturnError() { + when(bindingResult.isFailed()).thenReturn(true); + Models testModels = new ModelsImpl(); + when(models.put(anyString(), any())).thenReturn(testModels); + User user = getUser(); + assertNotNull(userController.saveUser(user)); + assertDoesNotThrow(() -> userController.saveUser(user)); + assertEquals("user.jsp", userController.saveUser(user)); + } + + @Test + @DisplayName("Test Save User Success View") + void whenSaveUserSuccess_thenRedirectSuccess() { + assertNotNull(userController.saveUserSuccess()); + assertDoesNotThrow(() -> userController.saveUserSuccess()); + assertEquals("success.jsp", userController.saveUserSuccess()); + } + + @Test + @DisplayName("Test Get Users API") + void whenGetUser_thenReturnUsers() { + when(bindingResult.isFailed()).thenReturn(false); + + User user= getUser(); + + assertNotNull(user); + assertEquals(30, user.getAge()); + assertEquals("john doe", user.getName()); + assertEquals("anymail", user.getEmail()); + assertEquals("99887766554433", user.getPhone()); + assertEquals("1", user.getId()); + + userController.saveUser(user); + userController.saveUser(user); + userController.saveUser(user); + + assertNotNull(userController.getUsers()); + assertDoesNotThrow(() -> userController.getUsers()); + assertEquals(3, userController.getUsers().size()); + + } + + private User getUser() { + User user = new User(); + user.setId("1"); + user.setName("john doe"); + user.setAge(30); + user.setEmail("anymail"); + user.setPhone("99887766554433"); + return user; + } + +} diff --git a/pom.xml b/pom.xml index 197e946974..b6767c629b 100644 --- a/pom.xml +++ b/pom.xml @@ -462,6 +462,7 @@ jaxb jee-7 jee-7-security + jakarta-ee jersey jgit jgroups @@ -555,9 +556,9 @@ rxjava-observables rxjava-operators - atomikos - reactive-systems - slack + atomikos + reactive-systems + slack @@ -945,6 +946,7 @@ jaxb jee-7 jee-7-security + jakarta-ee jersey jgit jgroups @@ -1038,9 +1040,9 @@ rxjava-observables rxjava-operators - atomikos - reactive-systems - slack + atomikos + reactive-systems + slack @@ -1311,43 +1313,43 @@
- core-java-modules/core-java-9 - core-java-modules/core-java-9-improvements - core-java-modules/core-java-9-jigsaw + core-java-modules/core-java-9 + core-java-modules/core-java-9-improvements + core-java-modules/core-java-9-jigsaw - core-java-modules/core-java-9-streams - core-java-modules/core-java-10 - core-java-modules/core-java-11 - core-java-modules/core-java-11-2 - - - - - core-java-modules/core-java-collections-set - core-java-modules/core-java-collections-maps-4 - core-java-modules/core-java-date-operations-1 - core-java-modules/core-java-datetime-conversion - core-java-modules/core-java-datetime-string - core-java-modules/core-java-io-conversions-2 - core-java-modules/core-java-jpms - core-java-modules/core-java-os - core-java-modules/core-java-string-algorithms-3 - core-java-modules/core-java-string-operations-3 - core-java-modules/core-java-string-operations-4 - core-java-modules/core-java-time-measurements - core-java-modules/core-java-networking-3 - core-java-modules/multimodulemavenproject - ddd-modules - httpclient-2 - libraries-concurrency - persistence-modules/sirix - persistence-modules/spring-data-cassandra-2 - quarkus-vs-springboot - quarkus-jandex - spring-boot-modules/spring-boot-cassandre - spring-boot-modules/spring-boot-camel - testing-modules/testing-assertions - persistence-modules/fauna + core-java-modules/core-java-9-streams + core-java-modules/core-java-10 + core-java-modules/core-java-11 + core-java-modules/core-java-11-2 + + + + + core-java-modules/core-java-collections-set + core-java-modules/core-java-collections-maps-4 + core-java-modules/core-java-date-operations-1 + core-java-modules/core-java-datetime-conversion + core-java-modules/core-java-datetime-string + core-java-modules/core-java-io-conversions-2 + core-java-modules/core-java-jpms + core-java-modules/core-java-os + core-java-modules/core-java-string-algorithms-3 + core-java-modules/core-java-string-operations-3 + core-java-modules/core-java-string-operations-4 + core-java-modules/core-java-time-measurements + core-java-modules/core-java-networking-3 + core-java-modules/multimodulemavenproject + ddd-modules + httpclient-2 + libraries-concurrency + persistence-modules/sirix + persistence-modules/spring-data-cassandra-2 + quarkus-vs-springboot + quarkus-jandex + spring-boot-modules/spring-boot-cassandre + spring-boot-modules/spring-boot-camel + testing-modules/testing-assertions + persistence-modules/fauna From fbb90aa41a6524acfd1d5f9ab526200a3f948f11 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Thu, 10 Mar 2022 16:27:42 +0530 Subject: [PATCH 113/249] JAVA-10379 Work done on feedback --- .../HibernateManyToManyAnnotationMainIntegrationTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java index 71051c821c..5255cb040f 100644 --- a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java +++ b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java @@ -52,9 +52,11 @@ public class HibernateManyToManyAnnotationMainIntegrationTest { for(Employee employee : employeeList) { assertNotNull(employee.getProjects()); + assertEquals(2, employee.getProjects().size()); } for(Project project : projectList) { assertNotNull(project.getEmployees()); + assertEquals(2, project.getEmployees().size()); } } @@ -70,6 +72,11 @@ public class HibernateManyToManyAnnotationMainIntegrationTest { for (String emp : employeeData) { Employee employee = new Employee(emp.split(" ")[0], emp.split(" ")[1]); employee.setProjects(projects); + + for (Project proj : projects) { + proj.getEmployees().add(employee); + } + session.persist(employee); } } From 227afb71cf18ce3e78a5d6a5ae2a7c233b322b0b Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Thu, 10 Mar 2022 15:08:46 +0100 Subject: [PATCH 114/249] JAVA-10271: Fix circular dependency issue --- .../java/com/baeldung/keycloak/KeycloakConfig.java | 14 ++++++++++++++ .../java/com/baeldung/keycloak/SecurityConfig.java | 5 ----- 2 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/KeycloakConfig.java diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/KeycloakConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/KeycloakConfig.java new file mode 100644 index 0000000000..6a3dc45717 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/KeycloakConfig.java @@ -0,0 +1,14 @@ +package com.baeldung.keycloak; + +import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class KeycloakConfig { + + @Bean + public KeycloakSpringBootConfigResolver keycloakConfigResolver() { + return new KeycloakSpringBootConfigResolver(); + } +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java index 78023aff8f..826f475a6e 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java @@ -23,11 +23,6 @@ class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { auth.authenticationProvider(keycloakAuthenticationProvider); } - @Bean - public KeycloakSpringBootConfigResolver KeycloakConfigResolver() { - return new KeycloakSpringBootConfigResolver(); - } - // Specifies the session authentication strategy @Bean @Override From fee01d60fbd97dd80cc1ada797ff6e0fb8c11f28 Mon Sep 17 00:00:00 2001 From: Kapil Khandelwal Date: Fri, 11 Mar 2022 00:20:08 +0530 Subject: [PATCH 115/249] BAEL-5374: push Into Array in MongoDB (#11916) --- .../com/baeldung/mongo/PushOperations.java | 99 +++++++++++++++++++ .../baeldung/mongo/PushOperationLiveTest.java | 92 +++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/PushOperations.java create mode 100644 persistence-modules/java-mongodb/src/test/java/com/baeldung/mongo/PushOperationLiveTest.java diff --git a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/PushOperations.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/PushOperations.java new file mode 100644 index 0000000000..fa1f9ddc96 --- /dev/null +++ b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/PushOperations.java @@ -0,0 +1,99 @@ +package com.baeldung.mongo; + +import java.io.FileNotFoundException; +import java.io.IOException; + +import org.bson.Document; + +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Updates; +import com.mongodb.client.result.UpdateResult; + +public class PushOperations { + + private static MongoClient mongoClient; + private static String testCollectionName; + private static String databaseName; + + public static void setUp() { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + } + + databaseName = "baeldung"; + testCollectionName = "orders"; + + } + + public static void pushOperationUsingDBObject() { + + MongoDatabase database = mongoClient.getDatabase(databaseName); + MongoCollection collection = database.getCollection(testCollectionName); + DBObject listItem = new BasicDBObject("items", new BasicDBObject("itemName", "PIZZA MANIA").append("quantity", 1) + .append("price", 800)); + BasicDBObject searchFilter = new BasicDBObject("customerId", 1023); + BasicDBObject updateQuery = new BasicDBObject(); + updateQuery.append("$push", listItem); + UpdateResult updateResult = collection.updateOne(searchFilter, updateQuery); + + System.out.println("updateResult:- " + updateResult); + } + + public static void pushOperationUsingDocument() { + + MongoDatabase database = mongoClient.getDatabase(databaseName); + MongoCollection collection = database.getCollection(testCollectionName); + + Document item = new Document().append("itemName", "PIZZA MANIA") + .append("quantity", 1) + .append("price", 800); + UpdateResult updateResult = collection.updateOne(Filters.eq("customerId", 1023), Updates.push("items", item)); + + System.out.println("updateResult:- " + updateResult); + } + + public static void addToSetOperation() { + + MongoDatabase database = mongoClient.getDatabase(databaseName); + MongoCollection collection = database.getCollection(testCollectionName); + + Document item = new Document().append("itemName", "PIZZA MANIA") + .append("quantity", 1) + .append("price", 800); + UpdateResult updateResult = collection.updateOne(Filters.eq("customerId", 1023), Updates.addToSet("items", item)); + System.out.println("updateResult:- " + updateResult); + } + + public static void main(String args[]) { + + // + // Connect to cluster (default is localhost:27017) + // + setUp(); + + // + // Push document into the array using DBObject + // + + pushOperationUsingDBObject(); + + // + // Push document into the array using Document. + // + + pushOperationUsingDocument(); + + // + // Push document into the array using addToSet operator. + // + addToSetOperation(); + + } + +} + diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/mongo/PushOperationLiveTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/mongo/PushOperationLiveTest.java new file mode 100644 index 0000000000..bd8523b301 --- /dev/null +++ b/persistence-modules/java-mongodb/src/test/java/com/baeldung/mongo/PushOperationLiveTest.java @@ -0,0 +1,92 @@ +package com.baeldung.mongo; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import org.bson.Document; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Updates; +import com.mongodb.client.result.UpdateResult; + +public class PushOperationLiveTest { + + private static MongoClient mongoClient; + private static MongoDatabase db; + private static MongoCollection collection; + + @BeforeClass + public static void setup() { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + db = mongoClient.getDatabase("baeldung"); + collection = db.getCollection("orders"); + + collection.insertOne( + Document.parse("{\n" + " \"customerId\": 1023,\n" + " \"orderTimestamp\": NumberLong(\"1646460073000\"),\n" + " \"shippingDestination\": \"336, Street No.1 Pawai Mumbai\",\n" + " \"purchaseOrder\": 1000,\n" + + " \"contactNumber\":\"9898987676\",\n" + " \"items\": [ \n" + " {\n" + " \"itemName\": \"BERGER\",\n" + " \"quantity\": 1,\n" + " \"price\": 500\n" + " },\n" + + " {\n" + " \"itemName\": \"VEG PIZZA\",\n" + " \"quantity\": 1,\n" + " \"price\": 800\n" + " } \n" + " ]\n" + " }")); + } + } + + @Test + public void givenOrderCollection_whenPushOperationUsingDBObject_thenCheckingForDocument() { + + DBObject listItem = new BasicDBObject("items", new BasicDBObject("itemName", "PIZZA MANIA").append("quantity", 1) + .append("price", 800)); + BasicDBObject searchFilter = new BasicDBObject("customerId", 1023); + BasicDBObject updateQuery = new BasicDBObject(); + updateQuery.append("$push", listItem); + UpdateResult updateResult = collection.updateOne(searchFilter, updateQuery); + + Document orderDetail = collection.find(Filters.eq("customerId", 1023)) + .first(); + assertNotNull(orderDetail); + assertFalse(orderDetail.isEmpty()); + + } + + @Test + public void givenOrderCollection_whenPushOperationUsingDocument_thenCheckingForDocument() { + + Document item = new Document().append("itemName", "PIZZA MANIA") + .append("quantity", 1) + .append("price", 800); + UpdateResult updateResult = collection.updateOne(Filters.eq("customerId", 1023), Updates.push("items", item)); + + Document orderDetail = collection.find(Filters.eq("customerId", 1023)) + .first(); + assertNotNull(orderDetail); + assertFalse(orderDetail.isEmpty()); + + } + + @Test + public void givenOrderCollection_whenAddToSetOperation_thenCheckingForDocument() { + + Document item = new Document().append("itemName", "PIZZA MANIA") + .append("quantity", 1) + .append("price", 800); + UpdateResult updateResult = collection.updateOne(Filters.eq("customerId", 1023), Updates.addToSet("items", item)); + + Document orderDetail = collection.find(Filters.eq("customerId", 1023)) + .first(); + assertNotNull(orderDetail); + assertFalse(orderDetail.isEmpty()); + } + + @AfterClass + public static void cleanUp() { + mongoClient.close(); + } + +} + From c6bd572edaa27d9878a5eb7a7c5c3a6448ada31c Mon Sep 17 00:00:00 2001 From: thibaultfaure Date: Thu, 10 Mar 2022 23:34:39 -0300 Subject: [PATCH 116/249] BAEL-4524 Acquire a Lock By Key in Java (#11872) --- .../com/baeldung/lockbykey/ExampleUsage.java | 43 ++++++ .../com/baeldung/lockbykey/LockByKey.java | 41 +++++ .../lockbykey/SimpleExclusiveLockByKey.java | 18 +++ .../SimultaneousEntriesLockByKey.java | 25 +++ .../baeldung/lockbykey/LockByKeyUnitTest.java | 106 +++++++++++++ .../SimpleExclusiveLockByKeyUnitTest.java | 51 ++++++ .../SimultaneousEntriesLockByKeyUnitTest.java | 146 ++++++++++++++++++ 7 files changed, 430 insertions(+) create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/ExampleUsage.java create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/LockByKey.java create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/SimpleExclusiveLockByKey.java create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/SimultaneousEntriesLockByKey.java create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/lockbykey/LockByKeyUnitTest.java create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/lockbykey/SimpleExclusiveLockByKeyUnitTest.java create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/lockbykey/SimultaneousEntriesLockByKeyUnitTest.java diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/ExampleUsage.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/ExampleUsage.java new file mode 100644 index 0000000000..23cfb8455a --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/ExampleUsage.java @@ -0,0 +1,43 @@ +package com.baeldung.lockbykey; + +/** + * This class shows examples of how you should use the lock + * + */ +public class ExampleUsage { + + void doWithSimpleExclusiveLock(String key) { + SimpleExclusiveLockByKey simpleExclusiveLockByKey = new SimpleExclusiveLockByKey(); + if (simpleExclusiveLockByKey.tryLock(key)) { + try { + // do stuff + } finally { + // it is very important to unlock in the finally block to avoid locking keys forever + simpleExclusiveLockByKey.unlock(key); + } + } + } + + // A concrete example can be found in the unit tests + void doWithLock(String key) { + LockByKey lockByKey = new LockByKey(); + lockByKey.lock(key); + try { + // do stuff + } finally { + lockByKey.unlock(key); + } + } + + // It works exactly the same as with locks + void doWithSemaphore(String key) { + SimultaneousEntriesLockByKey lockByKey = new SimultaneousEntriesLockByKey(); + lockByKey.lock(key); + try { + // do stuff + } finally { + lockByKey.unlock(key); + } + } + +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/LockByKey.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/LockByKey.java new file mode 100644 index 0000000000..f81aa6779e --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/LockByKey.java @@ -0,0 +1,41 @@ +package com.baeldung.lockbykey; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class LockByKey { + + private static class LockWrapper { + private final Lock lock = new ReentrantLock(); + private final AtomicInteger numberOfThreadsInQueue = new AtomicInteger(1); + + private LockWrapper addThreadInQueue() { + numberOfThreadsInQueue.incrementAndGet(); + return this; + } + + private int removeThreadFromQueue() { + return numberOfThreadsInQueue.decrementAndGet(); + } + + } + + private static ConcurrentHashMap locks = new ConcurrentHashMap(); + + public void lock(String key) { + LockWrapper lockWrapper = locks.compute(key, (k, v) -> v == null ? new LockWrapper() : v.addThreadInQueue()); + lockWrapper.lock.lock(); + } + + public void unlock(String key) { + LockWrapper lockWrapper = locks.get(key); + lockWrapper.lock.unlock(); + if (lockWrapper.removeThreadFromQueue() == 0) { + // NB : We pass in the specific value to remove to handle the case where another thread would queue right before the removal + locks.remove(key, lockWrapper); + } + } + +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/SimpleExclusiveLockByKey.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/SimpleExclusiveLockByKey.java new file mode 100644 index 0000000000..9182f9c038 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/SimpleExclusiveLockByKey.java @@ -0,0 +1,18 @@ +package com.baeldung.lockbykey; + +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public class SimpleExclusiveLockByKey { + + private static Set usedKeys= ConcurrentHashMap.newKeySet(); + + public boolean tryLock(String key) { + return usedKeys.add(key); + } + + public void unlock(String key) { + usedKeys.remove(key); + } + +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/SimultaneousEntriesLockByKey.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/SimultaneousEntriesLockByKey.java new file mode 100644 index 0000000000..9532f973fa --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/lockbykey/SimultaneousEntriesLockByKey.java @@ -0,0 +1,25 @@ +package com.baeldung.lockbykey; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Semaphore; + +public class SimultaneousEntriesLockByKey { + + private static final int ALLOWED_THREADS = 2; + + private static ConcurrentHashMap semaphores = new ConcurrentHashMap(); + + public void lock(String key) { + Semaphore semaphore = semaphores.compute(key, (k, v) -> v == null ? new Semaphore(ALLOWED_THREADS) : v); + semaphore.acquireUninterruptibly(); + } + + public void unlock(String key) { + Semaphore semaphore = semaphores.get(key); + semaphore.release(); + if (semaphore.availablePermits() == ALLOWED_THREADS) { + semaphores.remove(key, semaphore); + } + } + +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/lockbykey/LockByKeyUnitTest.java b/core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/lockbykey/LockByKeyUnitTest.java new file mode 100644 index 0000000000..4e43a8fb49 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/lockbykey/LockByKeyUnitTest.java @@ -0,0 +1,106 @@ +package com.baeldung.lockbykey; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.jupiter.api.Test; + +public class LockByKeyUnitTest { + + @Test + void givenNoLockedKey_WhenLock_ThenSuccess() throws InterruptedException { + AtomicBoolean threadWasExecuted = new AtomicBoolean(false); + Thread thread = new Thread(() -> { + String key = "key"; + LockByKey lockByKey = new LockByKey(); + lockByKey.lock(key); + try { + threadWasExecuted.set(true); + } finally { + lockByKey.unlock(key); + } + }); + try { + thread.start(); + Thread.sleep(100); + } finally { + assertTrue(threadWasExecuted.get()); + } + } + + @Test + void givenLockedKey_WhenLock_ThenFailure() throws InterruptedException { + String key = "key"; + LockByKey lockByKey = new LockByKey(); + lockByKey.lock(key); + AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false); + Thread threadLockingOnAnotherKey = new Thread(() -> { + LockByKey otherLockByKey = new LockByKey(); + otherLockByKey.lock(key); + try { + anotherThreadWasExecuted.set(true); + } finally { + otherLockByKey.unlock(key); + } + }); + try { + threadLockingOnAnotherKey.start(); + Thread.sleep(100); + } finally { + assertFalse(anotherThreadWasExecuted.get()); + lockByKey.unlock(key); + } + } + + @Test + void givenAnotherKeyLocked_WhenLock_ThenSuccess() throws InterruptedException { + String key = "key"; + LockByKey lockByKey = new LockByKey(); + lockByKey.lock(key); + AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false); + Thread threadLockingOnAnotherKey = new Thread(() -> { + String anotherKey = "anotherKey"; + LockByKey otherLockByKey = new LockByKey(); + otherLockByKey.lock(anotherKey); + try { + anotherThreadWasExecuted.set(true); + } finally { + otherLockByKey.unlock(anotherKey); + } + }); + try { + threadLockingOnAnotherKey.start(); + Thread.sleep(100); + } finally { + assertTrue(anotherThreadWasExecuted.get()); + lockByKey.unlock(key); + } + } + + @Test + void givenUnlockedKey_WhenLock_ThenSuccess() throws InterruptedException { + String key = "key"; + LockByKey lockByKey = new LockByKey(); + lockByKey.lock(key); + AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false); + Thread threadLockingOnAnotherKey = new Thread(() -> { + LockByKey otherLockByKey = new LockByKey(); + otherLockByKey.lock(key); + try { + anotherThreadWasExecuted.set(true); + } finally { + otherLockByKey.unlock(key); + } + }); + try { + lockByKey.unlock(key); + threadLockingOnAnotherKey.start(); + Thread.sleep(100); + } finally { + assertTrue(anotherThreadWasExecuted.get()); + } + } + +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/lockbykey/SimpleExclusiveLockByKeyUnitTest.java b/core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/lockbykey/SimpleExclusiveLockByKeyUnitTest.java new file mode 100644 index 0000000000..deba728664 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/lockbykey/SimpleExclusiveLockByKeyUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.lockbykey; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.lang.reflect.Field; +import java.util.concurrent.ConcurrentHashMap; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class SimpleExclusiveLockByKeyUnitTest { + + @BeforeEach + void cleanUpLocks() throws Exception { + Field field = SimpleExclusiveLockByKey.class.getDeclaredField("usedKeys"); + field.setAccessible(true); + field.set(null, ConcurrentHashMap.newKeySet()); + } + + @Test + void givenNoLockedKey_WhenTryLock_ThenSuccess() { + SimpleExclusiveLockByKey lockByKey = new SimpleExclusiveLockByKey(); + assertTrue(lockByKey.tryLock("key")); + } + + @Test + void givenLockedKey_WhenTryLock_ThenFailure() { + String key = "key"; + SimpleExclusiveLockByKey lockByKey = new SimpleExclusiveLockByKey(); + lockByKey.tryLock(key); + assertFalse(lockByKey.tryLock(key)); + } + + @Test + void givenAnotherKeyLocked_WhenTryLock_ThenSuccess() { + SimpleExclusiveLockByKey lockByKey = new SimpleExclusiveLockByKey(); + lockByKey.tryLock("other"); + assertTrue(lockByKey.tryLock("key")); + } + + @Test + void givenUnlockedKey_WhenTryLock_ThenSuccess() { + String key = "key"; + SimpleExclusiveLockByKey lockByKey = new SimpleExclusiveLockByKey(); + lockByKey.tryLock(key); + lockByKey.unlock(key); + assertTrue(lockByKey.tryLock(key)); + } + +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/lockbykey/SimultaneousEntriesLockByKeyUnitTest.java b/core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/lockbykey/SimultaneousEntriesLockByKeyUnitTest.java new file mode 100644 index 0000000000..ec4e7f4d80 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/lockbykey/SimultaneousEntriesLockByKeyUnitTest.java @@ -0,0 +1,146 @@ +package com.baeldung.lockbykey; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.jupiter.api.Test; + +public class SimultaneousEntriesLockByKeyUnitTest { + + @Test + void givenNoKeyUsed_WhenLock_ThenSuccess() throws InterruptedException { + AtomicBoolean threadWasExecuted = new AtomicBoolean(false); + Thread thread = new Thread(() -> { + String key = "key"; + SimultaneousEntriesLockByKey lockByKey = new SimultaneousEntriesLockByKey(); + lockByKey.lock(key); + try { + threadWasExecuted.set(true); + } finally { + lockByKey.unlock(key); + } + }); + try { + thread.start(); + Thread.sleep(100); + } finally { + assertTrue(threadWasExecuted.get()); + } + } + + @Test + void givenKeyLockedWithRemainingPermits_WhenLock_ThenSuccess() throws InterruptedException { + String key = "key"; + SimultaneousEntriesLockByKey lockByKey = new SimultaneousEntriesLockByKey(); + lockByKey.lock(key); + AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false); + Thread threadLockingOnAnotherKey = new Thread(() -> { + SimultaneousEntriesLockByKey otherLockByKeyWithSemaphore = new SimultaneousEntriesLockByKey(); + otherLockByKeyWithSemaphore.lock(key); + try { + anotherThreadWasExecuted.set(true); + } finally { + otherLockByKeyWithSemaphore.unlock(key); + } + }); + try { + threadLockingOnAnotherKey.start(); + Thread.sleep(100); + } finally { + assertTrue(anotherThreadWasExecuted.get()); + lockByKey.unlock(key); + } + } + + @Test + void givenKeyLockedWithNoRemainingPermits_WhenLock_ThenFailure() throws InterruptedException { + String key = "key"; + SimultaneousEntriesLockByKey lockByKey = new SimultaneousEntriesLockByKey(); + lockByKey.lock(key); + AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false); + Thread threadLockingOnAnotherKey1 = new Thread(() -> { + SimultaneousEntriesLockByKey otherLockByKeyWithSemaphore = new SimultaneousEntriesLockByKey(); + otherLockByKeyWithSemaphore.lock(key); + try { + Thread.sleep(200); // make sure this thread will release the lock after the assertion + } catch (InterruptedException e) { + + } finally { + otherLockByKeyWithSemaphore.unlock(key); + } + }); + Thread threadLockingOnAnotherKey2 = new Thread(() -> { + SimultaneousEntriesLockByKey otherLockByKey = new SimultaneousEntriesLockByKey(); + try { + Thread.sleep(50); // make sure thread1 will acquire the key first + } catch (InterruptedException e) { + } + otherLockByKey.lock(key); + try { + anotherThreadWasExecuted.set(true); + } finally { + otherLockByKey.unlock(key); + } + }); + try { + threadLockingOnAnotherKey1.start(); + threadLockingOnAnotherKey2.start(); + Thread.sleep(100); + } finally { + assertFalse(anotherThreadWasExecuted.get()); + lockByKey.unlock(key); + } + } + + @Test + void givenAnotherKeyLocked_WhenLock_ThenSuccess() throws InterruptedException { + String key = "key"; + SimultaneousEntriesLockByKey lockByKey = new SimultaneousEntriesLockByKey(); + lockByKey.lock(key); + AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false); + Thread threadLockingOnAnotherKey = new Thread(() -> { + String anotherKey = "anotherKey"; + SimultaneousEntriesLockByKey otherLockByKey = new SimultaneousEntriesLockByKey(); + otherLockByKey.lock(anotherKey); + try { + anotherThreadWasExecuted.set(true); + } finally { + otherLockByKey.unlock(anotherKey); + } + }); + try { + threadLockingOnAnotherKey.start(); + Thread.sleep(100); + } finally { + assertTrue(anotherThreadWasExecuted.get()); + lockByKey.unlock(key); + } + } + + @Test + void givenUnlockedKey_WhenLock_ThenSuccess() throws InterruptedException { + String key = "key"; + SimultaneousEntriesLockByKey lockByKey = new SimultaneousEntriesLockByKey(); + lockByKey.lock(key); + AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false); + Thread threadLockingOnAnotherKey = new Thread(() -> { + SimultaneousEntriesLockByKey otherLockByKey = new SimultaneousEntriesLockByKey(); + otherLockByKey.lock(key); + try { + anotherThreadWasExecuted.set(true); + } finally { + otherLockByKey.unlock(key); + } + }); + try { + lockByKey.unlock(key); + threadLockingOnAnotherKey.start(); + Thread.sleep(100); + } finally { + assertTrue(anotherThreadWasExecuted.get()); + } + } + +} From bfd778c028f6c9fc75d9d05d9452d7ab4f3d1931 Mon Sep 17 00:00:00 2001 From: lucaCambi77 Date: Fri, 11 Mar 2022 03:48:37 +0100 Subject: [PATCH 117/249] BAEL-5395 - Authentication with Spring Security and MongoDB (#11883) * auth with spring security and mongodb * fix PMD * fix missing application property in tests * fix: code style * fix: static finale case * fix: omit Javadoc --- .../spring-security-web-boot-3/pom.xml | 12 +- .../mongoauth/MongoAuthApplication.java | 18 +++ .../mongoauth/config/MongoConfig.java | 40 ++++++ .../mongoauth/config/SecurityConfig.java | 59 +++++++++ .../controller/ResourceController.java | 23 ++++ .../com/baeldung/mongoauth/domain/Role.java | 13 ++ .../com/baeldung/mongoauth/domain/User.java | 83 ++++++++++++ .../baeldung/mongoauth/domain/UserRole.java | 21 ++++ .../mongoauth/repository/UserRepository.java | 13 ++ .../service/MongoAuthUserDetailService.java | 41 ++++++ .../mongoauth/service/SecurityService.java | 5 + .../service/SecurityServiceImpl.java | 39 ++++++ .../src/main/resources/application.properties | 1 + .../MongoAuthApplicationIntegrationTest.java | 118 ++++++++++++++++++ 14 files changed, 485 insertions(+), 1 deletion(-) create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/MongoAuthApplication.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/config/MongoConfig.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/config/SecurityConfig.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/controller/ResourceController.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/domain/Role.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/domain/User.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/domain/UserRole.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/repository/UserRepository.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/service/MongoAuthUserDetailService.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/service/SecurityService.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/service/SecurityServiceImpl.java create mode 100644 spring-security-modules/spring-security-web-boot-3/src/main/resources/application.properties create mode 100644 spring-security-modules/spring-security-web-boot-3/src/test/java/com/baeldung/mongoauth/MongoAuthApplicationIntegrationTest.java diff --git a/spring-security-modules/spring-security-web-boot-3/pom.xml b/spring-security-modules/spring-security-web-boot-3/pom.xml index 5f2a455294..5da993acd9 100644 --- a/spring-security-modules/spring-security-web-boot-3/pom.xml +++ b/spring-security-modules/spring-security-web-boot-3/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 spring-security-web-boot-3 0.0.1-SNAPSHOT @@ -23,6 +24,15 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-data-mongodb + + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + 3.3.1 + commons-io commons-io diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/MongoAuthApplication.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/MongoAuthApplication.java new file mode 100644 index 0000000000..53624c0dd8 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/MongoAuthApplication.java @@ -0,0 +1,18 @@ +package com.baeldung.mongoauth; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Import; + +import com.baeldung.mongoauth.config.MongoConfig; +import com.baeldung.mongoauth.config.SecurityConfig; + +@SpringBootApplication +@Import({ SecurityConfig.class, MongoConfig.class }) +public class MongoAuthApplication { + + public static void main(String... args) { + SpringApplication.run(MongoAuthApplication.class, args); + } + +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/config/MongoConfig.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/config/MongoConfig.java new file mode 100644 index 0000000000..ddef7800de --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/config/MongoConfig.java @@ -0,0 +1,40 @@ +package com.baeldung.mongoauth.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.util.SocketUtils; + +import com.mongodb.client.MongoClients; + +import de.flapdoodle.embed.mongo.MongodExecutable; +import de.flapdoodle.embed.mongo.MongodStarter; +import de.flapdoodle.embed.mongo.config.ImmutableMongodConfig; +import de.flapdoodle.embed.mongo.config.MongodConfig; +import de.flapdoodle.embed.mongo.config.Net; +import de.flapdoodle.embed.mongo.distribution.Version; +import de.flapdoodle.embed.process.runtime.Network; + +@Configuration +public class MongoConfig { + + private static final String CONNECTION_STRING = "mongodb://%s:%d"; + private static final String HOST = "localhost"; + + @Bean + public MongoTemplate mongoTemplate() throws Exception { + + int randomPort = SocketUtils.findAvailableTcpPort(); + + ImmutableMongodConfig mongoDbConfig = MongodConfig.builder() + .version(Version.Main.PRODUCTION) + .net(new Net(HOST, randomPort, Network.localhostIsIPv6())) + .build(); + + MongodStarter starter = MongodStarter.getDefaultInstance(); + MongodExecutable mongodExecutable = starter.prepare(mongoDbConfig); + mongodExecutable.start(); + return new MongoTemplate(MongoClients.create(String.format(CONNECTION_STRING, HOST, randomPort)), "mongo_auth"); + } + +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/config/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/config/SecurityConfig.java new file mode 100644 index 0000000000..050d917492 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/config/SecurityConfig.java @@ -0,0 +1,59 @@ +package com.baeldung.mongoauth.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true) +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + private final UserDetailsService userDetailsService; + + public SecurityConfig(UserDetailsService userDetailsService) { + this.userDetailsService = userDetailsService; + } + + @Bean + public AuthenticationManager customAuthenticationManager() throws Exception { + return authenticationManager(); + } + + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(@Autowired AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService) + .passwordEncoder(bCryptPasswordEncoder()); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf() + .disable() + .authorizeRequests() + .and() + .httpBasic() + .and() + .authorizeRequests() + .anyRequest() + .permitAll() + .and() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS); + } + +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/controller/ResourceController.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/controller/ResourceController.java new file mode 100644 index 0000000000..a5d9e91083 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/controller/ResourceController.java @@ -0,0 +1,23 @@ +package com.baeldung.mongoauth.controller; + +import javax.annotation.security.RolesAllowed; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ResourceController { + + @RolesAllowed("ROLE_ADMIN") + @GetMapping("/admin") + public String admin() { + return "Hello Admin!"; + } + + @RolesAllowed({ "ROLE_ADMIN", "ROLE_USER" }) + @GetMapping("/user") + public String user() { + return "Hello User!"; + } + +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/domain/Role.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/domain/Role.java new file mode 100644 index 0000000000..e475e68460 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/domain/Role.java @@ -0,0 +1,13 @@ +package com.baeldung.mongoauth.domain; + +public class Role { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/domain/User.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/domain/User.java new file mode 100644 index 0000000000..ffaea836a4 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/domain/User.java @@ -0,0 +1,83 @@ +package com.baeldung.mongoauth.domain; + +import java.util.Objects; +import java.util.Set; + +import org.bson.types.ObjectId; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.MongoId; +import org.springframework.security.core.userdetails.UserDetails; + +@Document +public class User implements UserDetails { + private @MongoId ObjectId id; + private String username; + private String password; + private Set userRoles; + + public ObjectId getId() { + return id; + } + + @Override + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setUserRoles(Set userRoles) { + this.userRoles = userRoles; + } + + @Override + public Set getAuthorities() { + return this.userRoles; + } + + @Override + public String getUsername() { + return this.username; + } + + public void setUsername(String username) { + this.username = username; + } + + @Override + public boolean isAccountNonExpired() { + return false; + } + + @Override + public boolean isAccountNonLocked() { + return false; + } + + @Override + public boolean isCredentialsNonExpired() { + return false; + } + + @Override + public boolean isEnabled() { + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + User user = (User) o; + return Objects.equals(username, user.username); + } + + @Override + public int hashCode() { + return Objects.hash(username); + } +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/domain/UserRole.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/domain/UserRole.java new file mode 100644 index 0000000000..ccfa3bd605 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/domain/UserRole.java @@ -0,0 +1,21 @@ +package com.baeldung.mongoauth.domain; + +import org.springframework.security.core.GrantedAuthority; + +public class UserRole implements GrantedAuthority { + + private Role role; + + @Override + public String getAuthority() { + return role.getName(); + } + + public Role getRole() { + return role; + } + + public void setRole(Role role) { + this.role = role; + } +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/repository/UserRepository.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/repository/UserRepository.java new file mode 100644 index 0000000000..c68f77ffbf --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/repository/UserRepository.java @@ -0,0 +1,13 @@ +package com.baeldung.mongoauth.repository; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; + +import com.baeldung.mongoauth.domain.User; + +public interface UserRepository extends MongoRepository { + + @Query("{username:'?0'}") + User findUserByUsername(String username); + +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/service/MongoAuthUserDetailService.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/service/MongoAuthUserDetailService.java new file mode 100644 index 0000000000..5838504d40 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/service/MongoAuthUserDetailService.java @@ -0,0 +1,41 @@ +package com.baeldung.mongoauth.service; + +import java.util.HashSet; +import java.util.Set; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import com.baeldung.mongoauth.repository.UserRepository; + +@Service +public class MongoAuthUserDetailService implements UserDetailsService { + + private final UserRepository userRepository; + + public MongoAuthUserDetailService(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @Override + public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { + + com.baeldung.mongoauth.domain.User user = userRepository.findUserByUsername(userName); + + Set grantedAuthorities = new HashSet<>(); + + user.getAuthorities() + .forEach(role -> { + grantedAuthorities.add(new SimpleGrantedAuthority(role.getRole() + .getName())); + }); + + return new User(user.getUsername(), user.getPassword(), grantedAuthorities); + } + +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/service/SecurityService.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/service/SecurityService.java new file mode 100644 index 0000000000..4204e4708b --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/service/SecurityService.java @@ -0,0 +1,5 @@ +package com.baeldung.mongoauth.service; + +public interface SecurityService { + boolean login(String username, String password); +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/service/SecurityServiceImpl.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/service/SecurityServiceImpl.java new file mode 100644 index 0000000000..f86ffaa26a --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/mongoauth/service/SecurityServiceImpl.java @@ -0,0 +1,39 @@ +package com.baeldung.mongoauth.service; + +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.stereotype.Service; + +@Service +public class SecurityServiceImpl implements SecurityService { + + private final AuthenticationManager authenticationManager; + + private final UserDetailsService userDetailsService; + + public SecurityServiceImpl(AuthenticationManager authenticationManager, UserDetailsService userDetailsService) { + this.authenticationManager = authenticationManager; + this.userDetailsService = userDetailsService; + } + + @Override + public boolean login(String username, String password) { + UserDetails userDetails = userDetailsService.loadUserByUsername(username); + + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities()); + + authenticationManager.authenticate(usernamePasswordAuthenticationToken); + + if (usernamePasswordAuthenticationToken.isAuthenticated()) { + SecurityContextHolder.getContext() + .setAuthentication(usernamePasswordAuthenticationToken); + + return true; + } + + return false; + } +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/resources/application.properties b/spring-security-modules/spring-security-web-boot-3/src/main/resources/application.properties new file mode 100644 index 0000000000..a5b5fb9804 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.mongodb.embedded.version=4.4.9 \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-boot-3/src/test/java/com/baeldung/mongoauth/MongoAuthApplicationIntegrationTest.java b/spring-security-modules/spring-security-web-boot-3/src/test/java/com/baeldung/mongoauth/MongoAuthApplicationIntegrationTest.java new file mode 100644 index 0000000000..b7994cad9e --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/test/java/com/baeldung/mongoauth/MongoAuthApplicationIntegrationTest.java @@ -0,0 +1,118 @@ +package com.baeldung.mongoauth; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.Collections; +import java.util.HashSet; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import com.baeldung.mongoauth.domain.Role; +import com.baeldung.mongoauth.domain.User; +import com.baeldung.mongoauth.domain.UserRole; + +@SpringBootTest(classes = { MongoAuthApplication.class }) +@AutoConfigureMockMvc +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +class MongoAuthApplicationIntegrationTest { + + @Autowired + private WebApplicationContext context; + + @Autowired + private MongoTemplate mongoTemplate; + + @Autowired + private BCryptPasswordEncoder bCryptPasswordEncoder; + + private MockMvc mvc; + + private static final String USER_NAME = "user@gmail.com"; + private static final String ADMIN_NAME = "admin@gmail.com"; + private static final String PASSWORD = "password"; + + @BeforeEach + public void setup() { + + setUp(); + + mvc = MockMvcBuilders.webAppContextSetup(context) + .apply(springSecurity()) + .build(); + } + + private void setUp() { + Role roleUser = new Role(); + roleUser.setName("ROLE_USER"); + mongoTemplate.save(roleUser); + + User user = new User(); + user.setUsername(USER_NAME); + user.setPassword(bCryptPasswordEncoder.encode(PASSWORD)); + + UserRole userRole = new UserRole(); + userRole.setRole(roleUser); + user.setUserRoles(new HashSet<>(Collections.singletonList(userRole))); + mongoTemplate.save(user); + + User admin = new User(); + admin.setUsername(ADMIN_NAME); + admin.setPassword(bCryptPasswordEncoder.encode(PASSWORD)); + + Role roleAdmin = new Role(); + roleAdmin.setName("ROLE_ADMIN"); + mongoTemplate.save(roleAdmin); + + UserRole adminRole = new UserRole(); + adminRole.setRole(roleAdmin); + admin.setUserRoles(new HashSet<>(Collections.singletonList(adminRole))); + mongoTemplate.save(admin); + } + + @Test + void givenUserCredentials_whenInvokeUserAuthorizedEndPoint_thenReturn200() throws Exception { + mvc.perform(get("/user").with(httpBasic(USER_NAME, PASSWORD))) + .andExpect(status().isOk()); + } + + @Test + void givenUserNotExists_whenInvokeEndPoint_thenReturn401() throws Exception { + mvc.perform(get("/user").with(httpBasic("not_existing_user", "password"))) + .andExpect(status().isUnauthorized()); + } + + @Test + void givenUserExistsAndWrongPassword_whenInvokeEndPoint_thenReturn401() throws Exception { + mvc.perform(get("/user").with(httpBasic(USER_NAME, "wrong_password"))) + .andExpect(status().isUnauthorized()); + } + + @Test + void givenUserCredentials_whenInvokeAdminAuthorizedEndPoint_thenReturn403() throws Exception { + mvc.perform(get("/admin").with(httpBasic(USER_NAME, PASSWORD))) + .andExpect(status().isForbidden()); + } + + @Test + void givenAdminCredentials_whenInvokeAdminAuthorizedEndPoint_thenReturn200() throws Exception { + mvc.perform(get("/admin").with(httpBasic(ADMIN_NAME, PASSWORD))) + .andExpect(status().isOk()); + + mvc.perform(get("/user").with(httpBasic(ADMIN_NAME, PASSWORD))) + .andExpect(status().isOk()); + } + +} From 538c845739ad530589a507fcc49ed50d98ea244a Mon Sep 17 00:00:00 2001 From: kwoyke Date: Fri, 11 Mar 2022 17:09:33 +0100 Subject: [PATCH 118/249] JAVA-10130: Add/enable missing modules (#11887) * JAVA-10130: Add apache-pot-2 module to the main pom.xml * JAVA-10130: Add missing core-java-* modules to the main pom.xml * JAVA-10130: Add maven-generate-war to the maven-modules pom.xml * JAVA-10130: Add hibernate-mapping-2 to the persistence-modules pom.xml * JAVA-10130: Add spring-data-jpa-enterprise-2 to the persistence-modules pom.xml * JAVA-10130: Add spring-5-autowiring-beans module to the main pom.xml * JAVA-10130: Add spring-cloud-docker module to the spring-cloud pom.xml * JAVA-10130: Enable spring-cloud-openfeign module * JAVA-10130: Add spring-data-rest-2 module to the main pom.xml * JAVA-10130: Add wildfly-mdb module to the wildfly pom.xml * JAVA-10130: Add aws-app-sync to the integration-lite-first profile * JAVA-10130: Add core-java-string-algorithms-3 * JAVA-10130: Add graphql/graphql-dgs * JAVA-10130: Add spring-di-3 and spring-threads * JAVA-10130: Add spring-5-webflux-2 and cleanup the main pom.xml * JAVA-10130: Add language-interop and libraries-rpc * JAVA-10130: Disable spring-cloud-openfeign module * JAVA-10478: Add docker module to the main pom.xml * JAVA-10478: Move docker module to jdk9+ profile * JAVA-10478: Remove spring-5-autowiring-beans from the main pom.xml --- maven-modules/pom.xml | 1 + persistence-modules/pom.xml | 2 + pom.xml | 89 ++++++++++++++++++++++--------------- spring-cloud/pom.xml | 4 +- spring-ejb/wildfly/pom.xml | 1 + 5 files changed, 60 insertions(+), 37 deletions(-) diff --git a/maven-modules/pom.xml b/maven-modules/pom.xml index 37be581804..0d65e5f9f4 100644 --- a/maven-modules/pom.xml +++ b/maven-modules/pom.xml @@ -19,6 +19,7 @@ maven-copy-files maven-custom-plugin maven-exec-plugin + maven-integration-test maven-multi-source maven-plugins diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 152e58d57b..64a9519a8b 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -27,6 +27,7 @@ hbase hibernate5 hibernate-mapping + hibernate-mapping-2 hibernate-ogm hibernate-annotations hibernate-exceptions @@ -73,6 +74,7 @@ spring-data-jpa-crud spring-data-jpa-crud-2 spring-data-jpa-enterprise + spring-data-jpa-enterprise-2 spring-data-jpa-filtering spring-data-jpa-query spring-data-jpa-query-2 diff --git a/pom.xml b/pom.xml index b6767c629b..a6202230d4 100644 --- a/pom.xml +++ b/pom.xml @@ -7,9 +7,6 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - - spring-5-webflux-2 - parent-modules pom @@ -355,6 +352,7 @@ apache-libraries apache-olingo apache-poi + apache-poi-2 apache-rocketmq apache-shiro apache-spark @@ -653,6 +651,7 @@ spring-cucumber spring-data-rest + spring-data-rest-2 spring-data-rest-querydsl spring-di spring-di-2 @@ -841,6 +840,7 @@ apache-libraries apache-olingo apache-poi + apache-poi-2 apache-rocketmq apache-shiro apache-spark @@ -855,6 +855,7 @@ atomix aws + aws-app-sync aws-lambda aws-reactive @@ -906,6 +907,7 @@ graphql/graphql-java + graphql/graphql-dgs grpc gson guava-modules @@ -967,6 +969,7 @@ ksqldb + language-interop libraries-2 libraries-3 @@ -981,6 +984,7 @@ libraries-http-2 libraries-io libraries-primitive + libraries-rpc libraries-security libraries-server libraries-server-2 @@ -1096,6 +1100,7 @@ spring-5-reactive-oauth spring-5-reactive-security spring-5-webflux + spring-5-webflux-2 spring-reactive spring-activiti @@ -1128,9 +1133,11 @@ spring-cucumber spring-data-rest + spring-data-rest-2 spring-data-rest-querydsl spring-di spring-di-2 + spring-di-3 spring-drools spring-ejb @@ -1168,6 +1175,8 @@ spring-static-resources spring-swagger-codegen + spring-threads + spring-vault spring-vertx @@ -1317,39 +1326,43 @@ core-java-modules/core-java-9-improvements core-java-modules/core-java-9-jigsaw - core-java-modules/core-java-9-streams - core-java-modules/core-java-10 - core-java-modules/core-java-11 - core-java-modules/core-java-11-2 - - - - - core-java-modules/core-java-collections-set - core-java-modules/core-java-collections-maps-4 - core-java-modules/core-java-date-operations-1 - core-java-modules/core-java-datetime-conversion - core-java-modules/core-java-datetime-string - core-java-modules/core-java-io-conversions-2 - core-java-modules/core-java-jpms - core-java-modules/core-java-os - core-java-modules/core-java-string-algorithms-3 - core-java-modules/core-java-string-operations-3 - core-java-modules/core-java-string-operations-4 - core-java-modules/core-java-time-measurements - core-java-modules/core-java-networking-3 - core-java-modules/multimodulemavenproject - ddd-modules - httpclient-2 - libraries-concurrency - persistence-modules/sirix - persistence-modules/spring-data-cassandra-2 - quarkus-vs-springboot - quarkus-jandex - spring-boot-modules/spring-boot-cassandre - spring-boot-modules/spring-boot-camel - testing-modules/testing-assertions - persistence-modules/fauna + core-java-modules/core-java-9-streams + core-java-modules/core-java-10 + core-java-modules/core-java-11 + core-java-modules/core-java-11-2 + + + + + + + core-java-modules/core-java-collections-set + core-java-modules/core-java-collections-maps-4 + core-java-modules/core-java-date-operations-1 + core-java-modules/core-java-datetime-conversion + core-java-modules/core-java-datetime-string + core-java-modules/core-java-io-conversions-2 + core-java-modules/core-java-jpms + core-java-modules/core-java-os + core-java-modules/core-java-string-algorithms-3 + core-java-modules/core-java-string-operations-3 + core-java-modules/core-java-string-operations-4 + core-java-modules/core-java-time-measurements + core-java-modules/core-java-networking-3 + core-java-modules/multimodulemavenproject + core-java-modules/core-java-strings + ddd-modules + docker + httpclient-2 + libraries-concurrency + persistence-modules/sirix + persistence-modules/spring-data-cassandra-2 + quarkus-vs-springboot + quarkus-jandex + spring-boot-modules/spring-boot-cassandre + spring-boot-modules/spring-boot-camel + testing-modules/testing-assertions + persistence-modules/fauna @@ -1388,6 +1401,8 @@ + + core-java-modules/core-java-collections-set core-java-modules/core-java-collections-maps-4 core-java-modules/core-java-date-operations-1 @@ -1396,6 +1411,7 @@ core-java-modules/core-java-io-conversions-2 core-java-modules/core-java-jpms core-java-modules/core-java-os + core-java-modules/core-java-string-algorithms-3 core-java-modules/core-java-string-operations-3 core-java-modules/core-java-string-operations-4 core-java-modules/core-java-time-measurements @@ -1403,6 +1419,7 @@ core-java-modules/multimodulemavenproject core-java-modules/core-java-strings ddd-modules + docker httpclient-2 libraries-concurrency persistence-modules/sirix diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml index ac810c9a77..75010fbd34 100644 --- a/spring-cloud/pom.xml +++ b/spring-cloud/pom.xml @@ -45,9 +45,11 @@ spring-cloud-ribbon-retry spring-cloud-circuit-breaker spring-cloud-eureka-self-preservation - + + spring-cloud-sentinel spring-cloud-dapr + spring-cloud-docker diff --git a/spring-ejb/wildfly/pom.xml b/spring-ejb/wildfly/pom.xml index ae90f71b7c..8a6d41ea82 100644 --- a/spring-ejb/wildfly/pom.xml +++ b/spring-ejb/wildfly/pom.xml @@ -21,6 +21,7 @@ wildfly-jpa wildfly-ejb-interfaces wildfly-ejb + wildfly-mdb From 5b56b1ed392e3448f940601dd74367b88577a0d1 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Fri, 11 Mar 2022 20:11:54 -0300 Subject: [PATCH 119/249] BAEL-5403 - Import Data to MongoDB from Json File using Java * Project * Integration tests --- .../SpringBootPersistenceApplication.java | 48 +++++++- .../boot/json/convertfile/ImportUtils.java | 60 ++++++++++ .../json/convertfile/dao/BookRepository.java | 9 ++ .../boot/json/convertfile/data/Book.java | 38 +++++++ .../service/ImportJsonService.java | 74 ++++++++++++ .../json/convertfile/web/BookController.java | 51 +++++++++ .../convertfile/web/ImportJsonController.java | 35 ++++++ .../boot.json.convertfile/data.json.log | 3 + .../ImportJsonServiceIntegrationTest.java | 105 ++++++++++++++++++ .../boot.json.convertfile/books.json.log | 2 + .../boot.json.convertfile/movies.json.log | 3 + 11 files changed, 427 insertions(+), 1 deletion(-) create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/ImportUtils.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/dao/BookRepository.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/data/Book.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/service/ImportJsonService.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/web/BookController.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/web/ImportJsonController.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/resources/boot.json.convertfile/data.json.log create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/boot/json/convertfile/service/ImportJsonServiceIntegrationTest.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/test/resources/boot.json.convertfile/books.json.log create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/test/resources/boot.json.convertfile/movies.json.log diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/SpringBootPersistenceApplication.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/SpringBootPersistenceApplication.java index 2dff3f37df..a5cb443291 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/SpringBootPersistenceApplication.java +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/SpringBootPersistenceApplication.java @@ -1,13 +1,59 @@ package com.baeldung; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; + +import com.baeldung.boot.json.convertfile.ImportUtils; +import com.baeldung.boot.json.convertfile.service.ImportJsonService; @SpringBootApplication -public class SpringBootPersistenceApplication { +public class SpringBootPersistenceApplication implements ApplicationRunner { + private Logger log = LogManager.getLogger(this.getClass()); + private static final String RESOURCE_PREFIX = "classpath:"; + + @Autowired + private ApplicationContext context; public static void main(String ... args) { SpringApplication.run(SpringBootPersistenceApplication.class, args); } + @Override + public void run(ApplicationArguments args) throws Exception { + if (args.containsOption("import")) { + if (!args.containsOption("collection")) + throw new IllegalArgumentException("required option: --collection with collection name when using --import"); + + String collection = args.getOptionValues("collection") + .get(0); + + List sources = args.getOptionValues("import"); + for (String source : sources) { + List jsonLines = new ArrayList<>(); + if (source.startsWith(RESOURCE_PREFIX)) { + String resource = source.substring(RESOURCE_PREFIX.length()); + jsonLines = ImportUtils.linesFromResource(resource); + } else { + jsonLines = ImportUtils.lines(new File(source)); + } + + if (jsonLines == null || jsonLines.isEmpty()) + throw new IllegalArgumentException("no input to import"); + + ImportJsonService importService = context.getBean(ImportJsonService.class); + String result = importService.importTo(collection, jsonLines); + log.info(source + " - result: " + result); + } + } + } } diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/ImportUtils.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/ImportUtils.java new file mode 100644 index 0000000000..c09746a33d --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/ImportUtils.java @@ -0,0 +1,60 @@ +package com.baeldung.boot.json.convertfile; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.web.multipart.MultipartFile; + +public class ImportUtils { + private static Logger log = LogManager.getLogger(ImportUtils.class); + + public static List lines(String json) { + if (json == null) + return Collections.emptyList(); + + String[] split = json.split("[\\r\\n]+"); + return Arrays.asList(split); + } + + public static List lines(MultipartFile file) { + try { + Path tmp = Files.write(File.createTempFile("mongo-upload", null) + .toPath(), file.getBytes()); + + return Files.readAllLines(tmp); + } catch (IOException e) { + log.error("reading lines from " + file, e); + return null; + } + } + + public static List lines(File file) { + try { + return Files.readAllLines(file.toPath()); + } catch (IOException e) { + log.error("reading lines from " + file, e); + return null; + } + } + + public static List linesFromResource(String resource) { + Resource input = new ClassPathResource(resource); + try { + Path path = input.getFile() + .toPath(); + return Files.readAllLines(path); + } catch (IOException e) { + log.error("reading lines from classpath resource: " + resource, e); + return null; + } + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/dao/BookRepository.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/dao/BookRepository.java new file mode 100644 index 0000000000..523be429da --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/dao/BookRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.boot.json.convertfile.dao; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.boot.json.convertfile.data.Book; + +public interface BookRepository extends MongoRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/data/Book.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/data/Book.java new file mode 100644 index 0000000000..c352cdeecd --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/data/Book.java @@ -0,0 +1,38 @@ +package com.baeldung.boot.json.convertfile.data; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document("books") +public class Book { + @Id + private String id; + + private String name; + + private String genre; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getGenre() { + return genre; + } + + public void setGenre(String genre) { + this.genre = genre; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/service/ImportJsonService.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/service/ImportJsonService.java new file mode 100644 index 0000000000..4800a85da3 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/service/ImportJsonService.java @@ -0,0 +1,74 @@ +package com.baeldung.boot.json.convertfile.service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bson.Document; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.mongodb.MongoBulkWriteException; + +@Service +public class ImportJsonService { + private Logger log = LogManager.getLogger(this.getClass()); + + @Autowired + private MongoTemplate mongo; + + public String importTo(Class type, List jsonLines) { + List mongoDocs = generateMongoDocs(jsonLines, type); + String collection = type.getAnnotation(org.springframework.data.mongodb.core.mapping.Document.class) + .value(); + int inserts = insertInto(collection, mongoDocs); + return inserts + "/" + jsonLines.size(); + } + + public String importTo(String collection, List jsonLines) { + List mongoDocs = generateMongoDocs(jsonLines); + int inserts = insertInto(collection, mongoDocs); + return inserts + "/" + jsonLines.size(); + } + + private int insertInto(String collection, List mongoDocs) { + try { + Collection inserts = mongo.insert(mongoDocs, collection); + return inserts.size(); + } catch (DataIntegrityViolationException e) { + log.error("importing docs", e); + if (e.getCause() instanceof MongoBulkWriteException) { + return ((MongoBulkWriteException) e.getCause()).getWriteResult() + .getInsertedCount(); + } + return 0; + } + } + + private List generateMongoDocs(List lines) { + return generateMongoDocs(lines, null); + } + + private List generateMongoDocs(List lines, Class type) { + ObjectMapper mapper = new ObjectMapper(); + + List docs = new ArrayList<>(); + for (String json : lines) { + try { + if (type != null) { + T v = mapper.readValue(json, type); + json = mapper.writeValueAsString(v); + } + docs.add(Document.parse(json)); + } catch (Throwable e) { + log.error("parsing: " + json, e); + } + } + return docs; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/web/BookController.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/web/BookController.java new file mode 100644 index 0000000000..3fbe1bb34c --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/web/BookController.java @@ -0,0 +1,51 @@ +package com.baeldung.boot.json.convertfile.web; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import com.baeldung.boot.json.convertfile.ImportUtils; +import com.baeldung.boot.json.convertfile.dao.BookRepository; +import com.baeldung.boot.json.convertfile.data.Book; +import com.baeldung.boot.json.convertfile.service.ImportJsonService; + +@RestController +@RequestMapping("/books") +public class BookController { + @Autowired + private BookRepository books; + + @Autowired + private ImportJsonService service; + + @PostMapping + public Book postBook(@RequestBody Book book) throws IOException { + return books.insert(book); + } + + @GetMapping + public List getBooks() { + return books.findAll(); + } + + @GetMapping("/{id}") + public Optional getBook(@PathVariable String id) { + return books.findById(id); + } + + @PostMapping("/import/file") + public String postJsonFile(@RequestPart("parts") MultipartFile jsonStringsFile) throws IOException { + List jsonLines = ImportUtils.lines(jsonStringsFile); + return service.importTo(Book.class, jsonLines); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/web/ImportJsonController.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/web/ImportJsonController.java new file mode 100644 index 0000000000..2e475c9e8c --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/web/ImportJsonController.java @@ -0,0 +1,35 @@ +package com.baeldung.boot.json.convertfile.web; + +import java.io.IOException; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import com.baeldung.boot.json.convertfile.ImportUtils; +import com.baeldung.boot.json.convertfile.service.ImportJsonService; + +@RestController +@RequestMapping("/import-json") +public class ImportJsonController { + @Autowired + private ImportJsonService service; + + @PostMapping("/{collection}") + public String postJson(@RequestBody String jsonStrings, @PathVariable String collection) { + List jsonLines = ImportUtils.lines(jsonStrings); + return service.importTo(collection, jsonLines); + } + + @PostMapping("/file/{collection}") + public String postJsonFile(@RequestPart("parts") MultipartFile jsonStringsFile, @PathVariable String collection) throws IOException { + List jsonLines = ImportUtils.lines(jsonStringsFile); + return service.importTo(collection, jsonLines); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/resources/boot.json.convertfile/data.json.log b/persistence-modules/spring-boot-persistence-mongodb/src/main/resources/boot.json.convertfile/data.json.log new file mode 100644 index 0000000000..4c1a23f435 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/resources/boot.json.convertfile/data.json.log @@ -0,0 +1,3 @@ +{"name":"Book A", "genre": "Comedy"} +{"name":"Book B", "genre": "Thriller"} +{"_id": "mongo-id", "name":"Book C", "genre": "Drama"} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/boot/json/convertfile/service/ImportJsonServiceIntegrationTest.java b/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/boot/json/convertfile/service/ImportJsonServiceIntegrationTest.java new file mode 100644 index 0000000000..611cdffa88 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/boot/json/convertfile/service/ImportJsonServiceIntegrationTest.java @@ -0,0 +1,105 @@ +package com.baeldung.boot.json.convertfile.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.boot.json.convertfile.ImportUtils; +import com.baeldung.boot.json.convertfile.dao.BookRepository; +import com.baeldung.boot.json.convertfile.data.Book; +import com.mongodb.DBObject; + +@SpringBootTest +@DirtiesContext +@RunWith(SpringRunner.class) +public class ImportJsonServiceIntegrationTest { + @Autowired + private ImportJsonService service; + + @Autowired + private MongoTemplate mongoDb; + + @Autowired + BookRepository bookRepository; + + @Test + public void givenJsonString_whenGenericType_thenDocumentImported() { + String collection = "items"; + List docs = mongoDb.findAll(DBObject.class, collection); + int sizeBefore = docs.size(); + + String json = "{\"name\":\"Item A\"}\n{\"name\":\"Item B\"}"; + List jsonLines = ImportUtils.lines(json); + service.importTo(collection, jsonLines); + + docs = mongoDb.findAll(DBObject.class, collection); + int sizeAfter = docs.size(); + assertThat(sizeAfter - sizeBefore).isEqualTo(jsonLines.size()); + } + + @Test + public void givenJsonFile_whenClasspathSource_thenDocumentImported() { + String collection = "movies"; + List docs = mongoDb.findAll(DBObject.class, collection); + int sizeBefore = docs.size(); + + String resource = "boot.json.convertfile/movies.json.log"; + List jsonLines = ImportUtils.linesFromResource(resource); + service.importTo(collection, jsonLines); + + docs = mongoDb.findAll(DBObject.class, collection); + int sizeAfter = docs.size(); + assertThat(sizeAfter - sizeBefore).isEqualTo(jsonLines.size()); + } + + @Test + public void givenJsonClasspathFile_whenCorrectlyTyped_thenDocumentImported() { + List books = bookRepository.findAll(); + int sizeBefore = books.size(); + + String resource = "boot.json.convertfile/books.json.log"; + List jsonLines = ImportUtils.linesFromResource(resource); + service.importTo(Book.class, jsonLines); + + books = bookRepository.findAll(); + int sizeAfter = books.size(); + assertThat(sizeAfter - sizeBefore).isEqualTo(jsonLines.size()); + } + + @Test + public void givenIncorrectlyTypedJson_whenUsingTypes_thenDocumentNotImported() { + List books = bookRepository.findAll(); + int sizeBefore = books.size(); + + String resource = "boot.json.convertfile/movies.json.log"; + List jsonLines = ImportUtils.linesFromResource(resource); + service.importTo(Book.class, jsonLines); + + books = bookRepository.findAll(); + int sizeAfter = books.size(); + assertThat(sizeAfter - sizeBefore).isEqualTo(0); + } + + @Test + public void whenInvalidJson_thenDocumentNotImported() { + String collection = "items"; + List docs = mongoDb.findAll(DBObject.class, collection); + int sizeBefore = docs.size(); + + String json = "{name: Item A}\n{name: Item B}"; + List jsonLines = ImportUtils.lines(json); + service.importTo(collection, jsonLines); + + docs = mongoDb.findAll(DBObject.class, collection); + int sizeAfter = docs.size(); + assertThat(sizeAfter - sizeBefore).isEqualTo(0); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/test/resources/boot.json.convertfile/books.json.log b/persistence-modules/spring-boot-persistence-mongodb/src/test/resources/boot.json.convertfile/books.json.log new file mode 100644 index 0000000000..63c618ba82 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/test/resources/boot.json.convertfile/books.json.log @@ -0,0 +1,2 @@ +{"name":"Movie A", "genre": "Comedy"} +{"name":"Movie B", "genre": "Thriller"} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/test/resources/boot.json.convertfile/movies.json.log b/persistence-modules/spring-boot-persistence-mongodb/src/test/resources/boot.json.convertfile/movies.json.log new file mode 100644 index 0000000000..7658d8610e --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/test/resources/boot.json.convertfile/movies.json.log @@ -0,0 +1,3 @@ +{"title":"Movie A", "genre": "Comedy"} +{"title":"Movie B", "genre": "Thriller"} +{"_id": "mongo-id", "title":"Movie C", "genre": "Drama"} From 0f920f8c79261ba84f8c57bb1775481e996db65f Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 12 Mar 2022 10:38:34 +0530 Subject: [PATCH 120/249] JAVA-10083 --- .../hibernate-queries-2/.gitignore | 13 --- .../hibernate-queries-2/README.md | 8 -- .../hibernate-queries-2/pom.xml | 86 ------------------- .../src/main/resources/logback.xml | 19 ---- .../src/test/resources/.gitignore | 13 --- .../hibernate-queries/README.md | 1 + persistence-modules/hibernate-queries/pom.xml | 59 ++++++++++++- .../hibernate/criteria/PersistenceConfig.java | 0 .../hibernate/criteria/model/Item.java | 0 .../criteria/util/HibernateUtil.java | 0 .../criteria/view/ApplicationView.java | 0 .../src/main/resources/import-db.sql | 0 .../src/main/resources/logback.xml | 6 ++ .../main/resources/persistence-h2.properties | 0 .../java/com/baeldung/SpringContextTest.java | 0 .../HibernateCriteriaIntegrationTest.java | 0 .../criteria/HibernateCriteriaTestRunner.java | 0 .../criteria/HibernateCriteriaTestSuite.java | 0 .../hibernate/criteria/model/Item.hbm.xml | 0 .../src/test/resources/criteria.cfg.xml | 0 .../src/test/resources/import-db.sql | 0 21 files changed, 65 insertions(+), 140 deletions(-) delete mode 100644 persistence-modules/hibernate-queries-2/.gitignore delete mode 100644 persistence-modules/hibernate-queries-2/README.md delete mode 100644 persistence-modules/hibernate-queries-2/pom.xml delete mode 100644 persistence-modules/hibernate-queries-2/src/main/resources/logback.xml delete mode 100644 persistence-modules/hibernate-queries-2/src/test/resources/.gitignore rename persistence-modules/{hibernate-queries-2 => hibernate-queries}/src/main/java/com/baeldung/hibernate/criteria/PersistenceConfig.java (100%) rename persistence-modules/{hibernate-queries-2 => hibernate-queries}/src/main/java/com/baeldung/hibernate/criteria/model/Item.java (100%) rename persistence-modules/{hibernate-queries-2 => hibernate-queries}/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java (100%) rename persistence-modules/{hibernate-queries-2 => hibernate-queries}/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java (100%) rename persistence-modules/{hibernate-queries-2 => hibernate-queries}/src/main/resources/import-db.sql (100%) rename persistence-modules/{hibernate-queries-2 => hibernate-queries}/src/main/resources/persistence-h2.properties (100%) rename persistence-modules/{hibernate-queries-2 => hibernate-queries}/src/test/java/com/baeldung/SpringContextTest.java (100%) rename persistence-modules/{hibernate-queries-2 => hibernate-queries}/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java (100%) rename persistence-modules/{hibernate-queries-2 => hibernate-queries}/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java (100%) rename persistence-modules/{hibernate-queries-2 => hibernate-queries}/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java (100%) rename persistence-modules/{hibernate-queries-2 => hibernate-queries}/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml (100%) rename persistence-modules/{hibernate-queries-2 => hibernate-queries}/src/test/resources/criteria.cfg.xml (100%) rename persistence-modules/{hibernate-queries-2 => hibernate-queries}/src/test/resources/import-db.sql (100%) diff --git a/persistence-modules/hibernate-queries-2/.gitignore b/persistence-modules/hibernate-queries-2/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/persistence-modules/hibernate-queries-2/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/persistence-modules/hibernate-queries-2/README.md b/persistence-modules/hibernate-queries-2/README.md deleted file mode 100644 index 276e08ef52..0000000000 --- a/persistence-modules/hibernate-queries-2/README.md +++ /dev/null @@ -1,8 +0,0 @@ -## Hibernate 5 with Spring - -This module contains articles about JPA Criteria Queries. - -### Relevant articles - -- [JPA Criteria Queries](https://www.baeldung.com/hibernate-criteria-queries) - diff --git a/persistence-modules/hibernate-queries-2/pom.xml b/persistence-modules/hibernate-queries-2/pom.xml deleted file mode 100644 index 58b1b23b06..0000000000 --- a/persistence-modules/hibernate-queries-2/pom.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - 4.0.0 - hibernate-queries-2 - 0.1-SNAPSHOT - hibernate-queries-2 - - - com.baeldung - persistence-modules - 1.0.0-SNAPSHOT - - - - - - org.springframework - spring-context - ${org.springframework.version} - - - org.springframework.data - spring-data-jpa - ${org.springframework.data.version} - - - org.hibernate - hibernate-core - ${hibernate.version} - - - org.apache.tomcat - tomcat-dbcp - ${tomcat-dbcp.version} - - - - - com.google.guava - guava - ${guava.version} - - - - org.springframework - spring-test - ${org.springframework.version} - test - - - com.h2database - h2 - ${h2.version} - - - com.sun.xml.bind - jaxb-core - ${com.sun.xml.version} - - - javax.xml.bind - jaxb-api - ${javax.xml.bind.version} - - - com.sun.xml.bind - jaxb-impl - ${com.sun.xml.version} - - - - - - 5.0.2.RELEASE - 1.10.6.RELEASE - - 5.2.10.Final - 9.0.0.M26 - 2.3.4 - 2.3.0.1 - 2.3.1 - - - \ No newline at end of file diff --git a/persistence-modules/hibernate-queries-2/src/main/resources/logback.xml b/persistence-modules/hibernate-queries-2/src/main/resources/logback.xml deleted file mode 100644 index ec0dc2469a..0000000000 --- a/persistence-modules/hibernate-queries-2/src/main/resources/logback.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - web - %date [%thread] %-5level %logger{36} - %message%n - - - - - - - - - - - - - - \ No newline at end of file diff --git a/persistence-modules/hibernate-queries-2/src/test/resources/.gitignore b/persistence-modules/hibernate-queries-2/src/test/resources/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/persistence-modules/hibernate-queries-2/src/test/resources/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/persistence-modules/hibernate-queries/README.md b/persistence-modules/hibernate-queries/README.md index 58ca74cd24..f1bc1cba0f 100644 --- a/persistence-modules/hibernate-queries/README.md +++ b/persistence-modules/hibernate-queries/README.md @@ -4,6 +4,7 @@ This module contains articles about use of Queries in Hibernate. ### Relevant articles: +- [JPA Criteria Queries](https://www.baeldung.com/hibernate-criteria-queries) - [Criteria Queries Using JPA Metamodel](https://www.baeldung.com/hibernate-criteria-queries-metamodel) - [Get All Data from a Table with Hibernate](https://www.baeldung.com/hibernate-select-all) - [Hibernate Named Query](https://www.baeldung.com/hibernate-named-query) diff --git a/persistence-modules/hibernate-queries/pom.xml b/persistence-modules/hibernate-queries/pom.xml index 20c2da9ea9..f0307a6eaf 100644 --- a/persistence-modules/hibernate-queries/pom.xml +++ b/persistence-modules/hibernate-queries/pom.xml @@ -14,6 +14,38 @@
+ + + org.springframework + spring-context + ${org.springframework.version} + + + org.springframework.data + spring-data-jpa + ${org.springframework.data.version} + + + org.apache.tomcat + tomcat-dbcp + ${tomcat-dbcp.version} + + + + + + com.google.guava + guava + ${guava.version} + + + + org.springframework + spring-test + ${org.springframework.version} + test + + org.hibernate hibernate-core @@ -49,9 +81,34 @@ jmh-generator-annprocess ${jmh-generator.version} - + + + com.sun.xml.bind + jaxb-core + ${com.sun.xml.version} + + + javax.xml.bind + jaxb-api + ${javax.xml.bind.version} + + + com.sun.xml.bind + jaxb-impl + ${com.sun.xml.version} + + + + 5.0.2.RELEASE + 1.10.6.RELEASE + + 5.2.10.Final + 9.0.0.M26 + 2.3.4 + 2.3.0.1 + 2.3.1 6.0.6 2.2.3 diff --git a/persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/PersistenceConfig.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/PersistenceConfig.java similarity index 100% rename from persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/PersistenceConfig.java rename to persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/PersistenceConfig.java diff --git a/persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/model/Item.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/model/Item.java similarity index 100% rename from persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/model/Item.java rename to persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/model/Item.java diff --git a/persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java similarity index 100% rename from persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java rename to persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java diff --git a/persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java similarity index 100% rename from persistence-modules/hibernate-queries-2/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java rename to persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java diff --git a/persistence-modules/hibernate-queries-2/src/main/resources/import-db.sql b/persistence-modules/hibernate-queries/src/main/resources/import-db.sql similarity index 100% rename from persistence-modules/hibernate-queries-2/src/main/resources/import-db.sql rename to persistence-modules/hibernate-queries/src/main/resources/import-db.sql diff --git a/persistence-modules/hibernate-queries/src/main/resources/logback.xml b/persistence-modules/hibernate-queries/src/main/resources/logback.xml index 7d900d8ea8..612296c6ce 100644 --- a/persistence-modules/hibernate-queries/src/main/resources/logback.xml +++ b/persistence-modules/hibernate-queries/src/main/resources/logback.xml @@ -7,6 +7,12 @@ + + + + + + diff --git a/persistence-modules/hibernate-queries-2/src/main/resources/persistence-h2.properties b/persistence-modules/hibernate-queries/src/main/resources/persistence-h2.properties similarity index 100% rename from persistence-modules/hibernate-queries-2/src/main/resources/persistence-h2.properties rename to persistence-modules/hibernate-queries/src/main/resources/persistence-h2.properties diff --git a/persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/SpringContextTest.java similarity index 100% rename from persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/SpringContextTest.java rename to persistence-modules/hibernate-queries/src/test/java/com/baeldung/SpringContextTest.java diff --git a/persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java similarity index 100% rename from persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java rename to persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java diff --git a/persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java similarity index 100% rename from persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java rename to persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java diff --git a/persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java similarity index 100% rename from persistence-modules/hibernate-queries-2/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java rename to persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java diff --git a/persistence-modules/hibernate-queries-2/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml b/persistence-modules/hibernate-queries/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml similarity index 100% rename from persistence-modules/hibernate-queries-2/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml rename to persistence-modules/hibernate-queries/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml diff --git a/persistence-modules/hibernate-queries-2/src/test/resources/criteria.cfg.xml b/persistence-modules/hibernate-queries/src/test/resources/criteria.cfg.xml similarity index 100% rename from persistence-modules/hibernate-queries-2/src/test/resources/criteria.cfg.xml rename to persistence-modules/hibernate-queries/src/test/resources/criteria.cfg.xml diff --git a/persistence-modules/hibernate-queries-2/src/test/resources/import-db.sql b/persistence-modules/hibernate-queries/src/test/resources/import-db.sql similarity index 100% rename from persistence-modules/hibernate-queries-2/src/test/resources/import-db.sql rename to persistence-modules/hibernate-queries/src/test/resources/import-db.sql From 64bc644d554db1863cbf97e83498fc96d00c9dcb Mon Sep 17 00:00:00 2001 From: sharifi Date: Sat, 12 Mar 2022 09:49:18 +0330 Subject: [PATCH 121/249] bael-4197: move source code to spring-boot-testing-2 module --- .../com/baeldung/xmlapplicationcontext/XmlBeanApplication.java | 0 .../java/com/baeldung/xmlapplicationcontext/domain/Employee.java | 0 .../baeldung/xmlapplicationcontext/service/EmployeeService.java | 0 .../xmlapplicationcontext/service/EmployeeServiceImpl.java | 0 .../xmlapplicationcontext/service/EmployeeServiceTestImpl.java | 0 .../src/main/resources/application-context.xml | 0 .../src/main/webapp/WEB-INF/application-context.xml | 0 .../EmployeeServiceAppContextIntegrationTest.java | 0 .../EmployeeServiceTestContextIntegrationTest.java | 0 .../src/test/resources/test-context.xml | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename spring-boot-modules/{spring-boot-testing => spring-boot-testing-2}/src/main/java/com/baeldung/xmlapplicationcontext/XmlBeanApplication.java (100%) rename spring-boot-modules/{spring-boot-testing => spring-boot-testing-2}/src/main/java/com/baeldung/xmlapplicationcontext/domain/Employee.java (100%) rename spring-boot-modules/{spring-boot-testing => spring-boot-testing-2}/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeService.java (100%) rename spring-boot-modules/{spring-boot-testing => spring-boot-testing-2}/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeServiceImpl.java (100%) rename spring-boot-modules/{spring-boot-testing => spring-boot-testing-2}/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeServiceTestImpl.java (100%) rename spring-boot-modules/{spring-boot-testing => spring-boot-testing-2}/src/main/resources/application-context.xml (100%) rename spring-boot-modules/{spring-boot-testing => spring-boot-testing-2}/src/main/webapp/WEB-INF/application-context.xml (100%) rename spring-boot-modules/{spring-boot-testing => spring-boot-testing-2}/src/test/java/com/baeldung/xmlapplicationcontext/EmployeeServiceAppContextIntegrationTest.java (100%) rename spring-boot-modules/{spring-boot-testing => spring-boot-testing-2}/src/test/java/com/baeldung/xmlapplicationcontext/EmployeeServiceTestContextIntegrationTest.java (100%) rename spring-boot-modules/{spring-boot-testing => spring-boot-testing-2}/src/test/resources/test-context.xml (100%) diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/xmlapplicationcontext/XmlBeanApplication.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/xmlapplicationcontext/XmlBeanApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/xmlapplicationcontext/XmlBeanApplication.java rename to spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/xmlapplicationcontext/XmlBeanApplication.java diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/xmlapplicationcontext/domain/Employee.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/xmlapplicationcontext/domain/Employee.java similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/xmlapplicationcontext/domain/Employee.java rename to spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/xmlapplicationcontext/domain/Employee.java diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeService.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeService.java similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeService.java rename to spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeService.java diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeServiceImpl.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeServiceImpl.java similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeServiceImpl.java rename to spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeServiceImpl.java diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeServiceTestImpl.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeServiceTestImpl.java similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeServiceTestImpl.java rename to spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/xmlapplicationcontext/service/EmployeeServiceTestImpl.java diff --git a/spring-boot-modules/spring-boot-testing/src/main/resources/application-context.xml b/spring-boot-modules/spring-boot-testing-2/src/main/resources/application-context.xml similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/main/resources/application-context.xml rename to spring-boot-modules/spring-boot-testing-2/src/main/resources/application-context.xml diff --git a/spring-boot-modules/spring-boot-testing/src/main/webapp/WEB-INF/application-context.xml b/spring-boot-modules/spring-boot-testing-2/src/main/webapp/WEB-INF/application-context.xml similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/main/webapp/WEB-INF/application-context.xml rename to spring-boot-modules/spring-boot-testing-2/src/main/webapp/WEB-INF/application-context.xml diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/xmlapplicationcontext/EmployeeServiceAppContextIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/xmlapplicationcontext/EmployeeServiceAppContextIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/xmlapplicationcontext/EmployeeServiceAppContextIntegrationTest.java rename to spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/xmlapplicationcontext/EmployeeServiceAppContextIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/xmlapplicationcontext/EmployeeServiceTestContextIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/xmlapplicationcontext/EmployeeServiceTestContextIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/xmlapplicationcontext/EmployeeServiceTestContextIntegrationTest.java rename to spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/xmlapplicationcontext/EmployeeServiceTestContextIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-testing/src/test/resources/test-context.xml b/spring-boot-modules/spring-boot-testing-2/src/test/resources/test-context.xml similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/test/resources/test-context.xml rename to spring-boot-modules/spring-boot-testing-2/src/test/resources/test-context.xml From 612dc0be7c8c8a1ba46c565a8ef114f151ed74d3 Mon Sep 17 00:00:00 2001 From: Gaetano Piazzolla Date: Sat, 12 Mar 2022 19:21:34 +0100 Subject: [PATCH 122/249] BAEL-5358 - Case Insensitive Sorting in MongoDB (#11815) * [BAEL-5358] - MongoDB Case Insensitive Ordering. * [BAEL-5358] - removed comment, indent * [BAEL-5358] - using junit5 and testcontainers * [BAEL-5358] - fixed issues for PR * [BAEL-5358] - removed method-> inline --- persistence-modules/java-mongodb/pom.xml | 12 ++ .../CaseInsensitiveOrderingLiveTest.java | 108 ++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 persistence-modules/java-mongodb/src/test/java/com/baeldung/ordering/caseinsensitive/CaseInsensitiveOrderingLiveTest.java diff --git a/persistence-modules/java-mongodb/pom.xml b/persistence-modules/java-mongodb/pom.xml index 03229e72bd..88f0d18a5b 100644 --- a/persistence-modules/java-mongodb/pom.xml +++ b/persistence-modules/java-mongodb/pom.xml @@ -30,6 +30,18 @@ core ${morphia.version} + + org.testcontainers + mongodb + 1.16.3 + test + + + org.testcontainers + junit-jupiter + 1.16.3 + test + diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/ordering/caseinsensitive/CaseInsensitiveOrderingLiveTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/ordering/caseinsensitive/CaseInsensitiveOrderingLiveTest.java new file mode 100644 index 0000000000..ec2c332018 --- /dev/null +++ b/persistence-modules/java-mongodb/src/test/java/com/baeldung/ordering/caseinsensitive/CaseInsensitiveOrderingLiveTest.java @@ -0,0 +1,108 @@ +package com.baeldung.ordering.caseinsensitive; + +import com.mongodb.MongoClient; +import com.mongodb.client.*; +import com.mongodb.client.model.Collation; +import com.mongodb.client.model.Projections; +import com.mongodb.client.model.Sorts; +import org.bson.Document; +import org.bson.conversions.Bson; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.MongoDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static com.mongodb.client.model.Aggregates.project; +import static com.mongodb.client.model.Aggregates.sort; +import static com.mongodb.client.model.Sorts.ascending; +import static org.junit.Assert.assertEquals; + +@Testcontainers +class CaseInsensitiveOrderingLiveTest { + + private static MongoCollection userCollections; + + @Container + private static final MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10")); + + @BeforeAll + private static void setup() { + + MongoClient mongoClient = new MongoClient(mongoDBContainer.getContainerIpAddress(), mongoDBContainer.getMappedPort(27017)); + MongoDatabase database = mongoClient.getDatabase("test"); + userCollections = database.getCollection("users"); + + List list = new ArrayList<>(); + list.add(Document.parse("{'name': 'ben', surname: 'ThisField' }")); + list.add(Document.parse("{'name': 'aen', surname: 'Does' }")); + list.add(Document.parse("{'name': 'Ben', surname: 'Not' }")); + list.add(Document.parse("{'name': 'cen', surname: 'Matter' }")); + list.add(Document.parse("{'name': 'Aen', surname: 'Really' }")); + list.add(Document.parse("{'name': 'Cen', surname: 'TrustMe' }")); + + userCollections.insertMany(list); + } + + @Test + void givenMongoCollection_whenUsingFindWithSort_caseIsConsideredByDefault() { + FindIterable nameDoc = userCollections.find().sort(ascending("name")); + MongoCursor cursor = nameDoc.cursor(); + + List expectedNamesOrdering = Arrays.asList("Aen", "Ben", "Cen", "aen", "ben", "cen"); + List actualNamesOrdering = new ArrayList<>(); + while (cursor.hasNext()) { + Document document = cursor.next(); + actualNamesOrdering.add(document.get("name").toString()); + } + + assertEquals(expectedNamesOrdering, actualNamesOrdering); + } + + @Test + void givenMongoCollection_whenUsingFindWithSortAndCollation_caseIsNotConsidered() { + FindIterable nameDoc = userCollections.find().sort(ascending("name")) + .collation(Collation.builder().locale("en").build()); + MongoCursor cursor = nameDoc.cursor(); + List expectedNamesOrdering = Arrays.asList("aen", "Aen", "ben", "Ben", "cen", "Cen"); + List actualNamesOrdering = new ArrayList<>(); + while (cursor.hasNext()) { + Document document = cursor.next(); + actualNamesOrdering.add(document.get("name").toString()); + } + + assertEquals(expectedNamesOrdering, actualNamesOrdering); + + } + + @Test + void givenMongoCollection_whenUsingFindWithSortAndAggregate_caseIsNotConsidered() { + + Bson projectBson = project( + Projections.fields( + Projections.include("name", "surname"), + Projections.computed("lowerName", Projections.computed("$toLower", "$name")))); + + AggregateIterable nameDoc = userCollections.aggregate( + Arrays.asList(projectBson, + sort(Sorts.ascending("lowerName")))); + + MongoCursor cursor = nameDoc.cursor(); + + List expectedNamesOrdering = Arrays.asList("aen", "Aen", "ben", "Ben", "cen", "Cen"); + List actualNamesOrdering = new ArrayList<>(); + while (cursor.hasNext()) { + Document document = cursor.next(); + actualNamesOrdering.add(document.get("name").toString()); + } + + assertEquals(expectedNamesOrdering, actualNamesOrdering); + } + + +} From d30c353d35339d74b9b883045e21728435368266 Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Sat, 12 Mar 2022 20:09:18 +0100 Subject: [PATCH 123/249] pretty-print xml in java (#11899) * pretty-print xml in java * simplified pom.xml --- pom.xml | 1 + xml-2/.gitignore | 1 + xml-2/README.md | 5 + xml-2/pom.xml | 50 ++++++++++ .../xml/prettyprint/XmlPrettyPrinter.java | 91 +++++++++++++++++++ xml-2/src/main/resources/logback.xml | 13 +++ xml-2/src/main/resources/xml/emails.xml | 4 + xml-2/src/main/resources/xml/prettyprint.xsl | 11 +++ 8 files changed, 176 insertions(+) create mode 100644 xml-2/.gitignore create mode 100644 xml-2/README.md create mode 100644 xml-2/pom.xml create mode 100644 xml-2/src/main/java/com/baeldung/xml/prettyprint/XmlPrettyPrinter.java create mode 100644 xml-2/src/main/resources/logback.xml create mode 100644 xml-2/src/main/resources/xml/emails.xml create mode 100644 xml-2/src/main/resources/xml/prettyprint.xsl diff --git a/pom.xml b/pom.xml index a6202230d4..daaf9db6d2 100644 --- a/pom.xml +++ b/pom.xml @@ -1206,6 +1206,7 @@ wicket wildfly xml + xml-2 xstream diff --git a/xml-2/.gitignore b/xml-2/.gitignore new file mode 100644 index 0000000000..68b918851c --- /dev/null +++ b/xml-2/.gitignore @@ -0,0 +1 @@ +xml/.idea diff --git a/xml-2/README.md b/xml-2/README.md new file mode 100644 index 0000000000..e3c6ed6443 --- /dev/null +++ b/xml-2/README.md @@ -0,0 +1,5 @@ +## XML + +This module contains articles about eXtensible Markup Language (XML) + +### Relevant Articles: \ No newline at end of file diff --git a/xml-2/pom.xml b/xml-2/pom.xml new file mode 100644 index 0000000000..025ad682ad --- /dev/null +++ b/xml-2/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + xml-2 + 0.1-SNAPSHOT + xml-2 + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + org.dom4j + dom4j + ${dom4j.version} + + + + + xml-2 + + + src/main/resources + true + + + + + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + + 2.1.3 + + + \ No newline at end of file diff --git a/xml-2/src/main/java/com/baeldung/xml/prettyprint/XmlPrettyPrinter.java b/xml-2/src/main/java/com/baeldung/xml/prettyprint/XmlPrettyPrinter.java new file mode 100644 index 0000000000..85fd751325 --- /dev/null +++ b/xml-2/src/main/java/com/baeldung/xml/prettyprint/XmlPrettyPrinter.java @@ -0,0 +1,91 @@ +package com.baeldung.xml.prettyprint; + +import org.dom4j.DocumentHelper; +import org.dom4j.io.OutputFormat; +import org.dom4j.io.XMLWriter; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import java.io.*; + +public class XmlPrettyPrinter { + + public static String prettyPrintByTransformer(String xmlString, int indent, boolean ignoreDeclaration) { + + try { + final InputSource src = new InputSource(new StringReader(xmlString)); + final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(src); + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + transformerFactory.setAttribute("indent-number", indent); + Transformer transformer = transformerFactory.newTransformer(new StreamSource(new StringReader(readPrettyPrintXslt()))); + // Using the default transformer will create empty lines in Java9+ +// Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, ignoreDeclaration ? "yes" : "no"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + // Alternatively, we can set indent-size on the transformer object + // transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(indent)); + Writer out = new StringWriter(); + transformer.transform(new DOMSource(document), new StreamResult(out)); + return out.toString(); + } catch (Exception e) { + throw new RuntimeException("Error occurs when pretty-printing xml:\n" + xmlString, e); + } + } + + + public static String prettyPrintByDom4j(String xmlString, int indent, boolean skipDeclaration) { + try { + final OutputFormat format = OutputFormat.createPrettyPrint(); + format.setEncoding("UTF-8"); + format.setIndentSize(indent); + format.setSuppressDeclaration(skipDeclaration); + + final org.dom4j.Document document = DocumentHelper.parseText(xmlString); + final StringWriter sw = new StringWriter(); + final XMLWriter writer = new XMLWriter(sw, format); + writer.write(document); + return sw.toString(); + } catch (Exception e) { + throw new RuntimeException("Error occurs when pretty-printing xml:\n" + xmlString, e); + } + } + + public static void main(String[] args) throws IOException { + InputStream inputStream = XmlPrettyPrinter.class.getResourceAsStream("/xml/emails.xml"); + String xmlString = readFromInputStream(inputStream); + System.out.println("Pretty printing by Transformer"); + System.out.println("============================================="); + System.out.println(prettyPrintByTransformer(xmlString, 2, true)); + System.out.println("============================================="); + System.out.println("Pretty printing by Dom4j"); + System.out.println("============================================="); + System.out.println(prettyPrintByDom4j(xmlString, 8, false)); + System.out.println("============================================="); + } + + + private static String readPrettyPrintXslt() throws IOException { + InputStream inputStream = XmlPrettyPrinter.class.getResourceAsStream("/xml/prettyprint.xsl"); + return readFromInputStream(inputStream); + } + + private static String readFromInputStream(InputStream inputStream) throws IOException { + StringBuilder resultStringBuilder = new StringBuilder(); + try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { + String line; + while ((line = br.readLine()) != null) { + resultStringBuilder.append(line).append("\n"); + } + } + return resultStringBuilder.toString(); + } +} diff --git a/xml-2/src/main/resources/logback.xml b/xml-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/xml-2/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/xml-2/src/main/resources/xml/emails.xml b/xml-2/src/main/resources/xml/emails.xml new file mode 100644 index 0000000000..03338a28fc --- /dev/null +++ b/xml-2/src/main/resources/xml/emails.xml @@ -0,0 +1,4 @@ + Kai Amanda +I am flying to you +Jerry Tom Hey Tom, catch me if you can! + \ No newline at end of file diff --git a/xml-2/src/main/resources/xml/prettyprint.xsl b/xml-2/src/main/resources/xml/prettyprint.xsl new file mode 100644 index 0000000000..3941269f40 --- /dev/null +++ b/xml-2/src/main/resources/xml/prettyprint.xsl @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file From b8176a265a2bf1bd7f32ee34a3059347409d86d0 Mon Sep 17 00:00:00 2001 From: sampadawagde Date: Sun, 13 Mar 2022 14:48:44 +0530 Subject: [PATCH 124/249] JAVA-10138 - Fix formatting of POMs --- apache-olingo/pom.xml | 2 +- .../core-java-9-new-features/pom.xml | 44 +++++----- .../core-java-concurrency-basic-3/pom.xml | 2 +- .../core-java-date-operations-1/pom.xml | 1 - core-java-modules/core-java-jar/pom.xml | 2 +- core-java-modules/core-java-jvm/pom.xml | 15 ++-- .../core-java-serialization/pom.xml | 1 - .../core-java-string-algorithms-3/pom.xml | 1 + core-java-modules/core-java/pom.xml | 1 - core-java-modules/pom.xml | 2 +- ddd-modules/infrastructure/pom.xml | 4 +- ddd-modules/mainapp/pom.xml | 3 +- ddd-modules/ordercontext/pom.xml | 4 +- ddd-modules/pom.xml | 8 +- ddd-modules/sharedkernel/pom.xml | 4 +- ddd-modules/shippingcontext/pom.xml | 4 +- geotools/pom.xml | 16 ++-- graphql/graphql-dgs/pom.xml | 6 +- httpclient-2/pom.xml | 5 +- java-collections-maps-3/pom.xml | 1 - javax-servlets-2/pom.xml | 3 +- javaxval/pom.xml | 38 ++------- jta/pom.xml | 2 +- ksqldb/pom.xml | 1 - libraries-concurrency/pom.xml | 6 +- lombok-2/pom.xml | 2 +- lombok/pom.xml | 15 +--- .../maven-classifier-example-consumer/pom.xml | 38 ++++----- .../maven-classifier-example-provider/pom.xml | 81 ++++++++++--------- maven-modules/maven-classifier/pom.xml | 7 +- maven-modules/maven-generate-war/pom.xml | 2 +- .../maven-simple/parent-project/core/pom.xml | 2 +- .../maven-simple/parent-project/pom.xml | 3 +- .../parent-project/service/pom.xml | 2 +- .../parent-project/webapp/pom.xml | 2 +- metrics/pom.xml | 2 +- netty/pom.xml | 11 ++- patterns/enterprise-patterns/pom.xml | 40 ++++----- .../hibernate-mapping-2/pom.xml | 32 ++++---- persistence-modules/java-cassandra/pom.xml | 2 +- persistence-modules/spring-data-jdbc/pom.xml | 2 +- .../spring-data-jpa-query-3/pom.xml | 2 +- .../spring-hibernate-5/pom.xml | 32 ++++---- .../pom.xml | 2 +- spring-5-data-reactive/pom.xml | 2 +- spring-5-reactive-3/pom.xml | 1 + spring-activiti/pom.xml | 2 +- .../spring-boot-multiple-datasources/pom.xml | 6 +- .../spring-boot-swagger-keycloak/pom.xml | 2 +- .../spring-boot-swagger/pom.xml | 2 +- .../zookeeper-config/pom.xml | 2 +- .../pom.xml | 12 +-- spring-cloud/spring-cloud-eureka/pom.xml | 16 ++-- spring-cloud/spring-cloud-functions/pom.xml | 2 +- spring-cloud/spring-cloud-gateway/pom.xml | 43 +++++----- spring-cloud/spring-cloud-kubernetes/pom.xml | 18 ++--- .../spring-cloud-load-balancer/pom.xml | 6 +- .../spring-cloud-loadbalancer-client/pom.xml | 36 +++++---- .../spring-cloud-loadbalancer-server/pom.xml | 15 ++-- .../eureka-client/pom.xml | 2 +- .../eureka-server/pom.xml | 2 +- .../zuul-server/pom.xml | 4 +- .../spring-zuul-rate-limiting/pom.xml | 2 +- spring-ejb/ejb-beans/pom.xml | 1 - spring-reactive/pom.xml | 7 +- .../spring-5-security-oauth/pom.xml | 7 +- .../spring-security-legacy-oidc/pom.xml | 6 +- .../spring-security-web-boot-1/pom.xml | 1 - .../spring-security-web-boot-3/pom.xml | 5 +- spring-web-modules/pom.xml | 2 +- .../spring-mvc-basics-5/pom.xml | 2 +- testing-modules/cucumber/pom.xml | 1 - testing-modules/testng_command_line/pom.xml | 7 +- 73 files changed, 308 insertions(+), 361 deletions(-) diff --git a/apache-olingo/pom.xml b/apache-olingo/pom.xml index 5de0dfd511..25aab0ec97 100644 --- a/apache-olingo/pom.xml +++ b/apache-olingo/pom.xml @@ -83,4 +83,4 @@ 2.0.11 - + \ No newline at end of file diff --git a/core-java-modules/core-java-9-new-features/pom.xml b/core-java-modules/core-java-9-new-features/pom.xml index ce90a0f04a..78ffaff010 100644 --- a/core-java-modules/core-java-9-new-features/pom.xml +++ b/core-java-modules/core-java-9-new-features/pom.xml @@ -34,6 +34,28 @@ + + core-java-9-new-features + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + + + apache.snapshots + https://repository.apache.org/snapshots/ + + + incubator-features @@ -126,28 +148,6 @@ - - core-java-9-new-features - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${maven.compiler.source} - ${maven.compiler.target} - - - - - - - - apache.snapshots - https://repository.apache.org/snapshots/ - - - 3.0.0 4.0.2 diff --git a/core-java-modules/core-java-concurrency-basic-3/pom.xml b/core-java-modules/core-java-concurrency-basic-3/pom.xml index 20615e3250..7771d1200c 100644 --- a/core-java-modules/core-java-concurrency-basic-3/pom.xml +++ b/core-java-modules/core-java-concurrency-basic-3/pom.xml @@ -24,4 +24,4 @@ - + \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations-1/pom.xml b/core-java-modules/core-java-date-operations-1/pom.xml index ea9f94fa56..c5d46723d8 100644 --- a/core-java-modules/core-java-date-operations-1/pom.xml +++ b/core-java-modules/core-java-date-operations-1/pom.xml @@ -25,7 +25,6 @@ commons-lang3 ${commons-lang3.version} - com.darwinsys hirondelle-date4j diff --git a/core-java-modules/core-java-jar/pom.xml b/core-java-modules/core-java-jar/pom.xml index 714a370287..19da9b8a56 100644 --- a/core-java-modules/core-java-jar/pom.xml +++ b/core-java-modules/core-java-jar/pom.xml @@ -259,7 +259,7 @@ - + diff --git a/core-java-modules/core-java-jvm/pom.xml b/core-java-modules/core-java-jvm/pom.xml index e4c0f949c2..d26c72323f 100644 --- a/core-java-modules/core-java-jvm/pom.xml +++ b/core-java-modules/core-java-jvm/pom.xml @@ -64,13 +64,6 @@ - - 3.27.0-GA - 1.8.0 - 0.10 - 8.0.1 - 6.5.0 - @@ -181,4 +174,12 @@ + + 3.27.0-GA + 1.8.0 + 0.10 + 8.0.1 + 6.5.0 + + \ No newline at end of file diff --git a/core-java-modules/core-java-serialization/pom.xml b/core-java-modules/core-java-serialization/pom.xml index 315ed8cdad..c82ae9d1d6 100644 --- a/core-java-modules/core-java-serialization/pom.xml +++ b/core-java-modules/core-java-serialization/pom.xml @@ -64,7 +64,6 @@ true - org.apache.maven.plugins diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml index dc8ad3851d..147ea22375 100644 --- a/core-java-modules/core-java-string-algorithms-3/pom.xml +++ b/core-java-modules/core-java-string-algorithms-3/pom.xml @@ -54,4 +54,5 @@ 1.7 3.12.0 + \ No newline at end of file diff --git a/core-java-modules/core-java/pom.xml b/core-java-modules/core-java/pom.xml index 188c6a6f63..bb19b525d0 100644 --- a/core-java-modules/core-java/pom.xml +++ b/core-java-modules/core-java/pom.xml @@ -69,7 +69,6 @@ true - org.apache.maven.plugins diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 60319b4de4..2f684beea0 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -137,4 +137,4 @@
- + \ No newline at end of file diff --git a/ddd-modules/infrastructure/pom.xml b/ddd-modules/infrastructure/pom.xml index abf90935c3..232e5ff4b4 100644 --- a/ddd-modules/infrastructure/pom.xml +++ b/ddd-modules/infrastructure/pom.xml @@ -1,13 +1,11 @@ - 4.0.0 com.baeldung.dddmodules.infrastructure infrastructure 1.0 - jar diff --git a/ddd-modules/mainapp/pom.xml b/ddd-modules/mainapp/pom.xml index 6b913df979..a2d3b8f3ea 100644 --- a/ddd-modules/mainapp/pom.xml +++ b/ddd-modules/mainapp/pom.xml @@ -1,6 +1,5 @@ - 4.0.0 diff --git a/ddd-modules/ordercontext/pom.xml b/ddd-modules/ordercontext/pom.xml index 8dee3a5148..eaf44badd3 100644 --- a/ddd-modules/ordercontext/pom.xml +++ b/ddd-modules/ordercontext/pom.xml @@ -1,6 +1,5 @@ - 4.0.0 @@ -13,7 +12,6 @@ com.baeldung.dddmodules ddd-modules 1.0 - ../ diff --git a/ddd-modules/pom.xml b/ddd-modules/pom.xml index 134a9d0566..d2932ee515 100644 --- a/ddd-modules/pom.xml +++ b/ddd-modules/pom.xml @@ -1,6 +1,5 @@ - 4.0.0 @@ -14,7 +13,6 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ @@ -70,10 +68,8 @@ 9 9 - 3.8.1 - 1.0 - + \ No newline at end of file diff --git a/ddd-modules/sharedkernel/pom.xml b/ddd-modules/sharedkernel/pom.xml index 1afddf1e22..3966e1c26e 100644 --- a/ddd-modules/sharedkernel/pom.xml +++ b/ddd-modules/sharedkernel/pom.xml @@ -1,6 +1,5 @@ - 4.0.0 @@ -13,7 +12,6 @@ com.baeldung.dddmodules ddd-modules 1.0 - ../ diff --git a/ddd-modules/shippingcontext/pom.xml b/ddd-modules/shippingcontext/pom.xml index 25b5882ef1..a6e6167b69 100644 --- a/ddd-modules/shippingcontext/pom.xml +++ b/ddd-modules/shippingcontext/pom.xml @@ -1,6 +1,5 @@ - 4.0.0 @@ -13,7 +12,6 @@ com.baeldung.dddmodules ddd-modules 1.0 - ../ diff --git a/geotools/pom.xml b/geotools/pom.xml index b9a6a7c91f..05cae922a4 100644 --- a/geotools/pom.xml +++ b/geotools/pom.xml @@ -15,6 +15,14 @@ 1.0.0-SNAPSHOT + + + osgeo-release + OSGeo Repository + https://repo.osgeo.org/repository/release/ + + + org.geotools @@ -33,14 +41,6 @@ - - - osgeo-release - OSGeo Repository - https://repo.osgeo.org/repository/release/ - - - 15.2 15.2 diff --git a/graphql/graphql-dgs/pom.xml b/graphql/graphql-dgs/pom.xml index 1dc3630276..6165ae839f 100644 --- a/graphql/graphql-dgs/pom.xml +++ b/graphql/graphql-dgs/pom.xml @@ -33,26 +33,22 @@ spring-boot-starter 2.6.2 - org.springframework.boot spring-boot-starter-test 2.6.2 test - com.netflix.graphql.dgs.codegen graphql-dgs-codegen-client-core 5.1.14 - org.springframework.boot spring-boot-starter-web 2.6.2 - com.netflix.graphql.dgs graphql-dgs-spring-boot-starter @@ -88,4 +84,4 @@ - + \ No newline at end of file diff --git a/httpclient-2/pom.xml b/httpclient-2/pom.xml index 85fc1d87e7..287ff27e35 100644 --- a/httpclient-2/pom.xml +++ b/httpclient-2/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 httpclient-2 0.1-SNAPSHOT diff --git a/java-collections-maps-3/pom.xml b/java-collections-maps-3/pom.xml index a54061404d..729b357b76 100644 --- a/java-collections-maps-3/pom.xml +++ b/java-collections-maps-3/pom.xml @@ -22,7 +22,6 @@ junit-jupiter-api 5.8.1 - org.springframework spring-core diff --git a/javax-servlets-2/pom.xml b/javax-servlets-2/pom.xml index 34c00c3d05..5d8310f2b2 100644 --- a/javax-servlets-2/pom.xml +++ b/javax-servlets-2/pom.xml @@ -57,4 +57,5 @@ 4.5.13 4.0.1 - + + \ No newline at end of file diff --git a/javaxval/pom.xml b/javaxval/pom.xml index 4131ddeb97..e6ecee6cfb 100644 --- a/javaxval/pom.xml +++ b/javaxval/pom.xml @@ -37,35 +37,13 @@ - + 6.0.13.Final @@ -77,4 +55,4 @@ 5.0.2.RELEASE - + \ No newline at end of file diff --git a/jta/pom.xml b/jta/pom.xml index e62c480c81..906d28a7ea 100644 --- a/jta/pom.xml +++ b/jta/pom.xml @@ -15,7 +15,7 @@ 0.0.1-SNAPSHOT ../parent-boot-2 - + diff --git a/ksqldb/pom.xml b/ksqldb/pom.xml index ee4906090f..e55398d635 100644 --- a/ksqldb/pom.xml +++ b/ksqldb/pom.xml @@ -11,7 +11,6 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../pom.xml diff --git a/libraries-concurrency/pom.xml b/libraries-concurrency/pom.xml index d8f48a1959..eb581ce3a0 100644 --- a/libraries-concurrency/pom.xml +++ b/libraries-concurrency/pom.xml @@ -1,7 +1,7 @@ + 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"> 4.0.0 libraries-concurrency libraries-concurrency @@ -78,5 +78,5 @@ 0.8.0 - + \ No newline at end of file diff --git a/lombok-2/pom.xml b/lombok-2/pom.xml index 3c67e959a4..bde328444e 100644 --- a/lombok-2/pom.xml +++ b/lombok-2/pom.xml @@ -22,4 +22,4 @@ - + \ No newline at end of file diff --git a/lombok/pom.xml b/lombok/pom.xml index d4f89ab4f2..24a04783d1 100644 --- a/lombok/pom.xml +++ b/lombok/pom.xml @@ -62,18 +62,9 @@ false - + diff --git a/maven-modules/maven-classifier/maven-classifier-example-consumer/pom.xml b/maven-modules/maven-classifier/maven-classifier-example-consumer/pom.xml index cbf046ed5a..b280f21b4b 100644 --- a/maven-modules/maven-classifier/maven-classifier-example-consumer/pom.xml +++ b/maven-modules/maven-classifier/maven-classifier-example-consumer/pom.xml @@ -1,22 +1,16 @@ + 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"> + 4.0.0 + maven-classifier-example-consumer + maven-classifier com.baeldung 0.0.1-SNAPSHOT - 4.0.0 - - maven-classifier-example-consumer - - - 8 - 8 - - com.baeldung @@ -29,13 +23,14 @@ 0.0.1-SNAPSHOT arbitrary - - - - - - - + + + + + + + com.baeldung maven-classifier-example-provider @@ -50,4 +45,9 @@ - + + 8 + 8 + + + \ No newline at end of file diff --git a/maven-modules/maven-classifier/maven-classifier-example-provider/pom.xml b/maven-modules/maven-classifier/maven-classifier-example-provider/pom.xml index 12cb4fa1a2..111996c995 100644 --- a/maven-modules/maven-classifier/maven-classifier-example-provider/pom.xml +++ b/maven-modules/maven-classifier/maven-classifier-example-provider/pom.xml @@ -1,9 +1,10 @@ - + 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"> 4.0.0 + maven-classifier-example-provider + 0.0.1-SNAPSHOT maven-classifier @@ -11,15 +12,6 @@ 0.0.1-SNAPSHOT - maven-classifier-example-provider - 0.0.1-SNAPSHOT - - - 8 - 8 - - - @@ -39,21 +31,22 @@ true - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -76,18 +69,19 @@ test-jar - - - - - - - - - - - - + + + + + + + + + + + + @@ -119,4 +113,11 @@ - + + + 8 + 8 + + + + \ No newline at end of file diff --git a/maven-modules/maven-classifier/pom.xml b/maven-modules/maven-classifier/pom.xml index 6b75f60893..ba5f248ff6 100644 --- a/maven-modules/maven-classifier/pom.xml +++ b/maven-modules/maven-classifier/pom.xml @@ -1,9 +1,8 @@ + 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"> 4.0.0 - maven-classifier pom 0.0.1-SNAPSHOT @@ -24,4 +23,4 @@ 8 - + \ No newline at end of file diff --git a/maven-modules/maven-generate-war/pom.xml b/maven-modules/maven-generate-war/pom.xml index b388cfdadd..51eb54846c 100644 --- a/maven-modules/maven-generate-war/pom.xml +++ b/maven-modules/maven-generate-war/pom.xml @@ -6,8 +6,8 @@ com.baeldung maven-generate-war 0.0.1-SNAPSHOT - war maven-generate-war + war Spring boot project to demonstrate war file generation diff --git a/maven-modules/maven-simple/parent-project/core/pom.xml b/maven-modules/maven-simple/parent-project/core/pom.xml index ec25c9ace5..963f8edf6c 100644 --- a/maven-modules/maven-simple/parent-project/core/pom.xml +++ b/maven-modules/maven-simple/parent-project/core/pom.xml @@ -13,4 +13,4 @@ 1.0-SNAPSHOT - + \ No newline at end of file diff --git a/maven-modules/maven-simple/parent-project/pom.xml b/maven-modules/maven-simple/parent-project/pom.xml index a68f8e63bc..0b8fbdffab 100644 --- a/maven-modules/maven-simple/parent-project/pom.xml +++ b/maven-modules/maven-simple/parent-project/pom.xml @@ -19,4 +19,5 @@ service webapp - + + \ No newline at end of file diff --git a/maven-modules/maven-simple/parent-project/service/pom.xml b/maven-modules/maven-simple/parent-project/service/pom.xml index 1953ec8638..04cb1151e1 100644 --- a/maven-modules/maven-simple/parent-project/service/pom.xml +++ b/maven-modules/maven-simple/parent-project/service/pom.xml @@ -13,4 +13,4 @@ 1.0-SNAPSHOT - + \ No newline at end of file diff --git a/maven-modules/maven-simple/parent-project/webapp/pom.xml b/maven-modules/maven-simple/parent-project/webapp/pom.xml index bd13c5aeb8..ece8a0dd11 100644 --- a/maven-modules/maven-simple/parent-project/webapp/pom.xml +++ b/maven-modules/maven-simple/parent-project/webapp/pom.xml @@ -13,4 +13,4 @@ 1.0-SNAPSHOT - + \ No newline at end of file diff --git a/metrics/pom.xml b/metrics/pom.xml index abdfb14dc6..37b10ef484 100644 --- a/metrics/pom.xml +++ b/metrics/pom.xml @@ -92,4 +92,4 @@ 1.1.0 - + \ No newline at end of file diff --git a/netty/pom.xml b/netty/pom.xml index 817b1f2e70..c235ec9f4a 100644 --- a/netty/pom.xml +++ b/netty/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 netty 0.0.1-SNAPSHOT @@ -11,20 +12,18 @@ parent-modules 1.0.0-SNAPSHOT - + io.netty netty-all ${netty.version} - - + org.conscrypt conscrypt-openjdk-uber ${conscrypt-openjdk-uber.version} - diff --git a/patterns/enterprise-patterns/pom.xml b/patterns/enterprise-patterns/pom.xml index 999b359170..2228cc9505 100644 --- a/patterns/enterprise-patterns/pom.xml +++ b/patterns/enterprise-patterns/pom.xml @@ -16,6 +16,25 @@ wire-tap + + + + org.apache.camel.springboot + camel-spring-boot-dependencies + ${camel.version} + pom + import + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + + org.apache.camel.springboot @@ -39,25 +58,6 @@ - - - - org.apache.camel.springboot - camel-spring-boot-dependencies - ${camel.version} - pom - import - - - org.apache.logging.log4j - log4j-bom - ${log4j2.version} - import - pom - - - - @@ -70,7 +70,7 @@ 3.7.4 2.2.2.RELEASE - 2.17.1 + 2.17.1 \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping-2/pom.xml b/persistence-modules/hibernate-mapping-2/pom.xml index 10c07c95eb..47b00797bc 100644 --- a/persistence-modules/hibernate-mapping-2/pom.xml +++ b/persistence-modules/hibernate-mapping-2/pom.xml @@ -54,22 +54,22 @@ com.h2database h2 ${h2.version} - - - com.sun.xml.bind - jaxb-core - ${com.sun.xml.version} - - - javax.xml.bind - jaxb-api - ${javax.xml.bind.version} - - - com.sun.xml.bind - jaxb-impl - ${com.sun.xml.version} - + + + com.sun.xml.bind + jaxb-core + ${com.sun.xml.version} + + + javax.xml.bind + jaxb-api + ${javax.xml.bind.version} + + + com.sun.xml.bind + jaxb-impl + ${com.sun.xml.version} + diff --git a/persistence-modules/java-cassandra/pom.xml b/persistence-modules/java-cassandra/pom.xml index b0b98b040a..0dd148e528 100644 --- a/persistence-modules/java-cassandra/pom.xml +++ b/persistence-modules/java-cassandra/pom.xml @@ -77,4 +77,4 @@ 4.1.71.Final - + \ No newline at end of file diff --git a/persistence-modules/spring-data-jdbc/pom.xml b/persistence-modules/spring-data-jdbc/pom.xml index 168b171337..630fe141b3 100644 --- a/persistence-modules/spring-data-jdbc/pom.xml +++ b/persistence-modules/spring-data-jdbc/pom.xml @@ -36,4 +36,4 @@ - + \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-query-3/pom.xml b/persistence-modules/spring-data-jpa-query-3/pom.xml index 66a4486bc8..135d31aaba 100644 --- a/persistence-modules/spring-data-jpa-query-3/pom.xml +++ b/persistence-modules/spring-data-jpa-query-3/pom.xml @@ -29,4 +29,4 @@ - + \ No newline at end of file diff --git a/persistence-modules/spring-hibernate-5/pom.xml b/persistence-modules/spring-hibernate-5/pom.xml index ba18c5a221..3f5d00733d 100644 --- a/persistence-modules/spring-hibernate-5/pom.xml +++ b/persistence-modules/spring-hibernate-5/pom.xml @@ -107,22 +107,22 @@ com.h2database h2 ${h2.version} - - - com.sun.xml.bind - jaxb-core - ${com.sun.xml.version} - - - javax.xml.bind - jaxb-api - ${javax.xml.bind.version} - - - com.sun.xml.bind - jaxb-impl - ${com.sun.xml.version} - + + + com.sun.xml.bind + jaxb-core + ${com.sun.xml.version} + + + javax.xml.bind + jaxb-api + ${javax.xml.bind.version} + + + com.sun.xml.bind + jaxb-impl + ${com.sun.xml.version} + diff --git a/quarkus-jandex/hello-sender-application-properties/pom.xml b/quarkus-jandex/hello-sender-application-properties/pom.xml index f63bb9be81..6658123bee 100644 --- a/quarkus-jandex/hello-sender-application-properties/pom.xml +++ b/quarkus-jandex/hello-sender-application-properties/pom.xml @@ -23,4 +23,4 @@ - + \ No newline at end of file diff --git a/spring-5-data-reactive/pom.xml b/spring-5-data-reactive/pom.xml index 023eda856b..24971c0289 100644 --- a/spring-5-data-reactive/pom.xml +++ b/spring-5-data-reactive/pom.xml @@ -13,7 +13,7 @@ 0.0.1-SNAPSHOT ../parent-boot-2 - + diff --git a/spring-5-reactive-3/pom.xml b/spring-5-reactive-3/pom.xml index 89af34732f..fea72cc736 100644 --- a/spring-5-reactive-3/pom.xml +++ b/spring-5-reactive-3/pom.xml @@ -41,4 +41,5 @@ 1.0.1.RELEASE + \ No newline at end of file diff --git a/spring-activiti/pom.xml b/spring-activiti/pom.xml index 2ede13a152..898f88285b 100644 --- a/spring-activiti/pom.xml +++ b/spring-activiti/pom.xml @@ -16,7 +16,7 @@ 0.0.1-SNAPSHOT ../parent-boot-1 - + diff --git a/spring-boot-modules/spring-boot-multiple-datasources/pom.xml b/spring-boot-modules/spring-boot-multiple-datasources/pom.xml index d66095bc2c..9355de8a36 100644 --- a/spring-boot-modules/spring-boot-multiple-datasources/pom.xml +++ b/spring-boot-modules/spring-boot-multiple-datasources/pom.xml @@ -1,7 +1,7 @@ + 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"> 4.0.0 spring-boot-multiple-datasources 0.1.0-SNAPSHOT @@ -55,4 +55,4 @@ 2.6.3 - + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml b/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml index a7f3e01014..de2c8c68c4 100644 --- a/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml +++ b/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml @@ -72,4 +72,4 @@ 2.17.1 - + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger/pom.xml b/spring-boot-modules/spring-boot-swagger/pom.xml index b6ed50534e..749442c225 100644 --- a/spring-boot-modules/spring-boot-swagger/pom.xml +++ b/spring-boot-modules/spring-boot-swagger/pom.xml @@ -84,4 +84,4 @@ 3.1.1 - + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml b/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml index bdd75d0635..7700a2219d 100644 --- a/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml @@ -45,7 +45,7 @@ 2.0.0.RELEASE 3.4.13 - 2.17.1 + 2.17.1 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-eureka-self-preservation/pom.xml b/spring-cloud/spring-cloud-eureka-self-preservation/pom.xml index e22ad6b7c9..5000adc164 100644 --- a/spring-cloud/spring-cloud-eureka-self-preservation/pom.xml +++ b/spring-cloud/spring-cloud-eureka-self-preservation/pom.xml @@ -14,7 +14,12 @@ spring-cloud 1.0.0-SNAPSHOT - + + + spring-cloud-eureka-server + spring-cloud-eureka-client + + @@ -27,11 +32,6 @@ - - spring-cloud-eureka-server - spring-cloud-eureka-client - - org.springframework.boot diff --git a/spring-cloud/spring-cloud-eureka/pom.xml b/spring-cloud/spring-cloud-eureka/pom.xml index 795eab7d6e..63190f7f20 100644 --- a/spring-cloud/spring-cloud-eureka/pom.xml +++ b/spring-cloud/spring-cloud-eureka/pom.xml @@ -14,7 +14,14 @@ spring-cloud 1.0.0-SNAPSHOT - + + + spring-cloud-eureka-server + spring-cloud-eureka-client + spring-cloud-eureka-feign-client + spring-cloud-eureka-feign-client-integration-test + + @@ -27,13 +34,6 @@ - - spring-cloud-eureka-server - spring-cloud-eureka-client - spring-cloud-eureka-feign-client - spring-cloud-eureka-feign-client-integration-test - - org.springframework.boot diff --git a/spring-cloud/spring-cloud-functions/pom.xml b/spring-cloud/spring-cloud-functions/pom.xml index 3dc68e2824..d9f90c7a56 100644 --- a/spring-cloud/spring-cloud-functions/pom.xml +++ b/spring-cloud/spring-cloud-functions/pom.xml @@ -10,7 +10,7 @@ jar Demo project for Spring Cloud Function - + com.baeldung.spring.cloud spring-cloud 1.0.0-SNAPSHOT diff --git a/spring-cloud/spring-cloud-gateway/pom.xml b/spring-cloud/spring-cloud-gateway/pom.xml index a352bbd4e4..e8949cc039 100644 --- a/spring-cloud/spring-cloud-gateway/pom.xml +++ b/spring-cloud/spring-cloud-gateway/pom.xml @@ -83,31 +83,28 @@ org.springframework.boot spring-boot-devtools - org.springframework.boot spring-boot-starter-oauth2-resource-server - org.springframework.boot spring-boot-starter-oauth2-client - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - ${java.version} - ${java.version} - - + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${java.version} + ${java.version} + + org.springframework.boot spring-boot-maven-plugin @@ -123,15 +120,6 @@ - - - - 6.0.2.Final - 0.7.2 - 9.19 - - - quotes-application @@ -177,7 +165,6 @@ - gateway-url-rewrite @@ -192,6 +179,16 @@ - + + + + + + 6.0.2.Final + 0.7.2 + 9.19 + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-kubernetes/pom.xml b/spring-cloud/spring-cloud-kubernetes/pom.xml index c41c500a1b..698bdce1e5 100644 --- a/spring-cloud/spring-cloud-kubernetes/pom.xml +++ b/spring-cloud/spring-cloud-kubernetes/pom.xml @@ -15,6 +15,15 @@ 1.0.0-SNAPSHOT + + kubernetes-minikube/demo-frontend + kubernetes-minikube/demo-backend + kubernetes-selfhealing/liveness-example + kubernetes-selfhealing/readiness-example + kubernetes-guide/client-service + kubernetes-guide/travel-agency-service + + @@ -27,15 +36,6 @@ - - kubernetes-minikube/demo-frontend - kubernetes-minikube/demo-backend - kubernetes-selfhealing/liveness-example - kubernetes-selfhealing/readiness-example - kubernetes-guide/client-service - kubernetes-guide/travel-agency-service - - 2021.0.0 diff --git a/spring-cloud/spring-cloud-load-balancer/pom.xml b/spring-cloud/spring-cloud-load-balancer/pom.xml index 65cf83de09..3b81def641 100644 --- a/spring-cloud/spring-cloud-load-balancer/pom.xml +++ b/spring-cloud/spring-cloud-load-balancer/pom.xml @@ -19,7 +19,7 @@ spring-cloud-loadbalancer-server spring-cloud-loadbalancer-client - + @@ -44,7 +44,7 @@ 2.6.1 2021.0.0 - 2.17.1 + 2.17.1 - + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/pom.xml b/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/pom.xml index fc6e2854aa..c141452695 100644 --- a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/pom.xml +++ b/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/pom.xml @@ -3,17 +3,30 @@ xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + com.baeldung.springcloud.loadbalancer + spring-cloud-loadbalancer-client + 0.0.1-SNAPSHOT + spring-cloud-loadbalancer-client + Spring Cloud Load Balancer Demo - Client + com.baeldung.spring.cloud spring-cloud-loadbalancer 1.0.0-SNAPSHOT - com.baeldung.springcloud.loadbalancer - spring-cloud-loadbalancer-client - 0.0.1-SNAPSHOT - spring-cloud-loadbalancer-client - Spring Cloud Load Balancer Demo - Client + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + org.springframework.boot @@ -30,17 +43,6 @@ test - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - @@ -51,4 +53,4 @@ - + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/pom.xml b/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/pom.xml index 139996994d..3e61ecc90d 100644 --- a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/pom.xml +++ b/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/pom.xml @@ -3,24 +3,23 @@ xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - - com.baeldung.spring.cloud - spring-cloud-loadbalancer - 1.0.0-SNAPSHOT - - com.baeldung.spring.cloud.loadbalancer spring-cloud-loadbalancer-server 0.0.1-SNAPSHOT spring-cloud-loadbalancer-server Spring Cloud Load Balancer Demo - Server + + com.baeldung.spring.cloud + spring-cloud-loadbalancer + 1.0.0-SNAPSHOT + + org.springframework.boot spring-boot-starter-web - org.springframework.boot spring-boot-starter-test @@ -37,4 +36,4 @@ - + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml index b2cb66744b..3960cfde5d 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml @@ -52,7 +52,7 @@ test - + 2.17.1 diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml index 466291650c..c9bc120e4d 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml @@ -52,7 +52,7 @@ test - + 2.17.1 diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml index 27afc3eb69..76d899447f 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml @@ -60,8 +60,8 @@ test - - + + 2.17.1 diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml index 4727859ea2..5df22c78c8 100644 --- a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml @@ -13,7 +13,7 @@ spring-cloud-zuul 0.0.1-SNAPSHOT - + diff --git a/spring-ejb/ejb-beans/pom.xml b/spring-ejb/ejb-beans/pom.xml index 6f20d949b0..37b67beec4 100644 --- a/spring-ejb/ejb-beans/pom.xml +++ b/spring-ejb/ejb-beans/pom.xml @@ -38,7 +38,6 @@ tomee-embedded ${tomee-embedded.version} - org.springframework spring-context diff --git a/spring-reactive/pom.xml b/spring-reactive/pom.xml index d31ee04d82..d755c03ae0 100644 --- a/spring-reactive/pom.xml +++ b/spring-reactive/pom.xml @@ -1,8 +1,9 @@ + 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"> 4.0.0 + spring-reactive com.baeldung @@ -11,8 +12,6 @@ ../parent-boot-2 - spring-reactive - org.springframework.boot diff --git a/spring-security-modules/spring-5-security-oauth/pom.xml b/spring-security-modules/spring-5-security-oauth/pom.xml index 706cdb3082..8449b01ec0 100644 --- a/spring-security-modules/spring-5-security-oauth/pom.xml +++ b/spring-security-modules/spring-5-security-oauth/pom.xml @@ -15,8 +15,8 @@ 0.0.1-SNAPSHOT ../../parent-boot-2 - - + + org.apache.logging.log4j @@ -27,7 +27,6 @@ - @@ -85,7 +84,7 @@ is available --> 2.5.2 com.baeldung.oauth2.SpringOAuthApplication - 2.17.1 + 2.17.1 \ No newline at end of file diff --git a/spring-security-modules/spring-security-legacy-oidc/pom.xml b/spring-security-modules/spring-security-legacy-oidc/pom.xml index 9dd898f9dd..e98486b0ff 100644 --- a/spring-security-modules/spring-security-legacy-oidc/pom.xml +++ b/spring-security-modules/spring-security-legacy-oidc/pom.xml @@ -14,8 +14,8 @@ 0.0.1-SNAPSHOT ../../parent-boot-2 - - + + org.apache.logging.log4j @@ -62,7 +62,7 @@ 1.0.9.RELEASE 0.3.0 2.4.7 - 2.17.1 + 2.17.1 \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-boot-1/pom.xml b/spring-security-modules/spring-security-web-boot-1/pom.xml index 3f6001686d..18cdd0ae5c 100644 --- a/spring-security-modules/spring-security-web-boot-1/pom.xml +++ b/spring-security-modules/spring-security-web-boot-1/pom.xml @@ -179,7 +179,6 @@ - entryPoints diff --git a/spring-security-modules/spring-security-web-boot-3/pom.xml b/spring-security-modules/spring-security-web-boot-3/pom.xml index 5f2a455294..59fcf9949f 100644 --- a/spring-security-modules/spring-security-web-boot-3/pom.xml +++ b/spring-security-modules/spring-security-web-boot-3/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 spring-security-web-boot-3 0.0.1-SNAPSHOT @@ -63,5 +65,4 @@ 3.6.0 - \ No newline at end of file diff --git a/spring-web-modules/pom.xml b/spring-web-modules/pom.xml index d66d9cb35a..a5c23c1649 100644 --- a/spring-web-modules/pom.xml +++ b/spring-web-modules/pom.xml @@ -50,4 +50,4 @@ spring-web-url - + \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-basics-5/pom.xml b/spring-web-modules/spring-mvc-basics-5/pom.xml index 3b64f15c4b..5e8cd1b44e 100644 --- a/spring-web-modules/spring-mvc-basics-5/pom.xml +++ b/spring-web-modules/spring-mvc-basics-5/pom.xml @@ -41,7 +41,7 @@ - spring-mvc-basics + spring-mvc-basics-5 org.springframework.boot diff --git a/testing-modules/cucumber/pom.xml b/testing-modules/cucumber/pom.xml index 531b16ddec..ffa5c0d250 100644 --- a/testing-modules/cucumber/pom.xml +++ b/testing-modules/cucumber/pom.xml @@ -12,7 +12,6 @@ parent-boot-2 0.0.1-SNAPSHOT ../../parent-boot-2 - diff --git a/testing-modules/testng_command_line/pom.xml b/testing-modules/testng_command_line/pom.xml index 4c3af7621c..0f3201a432 100644 --- a/testing-modules/testng_command_line/pom.xml +++ b/testing-modules/testng_command_line/pom.xml @@ -3,10 +3,10 @@ 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"> 4.0.0 - com.baeldung.testing_modules testng_command_line 1.0.0-SNAPSHOT + com.baeldung testing-modules @@ -78,7 +78,6 @@ - ExecuteTestSuite @@ -101,6 +100,7 @@ + UTF-8 1.8 @@ -112,4 +112,5 @@ 3.8.0 2.22.1 - + + \ No newline at end of file From d2cea2ef063383ec62b3cb85f496c1154a63fd6d Mon Sep 17 00:00:00 2001 From: sampadawagde Date: Sun, 13 Mar 2022 14:53:36 +0530 Subject: [PATCH 125/249] resolve conflicts --- spring-security-modules/spring-security-web-boot-3/pom.xml | 5 ++--- testing-modules/testng_command_line/pom.xml | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/spring-security-modules/spring-security-web-boot-3/pom.xml b/spring-security-modules/spring-security-web-boot-3/pom.xml index 59fcf9949f..5f2a455294 100644 --- a/spring-security-modules/spring-security-web-boot-3/pom.xml +++ b/spring-security-modules/spring-security-web-boot-3/pom.xml @@ -1,7 +1,5 @@ - + 4.0.0 spring-security-web-boot-3 0.0.1-SNAPSHOT @@ -65,4 +63,5 @@ 3.6.0 + \ No newline at end of file diff --git a/testing-modules/testng_command_line/pom.xml b/testing-modules/testng_command_line/pom.xml index 0f3201a432..4c3af7621c 100644 --- a/testing-modules/testng_command_line/pom.xml +++ b/testing-modules/testng_command_line/pom.xml @@ -3,10 +3,10 @@ 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"> 4.0.0 + com.baeldung.testing_modules testng_command_line 1.0.0-SNAPSHOT - com.baeldung testing-modules @@ -78,6 +78,7 @@ + ExecuteTestSuite @@ -100,7 +101,6 @@ - UTF-8 1.8 @@ -112,5 +112,4 @@ 3.8.0 2.22.1 - - \ No newline at end of file + From df1cb49ab2b8cb20bcf3553a519a1534aef379d8 Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Mon, 14 Mar 2022 22:58:20 +0530 Subject: [PATCH 126/249] JAVA-10358 changes done to include maven-multi-module changes --- .../maven-simple/parent-project/core/pom.xml | 9 ++++++++- .../maven-simple/parent-project/pom.xml | 10 ++++++++++ .../maven-simple/parent-project/service/pom.xml | 2 +- .../maven-simple/parent-project/webapp/pom.xml | 16 +++++++++++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/maven-modules/maven-simple/parent-project/core/pom.xml b/maven-modules/maven-simple/parent-project/core/pom.xml index a403a59e84..287a331123 100644 --- a/maven-modules/maven-simple/parent-project/core/pom.xml +++ b/maven-modules/maven-simple/parent-project/core/pom.xml @@ -10,7 +10,14 @@ parent-project com.baeldung - 1.0.0-SNAPSHOT + 1.0-SNAPSHOT + + + org.springframework + spring-core + 4.3.30.RELEASE + + \ No newline at end of file diff --git a/maven-modules/maven-simple/parent-project/pom.xml b/maven-modules/maven-simple/parent-project/pom.xml index 7193b61ad7..3bae12e052 100644 --- a/maven-modules/maven-simple/parent-project/pom.xml +++ b/maven-modules/maven-simple/parent-project/pom.xml @@ -4,6 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 parent-project + 1.0-SNAPSHOT parent-project pom @@ -19,4 +20,13 @@ webapp + + + + org.springframework + spring-core + 5.3.16 + + + \ No newline at end of file diff --git a/maven-modules/maven-simple/parent-project/service/pom.xml b/maven-modules/maven-simple/parent-project/service/pom.xml index ee51b51d1b..04cb1151e1 100644 --- a/maven-modules/maven-simple/parent-project/service/pom.xml +++ b/maven-modules/maven-simple/parent-project/service/pom.xml @@ -10,7 +10,7 @@ parent-project com.baeldung - 1.0.0-SNAPSHOT + 1.0-SNAPSHOT \ No newline at end of file diff --git a/maven-modules/maven-simple/parent-project/webapp/pom.xml b/maven-modules/maven-simple/parent-project/webapp/pom.xml index d034d4e7d1..daaeca9394 100644 --- a/maven-modules/maven-simple/parent-project/webapp/pom.xml +++ b/maven-modules/maven-simple/parent-project/webapp/pom.xml @@ -7,10 +7,24 @@ webapp webapp + war + parent-project com.baeldung - 1.0.0-SNAPSHOT + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-war-plugin + 3.3.2 + + false + + + + \ No newline at end of file From 3c9ba669696699b17953276688c90781475edd0c Mon Sep 17 00:00:00 2001 From: PentaKon Date: Mon, 14 Mar 2022 20:16:03 +0200 Subject: [PATCH 127/249] Example code for Get the Number of Rows in a ResultSet --- .../resultsetrowcount/RowCounterApp.java | 43 +++++++++++++++++++ .../ScrollableRowCounter.java | 30 +++++++++++++ .../resultsetrowcount/StandardRowCounter.java | 32 ++++++++++++++ .../ScrollableRowCounterUnitTest.java | 43 +++++++++++++++++++ .../StandardRowCounterUnitTest.java | 43 +++++++++++++++++++ 5 files changed, 191 insertions(+) create mode 100644 persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/RowCounterApp.java create mode 100644 persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/ScrollableRowCounter.java create mode 100644 persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/StandardRowCounter.java create mode 100644 persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultsetrowcount/ScrollableRowCounterUnitTest.java create mode 100644 persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultsetrowcount/StandardRowCounterUnitTest.java diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/RowCounterApp.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/RowCounterApp.java new file mode 100644 index 0000000000..3126241d74 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/RowCounterApp.java @@ -0,0 +1,43 @@ +package com.baeldung.resultsetrowcount; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; + +class RowCounterApp { + + static Logger logger = LoggerFactory.getLogger(RowCounterApp.class); + + public static void main(String[] args) throws SQLException { + Connection conn = createDummyDB(); + + String selectQuery = "SELECT * FROM STORAGE"; + + StandardRowCounter standardCounter = new StandardRowCounter(conn); + logger.info("Standard counter count: {}", standardCounter.getQueryRowCount(selectQuery)); + + ScrollableRowCounter scrollableCounter = new ScrollableRowCounter(conn); + logger.info("Scrollable counter count: {}", scrollableCounter.getQueryRowCount(selectQuery)); + } + + static Connection createDummyDB() throws SQLException { + String dbUrl = "jdbc:h2:mem:testdb"; + Connection conn = DriverManager.getConnection(dbUrl); + try (Statement statement = conn.createStatement()) { + String sql = "CREATE TABLE STORAGE (id INTEGER not null, val VARCHAR(50), PRIMARY KEY (id))"; + statement.executeUpdate(sql); + sql = "INSERT INTO STORAGE VALUES (1, 'Entry A')"; + statement.executeUpdate(sql); + sql = "INSERT INTO STORAGE VALUES (2, 'Entry A')"; + statement.executeUpdate(sql); + sql = "INSERT INTO STORAGE VALUES (3, 'Entry A')"; + statement.executeUpdate(sql); + } + return conn; + } + +} diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/ScrollableRowCounter.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/ScrollableRowCounter.java new file mode 100644 index 0000000000..ecf74a78a8 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/ScrollableRowCounter.java @@ -0,0 +1,30 @@ +package com.baeldung.resultsetrowcount; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * A ResultSet counter that uses a scrollable cursor. + * Scrollable cursors must be supported by the underlying JDBC driver + * and will not always be available for use. + */ +class ScrollableRowCounter { + + Connection conn; + + ScrollableRowCounter(Connection conn) { + this.conn = conn; + } + + int getQueryRowCount(String query) throws SQLException { + try (Statement statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ResultSet scrollableRS = statement.executeQuery(query)) { + scrollableRS.last(); // check if we need a scrollable type for this (probably) + return scrollableRS.getRow(); + // if we want to process the result set data we can move the cursor back to + // the beginning using the scrollableRS.beforeFirst() method + } + } + +} diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/StandardRowCounter.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/StandardRowCounter.java new file mode 100644 index 0000000000..de51834487 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/StandardRowCounter.java @@ -0,0 +1,32 @@ +package com.baeldung.resultsetrowcount; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * A ResultSet counter that iterates through the query + * results and increments a counter variable until it + * reaches the last result. + * + * This solution will work on all cases but is ineffective, + * especially if the ResultSet will be discarded afterwards. + */ +class StandardRowCounter { + Connection conn; + + StandardRowCounter(Connection conn) { + this.conn = conn; + } + + int getQueryRowCount(String query) throws SQLException { + try (Statement statement = conn.createStatement(); ResultSet standardRS = statement.executeQuery(query)) { + int size = 0; + while (standardRS.next()) { + size++; + } + return size; + } + } +} diff --git a/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultsetrowcount/ScrollableRowCounterUnitTest.java b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultsetrowcount/ScrollableRowCounterUnitTest.java new file mode 100644 index 0000000000..959fa817b4 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultsetrowcount/ScrollableRowCounterUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.resultsetrowcount; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.sql.Connection; +import java.sql.SQLException; + +class ScrollableRowCounterUnitTest { + + Connection conn; + + @BeforeEach + void setUp() throws SQLException { + conn = RowCounterApp.createDummyDB(); + } + + @AfterEach + void tearDown() throws SQLException { + conn.close(); + } + + @Test + public void givenDummyDBWithThreeRows_whenAskingForScrollableRowCountForSelectStar_thenCountIsThree() throws SQLException { + ScrollableRowCounter counter = new ScrollableRowCounter(conn); + + int queryRowCount = counter.getQueryRowCount("SELECT * FROM STORAGE"); + + Assertions.assertEquals(3, queryRowCount); + } + + @Test + public void givenDummyDBWithThreeRows_whenAskingForScrollableRowCountForSelect1and2_thenCountIsTwo() throws SQLException { + ScrollableRowCounter counter = new ScrollableRowCounter(conn); + + int queryRowCount = counter.getQueryRowCount("SELECT * FROM STORAGE WHERE ID IN (1,2)"); + + Assertions.assertEquals(2, queryRowCount); + } + +} diff --git a/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultsetrowcount/StandardRowCounterUnitTest.java b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultsetrowcount/StandardRowCounterUnitTest.java new file mode 100644 index 0000000000..e329b5800c --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultsetrowcount/StandardRowCounterUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.resultsetrowcount; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.sql.Connection; +import java.sql.SQLException; + +class StandardRowCounterUnitTest { + + Connection conn; + + @BeforeEach + void setUp() throws SQLException { + conn = RowCounterApp.createDummyDB(); + } + + @AfterEach + void tearDown() throws SQLException { + conn.close(); + } + + @Test + public void givenDummyDBWithThreeRows_whenAskingForStandardRowCountForSelectStar_thenCountIsThree() throws SQLException { + StandardRowCounter counter = new StandardRowCounter(conn); + + int queryRowCount = counter.getQueryRowCount("SELECT * FROM STORAGE"); + + Assertions.assertEquals(3, queryRowCount); + } + + @Test + public void givenDummyDBWithThreeRows_whenAskingForStandardRowCountForSelect1and2_thenCountIsTwo() throws SQLException { + StandardRowCounter counter = new StandardRowCounter(conn); + + int queryRowCount = counter.getQueryRowCount("SELECT * FROM STORAGE WHERE ID IN (1,2)"); + + Assertions.assertEquals(2, queryRowCount); + } + +} From a7885769725cfdb38c68ba1658b3513a95bacbd0 Mon Sep 17 00:00:00 2001 From: PentaKon Date: Mon, 14 Mar 2022 20:27:25 +0200 Subject: [PATCH 128/249] Decouple h2 mem db from rest of examples --- .../main/java/com/baeldung/resultsetrowcount/RowCounterApp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/RowCounterApp.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/RowCounterApp.java index 3126241d74..8e22bb01af 100644 --- a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/RowCounterApp.java +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/RowCounterApp.java @@ -25,7 +25,7 @@ class RowCounterApp { } static Connection createDummyDB() throws SQLException { - String dbUrl = "jdbc:h2:mem:testdb"; + String dbUrl = "jdbc:h2:mem:storagedb"; Connection conn = DriverManager.getConnection(dbUrl); try (Statement statement = conn.createStatement()) { String sql = "CREATE TABLE STORAGE (id INTEGER not null, val VARCHAR(50), PRIMARY KEY (id))"; From aa35c80c419bb4c4829583e0504a4d007d594a84 Mon Sep 17 00:00:00 2001 From: Ralf Ueberfuhr <40685729+ueberfuhr@users.noreply.github.com> Date: Mon, 14 Mar 2022 20:23:35 +0100 Subject: [PATCH 129/249] BAEL-5457: Add Hikari configuration to datasource (#11923) --- .../todos/TodoDatasourceConfiguration.java | 1 + .../main/resources/application-multipledatasources.properties | 1 + 2 files changed, 2 insertions(+) diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/TodoDatasourceConfiguration.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/TodoDatasourceConfiguration.java index b6a16eb7e4..c599c26d01 100644 --- a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/TodoDatasourceConfiguration.java +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/TodoDatasourceConfiguration.java @@ -19,6 +19,7 @@ public class TodoDatasourceConfiguration { @Bean @Primary + @ConfigurationProperties("spring.datasource.todos.hikari") public DataSource todosDataSource() { return todosDataSourceProperties() .initializeDataSourceBuilder() diff --git a/persistence-modules/spring-data-jdbc/src/main/resources/application-multipledatasources.properties b/persistence-modules/spring-data-jdbc/src/main/resources/application-multipledatasources.properties index 0f2b643498..d9f859ea40 100644 --- a/persistence-modules/spring-data-jdbc/src/main/resources/application-multipledatasources.properties +++ b/persistence-modules/spring-data-jdbc/src/main/resources/application-multipledatasources.properties @@ -3,6 +3,7 @@ spring.datasource.todos.url=jdbc:h2:mem:todos spring.datasource.todos.username=sa spring.datasource.todos.password=null spring.datasource.todos.driverClassName=org.h2.Driver +spring.datasource.todos.hikari.connectionTimeout=44444 spring.datasource.topics.url=jdbc:h2:mem:topics spring.datasource.topics.username=sa spring.datasource.topics.password=null From f74056e1d78537e1eb1bceadefa23d9101a4deec Mon Sep 17 00:00:00 2001 From: Kapil Khandelwal Date: Tue, 15 Mar 2022 01:04:49 +0530 Subject: [PATCH 130/249] BAEL-5371: Create a new module java-mongodb-2 in persistence-modules and add push and set operations in Same MongoDB Update (#11924) --- persistence-modules/java-mongodb-2/.gitignore | 5 ++ persistence-modules/java-mongodb-2/README.md | 5 ++ persistence-modules/java-mongodb-2/pom.xml | 53 ++++++++++++++++++ .../mongo/update/PustSetOperation.java | 54 +++++++++++++++++++ .../src/main/resources/logback.xml | 13 +++++ .../update/PustSetOperationLiveTest.java | 53 ++++++++++++++++++ persistence-modules/pom.xml | 3 +- 7 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 persistence-modules/java-mongodb-2/.gitignore create mode 100644 persistence-modules/java-mongodb-2/README.md create mode 100644 persistence-modules/java-mongodb-2/pom.xml create mode 100644 persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/update/PustSetOperation.java create mode 100644 persistence-modules/java-mongodb-2/src/main/resources/logback.xml create mode 100644 persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/update/PustSetOperationLiveTest.java diff --git a/persistence-modules/java-mongodb-2/.gitignore b/persistence-modules/java-mongodb-2/.gitignore new file mode 100644 index 0000000000..79ba317cb5 --- /dev/null +++ b/persistence-modules/java-mongodb-2/.gitignore @@ -0,0 +1,5 @@ +.classpath +.project +.settings +target +build \ No newline at end of file diff --git a/persistence-modules/java-mongodb-2/README.md b/persistence-modules/java-mongodb-2/README.md new file mode 100644 index 0000000000..1b49e11499 --- /dev/null +++ b/persistence-modules/java-mongodb-2/README.md @@ -0,0 +1,5 @@ +## MongoDB + +This module contains articles about MongoDB in Java. + + diff --git a/persistence-modules/java-mongodb-2/pom.xml b/persistence-modules/java-mongodb-2/pom.xml new file mode 100644 index 0000000000..ffc8da0b64 --- /dev/null +++ b/persistence-modules/java-mongodb-2/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + java-mongodb-2 + 1.0-SNAPSHOT + java-mongodb-2 + + + com.baeldung + persistence-modules + 1.0.0-SNAPSHOT + + + + + de.flapdoodle.embedmongo + de.flapdoodle.embedmongo + ${flapdoodle.version} + test + + + org.mongodb + mongo-java-driver + ${mongo.version} + + + dev.morphia.morphia + core + ${morphia.version} + + + org.testcontainers + mongodb + 1.16.3 + test + + + org.testcontainers + junit-jupiter + 1.16.3 + test + + + + + 3.12.1 + 1.11 + 1.5.3 + + + diff --git a/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/update/PustSetOperation.java b/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/update/PustSetOperation.java new file mode 100644 index 0000000000..bb7eca4f23 --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/update/PustSetOperation.java @@ -0,0 +1,54 @@ +package com.baeldung.mongo.update; + +import org.bson.Document; + +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Updates; +import com.mongodb.client.result.UpdateResult; + +public class PustSetOperation { + + private static MongoClient mongoClient; + + private static String testCollectionName; + private static String databaseName; + + public static void setUp() { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + } + databaseName = "baeldung"; + testCollectionName = "marks"; + } + + public static void pushSetSolution() { + + MongoDatabase database = mongoClient.getDatabase(databaseName); + MongoCollection collection = database.getCollection(testCollectionName); + + Document subjectData = new Document().append("subjectId", 126) + .append("subjectName", "Java Programming") + .append("marks", 70); + UpdateResult updateQueryResult = collection.updateOne(Filters.eq("studentId", 1023), Updates.combine(Updates.set("totalMarks", 170), Updates.push("subjectDetails", subjectData))); + System.out.println("updateQueryResult:- " + updateQueryResult); + + } + + public static void main(String args[]) { + + // + // Connect to cluster (default is localhost:27017) + // + setUp(); + + // + // Push document into the array and set a field + // + pushSetSolution(); + + } +} + diff --git a/persistence-modules/java-mongodb-2/src/main/resources/logback.xml b/persistence-modules/java-mongodb-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/update/PustSetOperationLiveTest.java b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/update/PustSetOperationLiveTest.java new file mode 100644 index 0000000000..6279747429 --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/update/PustSetOperationLiveTest.java @@ -0,0 +1,53 @@ +package com.baeldung.update; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import org.bson.Document; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Updates; +import com.mongodb.client.result.UpdateResult; + +public class PustSetOperationLiveTest { + + private static MongoClient mongoClient; + private static MongoDatabase db; + private static MongoCollection collection; + + @BeforeClass + public static void setup() { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + db = mongoClient.getDatabase("baeldung"); + collection = db.getCollection("marks"); + + collection.insertOne(Document.parse("{\n" + " \"studentId\": 1023,\n" + " \"studentName\":\"James Broad\",\n" + " \"joiningYear\":\"2018\",\n" + " \"totalMarks\":100,\n" + " \"subjectDetails\":[\n" + + " {\n" + " \"subjectId\":123,\n" + " \"subjectName\":\"Operating Systems Concepts\",\n" + " \"marks\":4,\n" + " },\n" + " {\n" + + " \"subjectId\":124,\n" + " \"subjectName\":\"Numerical Analysis\",\n" + " \"marks\":60\n" + " }\n" + " ]\n" + " }")); + + } + } + + @Test + public void givenMarksCollection_whenPushSetOperation_thenCheckingForDocument() { + + Document subjectData = new Document().append("subjectId", 126) + .append("subjectName", "Java Programming") + .append("marks", 70); + UpdateResult updateQueryResult = collection.updateOne(Filters.eq("studentId", 1023), Updates.combine(Updates.set("totalMarks", 170), Updates.push("subjectDetails", subjectData))); + + Document studentDetail = collection.find(Filters.eq("studentId", 1023)) + .first(); + assertNotNull(studentDetail); + assertFalse(studentDetail.isEmpty()); + + } + +} + diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 64a9519a8b..f8e3cb05e8 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -43,6 +43,7 @@ java-jpa-2 java-jpa-3 java-mongodb + java-mongodb-2 jnosql jooq jpa-hibernate-cascade-type @@ -104,4 +105,4 @@ 42.2.20 - \ No newline at end of file + From 72b79f502328ec2a68a32fb69613550e58b0f97e Mon Sep 17 00:00:00 2001 From: asia Date: Mon, 14 Mar 2022 21:46:13 +0100 Subject: [PATCH 131/249] BAEL-5304: adding graphql-spqr module --- graphql/graphql-spqr/pom.xml | 51 +++++++++++++++++ .../main/java/com/baeldung/SpringBootApp.java | 11 ++++ .../src/main/java/com/baeldung/spqr/Book.java | 57 +++++++++++++++++++ .../java/com/baeldung/spqr/BookService.java | 51 +++++++++++++++++ .../java/com/baeldung/spqr/IBookService.java | 15 +++++ 5 files changed, 185 insertions(+) create mode 100644 graphql/graphql-spqr/pom.xml create mode 100644 graphql/graphql-spqr/src/main/java/com/baeldung/SpringBootApp.java create mode 100644 graphql/graphql-spqr/src/main/java/com/baeldung/spqr/Book.java create mode 100644 graphql/graphql-spqr/src/main/java/com/baeldung/spqr/BookService.java create mode 100644 graphql/graphql-spqr/src/main/java/com/baeldung/spqr/IBookService.java diff --git a/graphql/graphql-spqr/pom.xml b/graphql/graphql-spqr/pom.xml new file mode 100644 index 0000000000..c825be9b79 --- /dev/null +++ b/graphql/graphql-spqr/pom.xml @@ -0,0 +1,51 @@ + + + + 4.0.0 + com.baeldung.graphql + graphql-spqr + 1.0 + graphql-java + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../.. + + + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot-version} + + + org.springframework.boot + spring-boot-starter + ${spring-boot-version} + + + io.leangen.graphql + graphql-spqr-spring-boot-starter + ${graphql-spqr-spring-boot-starter-version} + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.6.2 + + + + + + 2.6.2 + 0.0.6 + + \ No newline at end of file diff --git a/graphql/graphql-spqr/src/main/java/com/baeldung/SpringBootApp.java b/graphql/graphql-spqr/src/main/java/com/baeldung/SpringBootApp.java new file mode 100644 index 0000000000..dc49f6a7e4 --- /dev/null +++ b/graphql/graphql-spqr/src/main/java/com/baeldung/SpringBootApp.java @@ -0,0 +1,11 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootApp { + public static void main(String[] args) { + SpringApplication.run(SpringBootApp.class, args); + } +} diff --git a/graphql/graphql-spqr/src/main/java/com/baeldung/spqr/Book.java b/graphql/graphql-spqr/src/main/java/com/baeldung/spqr/Book.java new file mode 100644 index 0000000000..405eadca84 --- /dev/null +++ b/graphql/graphql-spqr/src/main/java/com/baeldung/spqr/Book.java @@ -0,0 +1,57 @@ +package com.baeldung.spqr; + +import java.util.Objects; + +public class Book { + private Integer id; + private String author; + private String title; + + public Book(Integer id, String author, String title) { + this.id = id; + this.author = author; + this.title = title; + } + + public Book() { + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Book book = (Book) o; + return id.equals(book.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/graphql/graphql-spqr/src/main/java/com/baeldung/spqr/BookService.java b/graphql/graphql-spqr/src/main/java/com/baeldung/spqr/BookService.java new file mode 100644 index 0000000000..7c9b129491 --- /dev/null +++ b/graphql/graphql-spqr/src/main/java/com/baeldung/spqr/BookService.java @@ -0,0 +1,51 @@ +package com.baeldung.spqr; + +import io.leangen.graphql.annotations.GraphQLArgument; +import io.leangen.graphql.annotations.GraphQLMutation; +import io.leangen.graphql.annotations.GraphQLQuery; +import io.leangen.graphql.spqr.spring.annotations.GraphQLApi; +import org.springframework.stereotype.Service; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Service +@GraphQLApi +public class BookService implements IBookService { + + Set books = new HashSet<>(); + + @GraphQLQuery(name = "getBookWithTitle") + public Book getBookWithTitle(@GraphQLArgument(name = "title") String title) { + return books.stream() + .filter(book -> book.getTitle() + .equals(title)) + .findFirst() + .orElse(null); + } + + @GraphQLQuery(name = "getAllBooks", description = "Get all books") + public List getAllBooks() { + return books.stream() + .toList(); + } + + @GraphQLMutation(name = "addBook") + public Book addBook(@GraphQLArgument(name = "newBook") Book book) { + books.add(book); + return book; + } + + @GraphQLMutation(name = "updateBook") + public Book updateBook(@GraphQLArgument(name = "modifiedBook") Book book) { + books.remove(book); + books.add(book); + return book; + } + + @GraphQLMutation(name = "deleteBook") + public boolean deleteBook(@GraphQLArgument(name = "book") Book book) { + return books.remove(book); + } +} \ No newline at end of file diff --git a/graphql/graphql-spqr/src/main/java/com/baeldung/spqr/IBookService.java b/graphql/graphql-spqr/src/main/java/com/baeldung/spqr/IBookService.java new file mode 100644 index 0000000000..fa92494745 --- /dev/null +++ b/graphql/graphql-spqr/src/main/java/com/baeldung/spqr/IBookService.java @@ -0,0 +1,15 @@ +package com.baeldung.spqr; + +import java.util.List; + +public interface IBookService { + Book getBookWithTitle(String title); + + List getAllBooks(); + + Book addBook(Book book); + + Book updateBook(Book book); + + boolean deleteBook(Book book); +} From 7681cb2d65bc94120998be2848d53f70f7ed4c91 Mon Sep 17 00:00:00 2001 From: Jonathan Cook Date: Mon, 14 Mar 2022 23:35:32 +0100 Subject: [PATCH 132/249] BAEL-5234 - Apache Camel Routes Testing in Spring Boot (#11925) * BAEL-4706 - Spring Boot with Spring Batch * BAEL-3948 - Fix test(s) in spring-batch which leaves repository.sqlite changed * BAEL-4736 - Convert JSONArray to List of Object using camel-jackson * BAEL-4756 - Mockito MockSettings * BAEL-4756 - Mockito MockSettings - fix spelling * BAEL-2674 - Upgrade the Okhttp article * BAEL-4204 - Adding Interceptors in OkHTTP * BAEL-4836 - Mocking Static Methods with Mockito * BAEL-4205 - A Guide to Events in OkHTTP * BAEL-5408 - Update Camel version in spring-boot-camel module * BAEL-5234 - Apache Camel Routes Testing in Spring Boot * BAEL-5234 - Apache Camel Routes Testing in Spring Boot Co-authored-by: Jonathan Cook --- .../spring-boot-camel/.gitignore | 1 + spring-boot-modules/spring-boot-camel/pom.xml | 9 ++++++ .../boot/testing/GreetingsFileRouter.java | 19 +++++++++++ .../GreetingsFileSpringApplication.java | 13 ++++++++ .../testing/GreetingsFileRouterUnitTest.java | 32 +++++++++++++++++++ 5 files changed, 74 insertions(+) create mode 100644 spring-boot-modules/spring-boot-camel/.gitignore create mode 100644 spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/boot/testing/GreetingsFileRouter.java create mode 100644 spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/boot/testing/GreetingsFileSpringApplication.java create mode 100644 spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/boot/testing/GreetingsFileRouterUnitTest.java diff --git a/spring-boot-modules/spring-boot-camel/.gitignore b/spring-boot-modules/spring-boot-camel/.gitignore new file mode 100644 index 0000000000..16be8f2193 --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/.gitignore @@ -0,0 +1 @@ +/output/ diff --git a/spring-boot-modules/spring-boot-camel/pom.xml b/spring-boot-modules/spring-boot-camel/pom.xml index 5bda1b2351..ecf7143808 100644 --- a/spring-boot-modules/spring-boot-camel/pom.xml +++ b/spring-boot-modules/spring-boot-camel/pom.xml @@ -44,6 +44,12 @@ spring-boot-starter-test test + + org.apache.camel + camel-test-spring-junit5 + ${camel.version} + test + @@ -57,6 +63,9 @@ repackage + + com.baeldung.camel.boot.testing.GreetingsFileSpringApplication + diff --git a/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/boot/testing/GreetingsFileRouter.java b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/boot/testing/GreetingsFileRouter.java new file mode 100644 index 0000000000..670af5e08c --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/boot/testing/GreetingsFileRouter.java @@ -0,0 +1,19 @@ +package com.baeldung.camel.boot.testing; + +import org.apache.camel.builder.RouteBuilder; +import org.springframework.stereotype.Component; + +@Component +public class GreetingsFileRouter extends RouteBuilder { + + @Override + public void configure() throws Exception { + + from("direct:start") + .routeId("greetings-route") + .setBody(constant("Hello Baeldung Readers!")) + .to("file:output"); + + } + +} diff --git a/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/boot/testing/GreetingsFileSpringApplication.java b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/boot/testing/GreetingsFileSpringApplication.java new file mode 100644 index 0000000000..a4e862e65d --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/boot/testing/GreetingsFileSpringApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.camel.boot.testing; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GreetingsFileSpringApplication { + + public static void main(String[] args) { + SpringApplication.run(GreetingsFileSpringApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/boot/testing/GreetingsFileRouterUnitTest.java b/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/boot/testing/GreetingsFileRouterUnitTest.java new file mode 100644 index 0000000000..baeb1fd39c --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/boot/testing/GreetingsFileRouterUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.camel.boot.testing; + +import org.apache.camel.EndpointInject; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.apache.camel.test.spring.junit5.MockEndpoints; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +@CamelSpringBootTest +@MockEndpoints("file:output") +class GreetingsFileRouterUnitTest { + + @Autowired + private ProducerTemplate template; + + @EndpointInject("mock:file:output") + private MockEndpoint mock; + + @Test + void whenSendBody_thenGreetingReceivedSuccessfully() throws InterruptedException { + mock.expectedBodiesReceived("Hello Baeldung Readers!"); + + template.sendBody("direct:start", null); + + mock.assertIsSatisfied(); + } + +} From c249317694e4f218517ff177dbe247eafbddd7ef Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Mon, 14 Mar 2022 23:34:39 -0300 Subject: [PATCH 133/249] warn instead of throw --- .../baeldung/SpringBootPersistenceApplication.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/SpringBootPersistenceApplication.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/SpringBootPersistenceApplication.java index a5cb443291..bbda5823f8 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/SpringBootPersistenceApplication.java +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/SpringBootPersistenceApplication.java @@ -47,12 +47,13 @@ public class SpringBootPersistenceApplication implements ApplicationRunner { jsonLines = ImportUtils.lines(new File(source)); } - if (jsonLines == null || jsonLines.isEmpty()) - throw new IllegalArgumentException("no input to import"); - - ImportJsonService importService = context.getBean(ImportJsonService.class); - String result = importService.importTo(collection, jsonLines); - log.info(source + " - result: " + result); + if (jsonLines == null || jsonLines.isEmpty()) { + log.warn(source + " - no input to import"); + } else { + ImportJsonService importService = context.getBean(ImportJsonService.class); + String result = importService.importTo(collection, jsonLines); + log.info(source + " - import result: " + result); + } } } } From 405f0d03751bc4b9418e5710ceaaa0ce2ddcaa74 Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Tue, 15 Mar 2022 17:15:19 +0530 Subject: [PATCH 134/249] JAVA-10358 Extracted versions to properties --- maven-modules/maven-simple/parent-project/core/pom.xml | 6 +++++- maven-modules/maven-simple/parent-project/pom.xml | 6 +++++- maven-modules/maven-simple/parent-project/webapp/pom.xml | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/maven-modules/maven-simple/parent-project/core/pom.xml b/maven-modules/maven-simple/parent-project/core/pom.xml index 287a331123..c21addfff8 100644 --- a/maven-modules/maven-simple/parent-project/core/pom.xml +++ b/maven-modules/maven-simple/parent-project/core/pom.xml @@ -17,7 +17,11 @@ org.springframework spring-core - 4.3.30.RELEASE + ${spring-core.version} + + + 4.3.30.RELEASE + \ No newline at end of file diff --git a/maven-modules/maven-simple/parent-project/pom.xml b/maven-modules/maven-simple/parent-project/pom.xml index 3bae12e052..bde903b1b5 100644 --- a/maven-modules/maven-simple/parent-project/pom.xml +++ b/maven-modules/maven-simple/parent-project/pom.xml @@ -25,8 +25,12 @@ org.springframework spring-core - 5.3.16 + ${spring-core.version} + + + 5.3.16 + \ No newline at end of file diff --git a/maven-modules/maven-simple/parent-project/webapp/pom.xml b/maven-modules/maven-simple/parent-project/webapp/pom.xml index daaeca9394..e3b6697758 100644 --- a/maven-modules/maven-simple/parent-project/webapp/pom.xml +++ b/maven-modules/maven-simple/parent-project/webapp/pom.xml @@ -20,11 +20,15 @@ org.apache.maven.plugins maven-war-plugin - 3.3.2 + ${maven-war-plugin.version} false + + + 3.3.2 + \ No newline at end of file From 3c5aaa6b09c0db78b17681c5a1df3bde8456eab1 Mon Sep 17 00:00:00 2001 From: Seshu Kumar T Date: Tue, 15 Mar 2022 19:27:51 +0530 Subject: [PATCH 135/249] Producer consumer problem (#11781) * Producer consumer problem * Simplified producer consumer added Co-authored-by: Seshu Thanneeru --- .../baeldung/producerconsumer/Consumer.java | 51 ++++++++++++++ .../baeldung/producerconsumer/DataQueue.java | 59 ++++++++++++++++ .../baeldung/producerconsumer/Message.java | 27 ++++++++ .../baeldung/producerconsumer/Producer.java | 53 ++++++++++++++ .../ProducerConsumerDemonstrator.java | 69 +++++++++++++++++++ .../SimpleProducerConsumerDemonstrator.java | 60 ++++++++++++++++ .../baeldung/producerconsumer/ThreadUtil.java | 24 +++++++ 7 files changed, 343 insertions(+) create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/DataQueue.java create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Message.java create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/ProducerConsumerDemonstrator.java create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/SimpleProducerConsumerDemonstrator.java create mode 100644 core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/ThreadUtil.java diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java new file mode 100644 index 0000000000..5a059b74df --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java @@ -0,0 +1,51 @@ +package com.baeldung.producerconsumer; + +public class Consumer implements Runnable { + private final DataQueue dataQueue; + private volatile boolean runFlag; + + public Consumer(DataQueue dataQueue) { + this.dataQueue = dataQueue; + runFlag = true; + } + + @Override + public void run() { + consume(); + } + + public void consume() { + while (runFlag) { + Message message; + if (dataQueue.isEmpty()) { + try { + dataQueue.waitOnEmpty(); + } catch (InterruptedException e) { + e.printStackTrace(); + break; + } + } + if (!runFlag) { + break; + } + message = dataQueue.remove(); + dataQueue.notifyAllForFull(); + useMessage(message); + } + System.out.println("Consumer Stopped"); + } + + private void useMessage(Message message) { + if (message != null) { + System.out.printf("[%s] Consuming Message. Id: %d, Data: %f\n", Thread.currentThread().getName(), message.getId(), message.getData()); + + //Sleeping on random time to make it realistic + ThreadUtil.sleep((long) (message.getData() * 100)); + } + } + + public void stop() { + runFlag = false; + dataQueue.notifyAllForEmpty(); + } +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/DataQueue.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/DataQueue.java new file mode 100644 index 0000000000..6ab4fa2bc3 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/DataQueue.java @@ -0,0 +1,59 @@ +package com.baeldung.producerconsumer; + +import java.util.LinkedList; +import java.util.Queue; + +public class DataQueue { + private final Queue queue = new LinkedList<>(); + private final int maxSize; + private final Object FULL_QUEUE = new Object(); + private final Object EMPTY_QUEUE = new Object(); + + DataQueue(int maxSize) { + this.maxSize = maxSize; + } + + public boolean isFull() { + return queue.size() == maxSize; + } + + public boolean isEmpty() { + return queue.isEmpty(); + } + + public void waitOnFull() throws InterruptedException { + synchronized (FULL_QUEUE) { + FULL_QUEUE.wait(); + } + } + + public void waitOnEmpty() throws InterruptedException { + synchronized (EMPTY_QUEUE) { + EMPTY_QUEUE.wait(); + } + } + + public void notifyAllForFull() { + synchronized (FULL_QUEUE) { + FULL_QUEUE.notifyAll(); + } + } + + public void notifyAllForEmpty() { + synchronized (EMPTY_QUEUE) { + EMPTY_QUEUE.notifyAll(); + } + } + + public void add(Message message) { + synchronized (queue) { + queue.add(message); + } + } + + public Message remove() { + synchronized (queue) { + return queue.poll(); + } + } +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Message.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Message.java new file mode 100644 index 0000000000..48f6e986df --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Message.java @@ -0,0 +1,27 @@ +package com.baeldung.producerconsumer; + +public class Message { + private int id; + private double data; + + public Message(int id, double data) { + this.id = id; + this.data = data; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public double getData() { + return data; + } + + public void setData(double data) { + this.data = data; + } +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java new file mode 100644 index 0000000000..80d693bd97 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java @@ -0,0 +1,53 @@ +package com.baeldung.producerconsumer; + +public class Producer implements Runnable { + private final DataQueue dataQueue; + private volatile boolean runFlag; + + private static int idSequence = 0; + + public Producer(DataQueue dataQueue) { + this.dataQueue = dataQueue; + runFlag = true; + } + + @Override + public void run() { + produce(); + } + + public void produce() { + while (runFlag) { + Message message = generateMessage(); + while (dataQueue.isFull()) { + try { + dataQueue.waitOnFull(); + } catch (InterruptedException e) { + e.printStackTrace(); + break; + } + } + if (!runFlag) { + break; + } + dataQueue.add(message); + dataQueue.notifyAllForEmpty(); + } + System.out.println("Producer Stopped"); + } + + private Message generateMessage() { + Message message = new Message(++idSequence, Math.random()); + System.out.printf("[%s] Generated Message. Id: %d, Data: %f\n", Thread.currentThread().getName(), message.getId(), message.getData()); + + //Sleeping on random time to make it realistic + ThreadUtil.sleep((long) (message.getData() * 100)); + + return message; + } + + public void stop() { + runFlag = false; + dataQueue.notifyAllForFull(); + } +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/ProducerConsumerDemonstrator.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/ProducerConsumerDemonstrator.java new file mode 100644 index 0000000000..96d7b9f865 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/ProducerConsumerDemonstrator.java @@ -0,0 +1,69 @@ +package com.baeldung.producerconsumer; + +import java.util.ArrayList; +import java.util.List; + +import static com.baeldung.producerconsumer.ThreadUtil.*; + +public class ProducerConsumerDemonstrator { + private static final int MAX_QUEUE_CAPACITY = 5; + + public static void demoSingleProducerAndSingleConsumer() { + DataQueue dataQueue = new DataQueue(MAX_QUEUE_CAPACITY); + + Producer producer = new Producer(dataQueue); + Thread producerThread = new Thread(producer); + + Consumer consumer = new Consumer(dataQueue); + Thread consumerThread = new Thread(consumer); + + producerThread.start(); + consumerThread.start(); + + List threads = new ArrayList<>(); + threads.add(producerThread); + threads.add(consumerThread); + + // let threads run for two seconds + sleep(2000); + + // Stop threads + producer.stop(); + consumer.stop(); + + waitForAllThreadsToComplete(threads); + } + + public static void demoMultipleProducersAndMultipleConsumers() { + DataQueue dataQueue = new DataQueue(MAX_QUEUE_CAPACITY); + int producerCount = 3; + int consumerCount = 3; + List threads = new ArrayList<>(); + Producer producer = new Producer(dataQueue); + for(int i = 0; i < producerCount; i++) { + Thread producerThread = new Thread(producer); + producerThread.start(); + threads.add(producerThread); + } + Consumer consumer = new Consumer(dataQueue); + for(int i = 0; i < consumerCount; i++) { + Thread consumerThread = new Thread(consumer); + consumerThread.start(); + threads.add(consumerThread); + } + + // let threads run for two seconds + sleep(2000); + + // Stop threads + producer.stop(); + consumer.stop(); + + waitForAllThreadsToComplete(threads); + } + + public static void main(String[] args) { + demoSingleProducerAndSingleConsumer(); + demoMultipleProducersAndMultipleConsumers(); + } +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/SimpleProducerConsumerDemonstrator.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/SimpleProducerConsumerDemonstrator.java new file mode 100644 index 0000000000..f1f6e1cc9c --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/SimpleProducerConsumerDemonstrator.java @@ -0,0 +1,60 @@ +package com.baeldung.producerconsumer; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; + +import static com.baeldung.producerconsumer.ThreadUtil.sleep; + +public class SimpleProducerConsumerDemonstrator { + BlockingQueue blockingQueue = new LinkedBlockingDeque<>(5); + + private void produce() { + while (true) { + double value = generateValue(); + try { + blockingQueue.put(value); + } catch (InterruptedException e) { + e.printStackTrace(); + break; + } + System.out.printf("[%s] Value produced: %f\n", Thread.currentThread().getName(), value); + } + } + + private void consume() { + while (true) { + Double value; + try { + value = blockingQueue.take(); + } catch (InterruptedException e) { + e.printStackTrace(); + break; + } + // Consume value + System.out.printf("[%s] Value consumed: %f\n", Thread.currentThread().getName(), value); + } + } + + private double generateValue() { + return Math.random(); + } + + private void runProducerConsumer() { + for (int i = 0; i < 2; i++) { + Thread producerThread = new Thread(this::produce); + producerThread.start(); + } + + for (int i = 0; i < 3; i++) { + Thread consumerThread = new Thread(this::consume); + consumerThread.start(); + } + } + + public static void main(String[] args) { + SimpleProducerConsumerDemonstrator simpleProducerConsumerDemonstrator = new SimpleProducerConsumerDemonstrator(); + simpleProducerConsumerDemonstrator.runProducerConsumer(); + sleep(2000); + System.exit(0); + } +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/ThreadUtil.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/ThreadUtil.java new file mode 100644 index 0000000000..e49a9019fd --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/ThreadUtil.java @@ -0,0 +1,24 @@ +package com.baeldung.producerconsumer; + +import java.util.List; + +public class ThreadUtil { + public static void waitForAllThreadsToComplete(List threads) { + for(Thread thread: threads) { + try { + thread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public static void sleep(long interval) { + try { + // Wait for some time to demonstrate threads + Thread.sleep(interval); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} From edc11ea4f82cfcaa837e695c496b5d67e4ef51da Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Tue, 15 Mar 2022 19:49:00 +0530 Subject: [PATCH 136/249] JAVA-10358 Removed explicit groupId declaration from submodules --- maven-modules/maven-simple/parent-project/core/pom.xml | 1 - maven-modules/maven-simple/parent-project/service/pom.xml | 1 - maven-modules/maven-simple/parent-project/webapp/pom.xml | 1 - 3 files changed, 3 deletions(-) diff --git a/maven-modules/maven-simple/parent-project/core/pom.xml b/maven-modules/maven-simple/parent-project/core/pom.xml index c21addfff8..6553889c24 100644 --- a/maven-modules/maven-simple/parent-project/core/pom.xml +++ b/maven-modules/maven-simple/parent-project/core/pom.xml @@ -3,7 +3,6 @@ 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"> 4.0.0 - org.baeldung core core diff --git a/maven-modules/maven-simple/parent-project/service/pom.xml b/maven-modules/maven-simple/parent-project/service/pom.xml index 04cb1151e1..78d458c55a 100644 --- a/maven-modules/maven-simple/parent-project/service/pom.xml +++ b/maven-modules/maven-simple/parent-project/service/pom.xml @@ -3,7 +3,6 @@ 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"> 4.0.0 - org.baeldung service service diff --git a/maven-modules/maven-simple/parent-project/webapp/pom.xml b/maven-modules/maven-simple/parent-project/webapp/pom.xml index e3b6697758..f6cee60cbf 100644 --- a/maven-modules/maven-simple/parent-project/webapp/pom.xml +++ b/maven-modules/maven-simple/parent-project/webapp/pom.xml @@ -3,7 +3,6 @@ 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"> 4.0.0 - org.baeldung webapp webapp From 14db41f53aa6a6fbf650d80a7529fb0c1d3d87f9 Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Tue, 15 Mar 2022 20:23:29 +0530 Subject: [PATCH 137/249] JAVA-10561 Renamed org.baeldung to com.baeldung at all places --- maven-modules/maven-copy-files/copy-rename-maven-plugin/pom.xml | 2 -- .../src/test/java/{org => com}/baeldung/CopyFileUnitTest.java | 2 +- maven-modules/maven-copy-files/maven-antrun-plugin/pom.xml | 2 -- .../src/test/java/{org => com}/baeldung/CopyFileUnitTest.java | 2 +- maven-modules/maven-copy-files/maven-resources-plugin/pom.xml | 2 -- .../src/test/java/{org => com}/baeldung/CopyFileUnitTest.java | 2 +- 6 files changed, 3 insertions(+), 9 deletions(-) rename maven-modules/maven-copy-files/copy-rename-maven-plugin/src/test/java/{org => com}/baeldung/CopyFileUnitTest.java (94%) rename maven-modules/maven-copy-files/maven-antrun-plugin/src/test/java/{org => com}/baeldung/CopyFileUnitTest.java (94%) rename maven-modules/maven-copy-files/maven-resources-plugin/src/test/java/{org => com}/baeldung/CopyFileUnitTest.java (94%) diff --git a/maven-modules/maven-copy-files/copy-rename-maven-plugin/pom.xml b/maven-modules/maven-copy-files/copy-rename-maven-plugin/pom.xml index 06a44ed4fb..dbc27b61f2 100644 --- a/maven-modules/maven-copy-files/copy-rename-maven-plugin/pom.xml +++ b/maven-modules/maven-copy-files/copy-rename-maven-plugin/pom.xml @@ -3,9 +3,7 @@ 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"> 4.0.0 - org.baeldung copy-rename-maven-plugin - 1.0-SNAPSHOT copy-rename-maven-plugin diff --git a/maven-modules/maven-copy-files/copy-rename-maven-plugin/src/test/java/org/baeldung/CopyFileUnitTest.java b/maven-modules/maven-copy-files/copy-rename-maven-plugin/src/test/java/com/baeldung/CopyFileUnitTest.java similarity index 94% rename from maven-modules/maven-copy-files/copy-rename-maven-plugin/src/test/java/org/baeldung/CopyFileUnitTest.java rename to maven-modules/maven-copy-files/copy-rename-maven-plugin/src/test/java/com/baeldung/CopyFileUnitTest.java index a98db61fa9..94fa31a3ed 100644 --- a/maven-modules/maven-copy-files/copy-rename-maven-plugin/src/test/java/org/baeldung/CopyFileUnitTest.java +++ b/maven-modules/maven-copy-files/copy-rename-maven-plugin/src/test/java/com/baeldung/CopyFileUnitTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; diff --git a/maven-modules/maven-copy-files/maven-antrun-plugin/pom.xml b/maven-modules/maven-copy-files/maven-antrun-plugin/pom.xml index b005f4b125..430d0a1f5b 100644 --- a/maven-modules/maven-copy-files/maven-antrun-plugin/pom.xml +++ b/maven-modules/maven-copy-files/maven-antrun-plugin/pom.xml @@ -3,9 +3,7 @@ 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"> 4.0.0 - org.baeldung maven-antrun-plugin - 1.0-SNAPSHOT maven-antrun-plugin diff --git a/maven-modules/maven-copy-files/maven-antrun-plugin/src/test/java/org/baeldung/CopyFileUnitTest.java b/maven-modules/maven-copy-files/maven-antrun-plugin/src/test/java/com/baeldung/CopyFileUnitTest.java similarity index 94% rename from maven-modules/maven-copy-files/maven-antrun-plugin/src/test/java/org/baeldung/CopyFileUnitTest.java rename to maven-modules/maven-copy-files/maven-antrun-plugin/src/test/java/com/baeldung/CopyFileUnitTest.java index a98db61fa9..94fa31a3ed 100644 --- a/maven-modules/maven-copy-files/maven-antrun-plugin/src/test/java/org/baeldung/CopyFileUnitTest.java +++ b/maven-modules/maven-copy-files/maven-antrun-plugin/src/test/java/com/baeldung/CopyFileUnitTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; diff --git a/maven-modules/maven-copy-files/maven-resources-plugin/pom.xml b/maven-modules/maven-copy-files/maven-resources-plugin/pom.xml index a49095f528..b2e99f80bc 100644 --- a/maven-modules/maven-copy-files/maven-resources-plugin/pom.xml +++ b/maven-modules/maven-copy-files/maven-resources-plugin/pom.xml @@ -3,9 +3,7 @@ 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"> 4.0.0 - org.baeldung maven-resources-plugin - 1.0-SNAPSHOT maven-resources-plugin diff --git a/maven-modules/maven-copy-files/maven-resources-plugin/src/test/java/org/baeldung/CopyFileUnitTest.java b/maven-modules/maven-copy-files/maven-resources-plugin/src/test/java/com/baeldung/CopyFileUnitTest.java similarity index 94% rename from maven-modules/maven-copy-files/maven-resources-plugin/src/test/java/org/baeldung/CopyFileUnitTest.java rename to maven-modules/maven-copy-files/maven-resources-plugin/src/test/java/com/baeldung/CopyFileUnitTest.java index a98db61fa9..94fa31a3ed 100644 --- a/maven-modules/maven-copy-files/maven-resources-plugin/src/test/java/org/baeldung/CopyFileUnitTest.java +++ b/maven-modules/maven-copy-files/maven-resources-plugin/src/test/java/com/baeldung/CopyFileUnitTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; From a2dbf5d892b865b3c0d1d1ea0cbe1e3477c28a44 Mon Sep 17 00:00:00 2001 From: vaibhav007jain <72961247+vaibhav007jain@users.noreply.github.com> Date: Tue, 15 Mar 2022 21:09:20 +0530 Subject: [PATCH 138/249] BAEL-5385 Code for Automorphic Number. (#11928) --- .../automorphicnumber/AutomorphicNumber.java | 31 +++++++++++++++++++ .../AutomorphicNumberUnitTest.java | 19 ++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 java-numbers-4/src/main/java/com/baeldung/automorphicnumber/AutomorphicNumber.java create mode 100644 java-numbers-4/src/test/java/com/baeldung/automorphicnumber/AutomorphicNumberUnitTest.java diff --git a/java-numbers-4/src/main/java/com/baeldung/automorphicnumber/AutomorphicNumber.java b/java-numbers-4/src/main/java/com/baeldung/automorphicnumber/AutomorphicNumber.java new file mode 100644 index 0000000000..926b13deda --- /dev/null +++ b/java-numbers-4/src/main/java/com/baeldung/automorphicnumber/AutomorphicNumber.java @@ -0,0 +1,31 @@ +package com.baeldung.automorphicnumber; + +public class AutomorphicNumber { + + public static void main(String[] args) { + System.out.println(isAutomorphicUsingLoop(76)); + System.out.println(isAutomorphicUsingMath(76)); + } + + public static boolean isAutomorphicUsingMath(int number) { + int square = number * number; + + int numberOfDigits = (int) Math.floor(Math.log10(number) + 1); + int lastDigits = (int) (square % (Math.pow(10, numberOfDigits))); + + return number == lastDigits; + } + + public static boolean isAutomorphicUsingLoop(int number) { + int square = number * number; + + while (number > 0) { + if (number % 10 != square % 10) { + return false; + } + number /= 10; + square /= 10; + } + return true; + } +} \ No newline at end of file diff --git a/java-numbers-4/src/test/java/com/baeldung/automorphicnumber/AutomorphicNumberUnitTest.java b/java-numbers-4/src/test/java/com/baeldung/automorphicnumber/AutomorphicNumberUnitTest.java new file mode 100644 index 0000000000..8e31de9f47 --- /dev/null +++ b/java-numbers-4/src/test/java/com/baeldung/automorphicnumber/AutomorphicNumberUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.automorphicnumber; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; + +public class AutomorphicNumberUnitTest { + + @Test + void givenANumber_whenPassed_thenShouldDetermineAutomorphicOrNot() { + int number1 = 76; // automorphic + int number2 = 16; // not automorphic + assertTrue(AutomorphicNumber.isAutomorphicUsingLoop(number1)); + assertFalse(AutomorphicNumber.isAutomorphicUsingLoop(number2)); + assertTrue(AutomorphicNumber.isAutomorphicUsingMath(number1)); + assertFalse(AutomorphicNumber.isAutomorphicUsingMath(number2)); + } +} From 14f2b7c2b85426f31ba88e9a30a8ec7dd62f2260 Mon Sep 17 00:00:00 2001 From: Mayank Aggarwal Date: Tue, 15 Mar 2022 22:14:34 +0530 Subject: [PATCH 139/249] [BAEL-5420] Added value object creation (#11901) * [BAEL-5420] Added value object creation * BAEL-5420 Added JavaBean and DTO classes * [BAEL-5420] Indented the code * Renamed EmployeePojo to EmployeePOJO * BAEL-5420: Renamed to EmployeeDTO * [BAEL-5420] Resolving Review comments Co-authored-by: Mayank Agarwal --- .../com/baeldung/employee/EmployeeBean.java | 48 ++++++++++++++++++ .../com/baeldung/employee/EmployeeDTO.java | 34 +++++++++++++ .../com/baeldung/employee/EmployeePOJO.java | 49 +++++++++++++++++++ .../com/baeldung/employee/EmployeeVO.java | 40 +++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeBean.java create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeDTO.java create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeePOJO.java create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeVO.java diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeBean.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeBean.java new file mode 100644 index 0000000000..ed75a7157c --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeBean.java @@ -0,0 +1,48 @@ +package com.baeldung.employee; + +import java.io.Serializable; +import java.time.LocalDate; + +public class EmployeeBean implements Serializable { + + private static final long serialVersionUID = -3760445487636086034L; + + private String firstName; + private String lastName; + private LocalDate startDate; + + public EmployeeBean() { + + } + + public EmployeeBean(String firstName, String lastName, LocalDate startDate) { + this.firstName = firstName; + this.lastName = lastName; + this.startDate = startDate; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public LocalDate getStartDate() { + return startDate; + } + + public void setStartDate(LocalDate startDate) { + this.startDate = startDate; + } + +} diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeDTO.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeDTO.java new file mode 100644 index 0000000000..beb6bf3ce5 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeDTO.java @@ -0,0 +1,34 @@ +package com.baeldung.employee; + +import java.time.LocalDate; + +public class EmployeeDTO { + + private String firstName; + private String lastName; + private LocalDate startDate; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public LocalDate getStartDate() { + return startDate; + } + + public void setStartDate(LocalDate startDate) { + this.startDate = startDate; + } +} diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeePOJO.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeePOJO.java new file mode 100644 index 0000000000..50f17d965f --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeePOJO.java @@ -0,0 +1,49 @@ +package com.baeldung.employee; + +import java.time.LocalDate; +import java.util.Objects; + +public class EmployeePOJO { + + private String firstName; + private String lastName; + private LocalDate startDate; + + public EmployeePOJO(String firstName, String lastName, LocalDate startDate) { + this.firstName = firstName; + this.lastName = lastName; + this.startDate = startDate; + } + + public String name() { + return this.firstName + " " + this.lastName; + } + + public LocalDate getStart() { + return this.startDate; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public LocalDate getStartDate() { + return startDate; + } + + public void setStartDate(LocalDate startDate) { + this.startDate = startDate; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeVO.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeVO.java new file mode 100644 index 0000000000..7a1775f79d --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeVO.java @@ -0,0 +1,40 @@ +package com.baeldung.employee; + +import java.time.LocalDate; +import java.util.Objects; + +public class EmployeeVO { + private String firstName; + private String lastName; + private LocalDate startDate; + + public EmployeeVO(String firstName, String lastName, LocalDate startDate) { + this.firstName = firstName; + this.lastName = lastName; + this.startDate = startDate; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public LocalDate getStartDate() { + return startDate; + } + + @Override + public boolean equals(Object obj) { + return Objects.equals(firstName, this.firstName) + && Objects.equals(lastName, this.lastName) + && Objects.equals(startDate, this.startDate); + } + + @Override + public int hashCode() { + return Objects.hash(firstName, lastName, startDate); + } +} From b2c7dece6b5bc6d0a4cc92f8ec871cdf96d12d50 Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Wed, 16 Mar 2022 16:50:55 +0530 Subject: [PATCH 140/249] COMAUTO-10561 Fixed parent version --- maven-modules/maven-simple/maven-dependency/pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/maven-modules/maven-simple/maven-dependency/pom.xml b/maven-modules/maven-simple/maven-dependency/pom.xml index 628c1b62d4..ba63e53a1a 100644 --- a/maven-modules/maven-simple/maven-dependency/pom.xml +++ b/maven-modules/maven-simple/maven-dependency/pom.xml @@ -4,13 +4,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 maven-dependency - 1.0.0-SNAPSHOT pom com.baeldung maven-simple - 0.0.1-SNAPSHOT + 1.0.0-SNAPSHOT From 20825bdd9b402cee9cca1f359bc6a50157269db5 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:02:12 +0800 Subject: [PATCH 141/249] Create README.md --- persistence-modules/fauna/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 persistence-modules/fauna/README.md diff --git a/persistence-modules/fauna/README.md b/persistence-modules/fauna/README.md new file mode 100644 index 0000000000..f0899ceaf7 --- /dev/null +++ b/persistence-modules/fauna/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Building a web app Using Fauna and Spring for Your First web Agency Client](https://www.baeldung.com/faunadb-spring-web-app) From aa751ab0443817fa12e3ae35ef5eeab00baa2946 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:09:51 +0800 Subject: [PATCH 142/249] Update README.md --- persistence-modules/java-mongodb/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-mongodb/README.md b/persistence-modules/java-mongodb/README.md index 2b7fcd3de0..ae21f9df90 100644 --- a/persistence-modules/java-mongodb/README.md +++ b/persistence-modules/java-mongodb/README.md @@ -14,3 +14,4 @@ This module contains articles about MongoDB in Java. - [How to Check Field Existence in MongoDB?](https://www.baeldung.com/mongodb-check-field-exists) - [Get Last Inserted Document ID in MongoDB With Java Driver](https://www.baeldung.com/java-mongodb-last-inserted-id) - [Update Multiple Fields in a MongoDB Document](https://www.baeldung.com/mongodb-update-multiple-fields) +- [Update Documents in MongoDB](https://www.baeldung.com/mongodb-update-documents) From ad046e7fd6a1fdb712834589acedb3c190aa663e Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:12:31 +0800 Subject: [PATCH 143/249] Update README.md --- spring-cloud/spring-cloud-openfeign/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-cloud/spring-cloud-openfeign/README.md b/spring-cloud/spring-cloud-openfeign/README.md index 44f4d15b16..c1bd5ad43e 100644 --- a/spring-cloud/spring-cloud-openfeign/README.md +++ b/spring-cloud/spring-cloud-openfeign/README.md @@ -5,3 +5,4 @@ - [File Upload With Open Feign](https://www.baeldung.com/java-feign-file-upload) - [Feign Logging Configuration](https://www.baeldung.com/java-feign-logging) - [Provide an OAuth2 Token to a Feign Client](https://www.baeldung.com/spring-cloud-feign-oauth-token) +- [Retrieve Original Message From Feign ErrorDecoder](https://www.baeldung.com/feign-retrieve-original-message) From c8d224e24aea69f2da749438c8ad58568fc2b5d2 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:16:20 +0800 Subject: [PATCH 144/249] Update README.md --- persistence-modules/java-mongodb/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-mongodb/README.md b/persistence-modules/java-mongodb/README.md index ae21f9df90..50cc25d942 100644 --- a/persistence-modules/java-mongodb/README.md +++ b/persistence-modules/java-mongodb/README.md @@ -15,3 +15,4 @@ This module contains articles about MongoDB in Java. - [Get Last Inserted Document ID in MongoDB With Java Driver](https://www.baeldung.com/java-mongodb-last-inserted-id) - [Update Multiple Fields in a MongoDB Document](https://www.baeldung.com/mongodb-update-multiple-fields) - [Update Documents in MongoDB](https://www.baeldung.com/mongodb-update-documents) +- [Check Collection Existence in MongoDB](https://www.baeldung.com/java-check-collection-existence-mongodb) From 43b8b76b33c2901def547e88709711faf30461d9 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:21:51 +0800 Subject: [PATCH 145/249] Update README.md --- spring-security-modules/spring-security-web-boot-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-security-modules/spring-security-web-boot-3/README.md b/spring-security-modules/spring-security-web-boot-3/README.md index 2f98e0f4a0..400039dbfe 100644 --- a/spring-security-modules/spring-security-web-boot-3/README.md +++ b/spring-security-modules/spring-security-web-boot-3/README.md @@ -13,4 +13,5 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com - [Fixing 401s with CORS Preflights and Spring Security](https://www.baeldung.com/spring-security-cors-preflight) - [Content Security Policy with Spring Security](https://www.baeldung.com/spring-security-csp) - [Enable Logging for Spring Security](https://www.baeldung.com/spring-security-enable-logging) +- [Authentication With Spring Security and MongoDB](https://www.baeldung.com/spring-security-authentication-mongodb) - More articles: [[<-- prev]](/spring-security-modules/spring-security-web-boot-2) From d7baaf8ced9376b32c59d261ba3d28829369da06 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:25:15 +0800 Subject: [PATCH 146/249] Update README.md --- core-java-modules/core-java-concurrency-advanced-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-concurrency-advanced-4/README.md b/core-java-modules/core-java-concurrency-advanced-4/README.md index ba838dbc72..808db89b12 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/README.md +++ b/core-java-modules/core-java-concurrency-advanced-4/README.md @@ -5,3 +5,4 @@ - [Start Two Threads at the Exact Same Time in Java](https://www.baeldung.com/java-start-two-threads-at-same-time) - [Volatile Variables and Thread Safety](https://www.baeldung.com/java-volatile-variables-thread-safety) - [Producer-Consumer Problem With Example in Java](https://www.baeldung.com/java-producer-consumer-problem) +- [Acquire a Lock by a Key in Java](https://www.baeldung.com/java-acquire-lock-by-key) From 33d165653bd2148c4e989ebdacff5fdea6b5f6c2 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:28:01 +0800 Subject: [PATCH 147/249] Update README.md --- persistence-modules/java-mongodb/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-mongodb/README.md b/persistence-modules/java-mongodb/README.md index 50cc25d942..2c25cf5392 100644 --- a/persistence-modules/java-mongodb/README.md +++ b/persistence-modules/java-mongodb/README.md @@ -16,3 +16,4 @@ This module contains articles about MongoDB in Java. - [Update Multiple Fields in a MongoDB Document](https://www.baeldung.com/mongodb-update-multiple-fields) - [Update Documents in MongoDB](https://www.baeldung.com/mongodb-update-documents) - [Check Collection Existence in MongoDB](https://www.baeldung.com/java-check-collection-existence-mongodb) +- [Case Insensitive Sorting in MongoDB](https://www.baeldung.com/java-mongodb-case-insensitive-sorting) From 461db45f00fa56ec900780612aef7ac55b0b536f Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:29:59 +0800 Subject: [PATCH 148/249] Update README.md --- xml-2/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xml-2/README.md b/xml-2/README.md index e3c6ed6443..bc599f8480 100644 --- a/xml-2/README.md +++ b/xml-2/README.md @@ -2,4 +2,6 @@ This module contains articles about eXtensible Markup Language (XML) -### Relevant Articles: \ No newline at end of file +### Relevant Articles: + +- [Pretty-Print XML in Java](https://www.baeldung.com/java-pretty-print-xml) From cf99b18b1ddc4f4d2062f0dc52c9f311fba337c9 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:32:53 +0800 Subject: [PATCH 149/249] Create README.md --- jakarta-ee/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 jakarta-ee/README.md diff --git a/jakarta-ee/README.md b/jakarta-ee/README.md new file mode 100644 index 0000000000..54f372f736 --- /dev/null +++ b/jakarta-ee/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Introduction to Jakarta EE MVC / Eclipse Krazo](https://www.baeldung.com/java-ee-mvc-eclipse-krazo) From 12eacbcfe79eeb2079f88231cfc120b6c49628b9 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:38:26 +0800 Subject: [PATCH 150/249] Create README.md --- .../src/main/java/com/baeldung/swaggerresponseapi/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/README.md diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/README.md b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/README.md new file mode 100644 index 0000000000..a7ff3285ee --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Set List of Objects in Swagger API Response](https://www.baeldung.com/java-swagger-set-list-response) From 481bd47b897c3601931f4504fc4e275842a6aa9c Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:40:31 +0800 Subject: [PATCH 151/249] Update README.md --- persistence-modules/java-mongodb/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-mongodb/README.md b/persistence-modules/java-mongodb/README.md index 2c25cf5392..6f6bcba250 100644 --- a/persistence-modules/java-mongodb/README.md +++ b/persistence-modules/java-mongodb/README.md @@ -17,3 +17,4 @@ This module contains articles about MongoDB in Java. - [Update Documents in MongoDB](https://www.baeldung.com/mongodb-update-documents) - [Check Collection Existence in MongoDB](https://www.baeldung.com/java-check-collection-existence-mongodb) - [Case Insensitive Sorting in MongoDB](https://www.baeldung.com/java-mongodb-case-insensitive-sorting) +- [Push and Set Operations in Same MongoDB Update](https://www.baeldung.com/java-mongodb-push-set) From f20653b61653cb6a2ab6e1b6f73f17940d712ca4 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:42:19 +0800 Subject: [PATCH 152/249] Create README.md --- nginx-forward-proxy/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 nginx-forward-proxy/README.md diff --git a/nginx-forward-proxy/README.md b/nginx-forward-proxy/README.md new file mode 100644 index 0000000000..68ef37dcfb --- /dev/null +++ b/nginx-forward-proxy/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Using Nginx as a Forward Proxy](https://www.baeldung.com/nginx-forward-proxy) From 49630dc2f8379eb38967974fab9aa6a423d581ca Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:45:47 +0800 Subject: [PATCH 153/249] Update README.md --- core-java-modules/core-java-exceptions-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-exceptions-4/README.md b/core-java-modules/core-java-exceptions-4/README.md index e77787a8a3..7df8ef65b9 100644 --- a/core-java-modules/core-java-exceptions-4/README.md +++ b/core-java-modules/core-java-exceptions-4/README.md @@ -2,3 +2,4 @@ - [Java ArrayIndexOutOfBoundsException](https://www.baeldung.com/java-arrayindexoutofboundsexception) - [Java Missing Return Statement](https://www.baeldung.com/java-missing-return-statement) +- [Convert long to int Type in Java](https://www.baeldung.com/java-convert-long-to-int) From 743ccdec161767e83806fe0030acb051faed8aa6 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:47:44 +0800 Subject: [PATCH 154/249] Update README.md --- java-numbers-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/java-numbers-4/README.md b/java-numbers-4/README.md index f053a82b80..a6d866218c 100644 --- a/java-numbers-4/README.md +++ b/java-numbers-4/README.md @@ -4,3 +4,4 @@ - [Understanding the & 0xff Value in Java](https://www.baeldung.com/java-and-0xff) - [Determine if an Integer’s Square Root Is an Integer in Java](https://www.baeldung.com/java-find-if-square-root-is-integer) - [Guide to Java BigInteger](https://www.baeldung.com/java-biginteger) +- [Automorphic Numbers in Java](https://www.baeldung.com/java-automorphic-numbers) From 8439ee3c455a06004159e54fc0f301be0779692f Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:50:01 +0800 Subject: [PATCH 155/249] Update README.md --- core-java-modules/core-java-lang-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-lang-4/README.md b/core-java-modules/core-java-lang-4/README.md index e2a74b36af..a145633d2b 100644 --- a/core-java-modules/core-java-lang-4/README.md +++ b/core-java-modules/core-java-lang-4/README.md @@ -10,3 +10,4 @@ This module contains articles about core features in the Java language - [Tiered Compilation in JVM](https://www.baeldung.com/jvm-tiered-compilation) - [Fixing the “Declared package does not match the expected package” Error](https://www.baeldung.com/java-declared-expected-package-error) - [Chaining Constructors in Java](https://www.baeldung.com/java-chain-constructors) +- [Difference Between POJO, JavaBeans, DTO and VO](https://www.baeldung.com/java-pojo-javabeans-dto-vo) From 3d4c951f3e24fc8b83d18ea16202e5d8c456b142 Mon Sep 17 00:00:00 2001 From: sampadawagde Date: Wed, 16 Mar 2022 21:24:03 +0530 Subject: [PATCH 156/249] JAVA-10136: Fix references to parents --- reactive-systems/inventory-service/pom.xml | 3 +-- reactive-systems/order-service/pom.xml | 3 +-- reactive-systems/pom.xml | 5 +++-- reactive-systems/shipping-service/pom.xml | 3 +-- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/reactive-systems/inventory-service/pom.xml b/reactive-systems/inventory-service/pom.xml index 86575d498c..4aeec24922 100644 --- a/reactive-systems/inventory-service/pom.xml +++ b/reactive-systems/inventory-service/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + reactive-systems 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/reactive-systems/order-service/pom.xml b/reactive-systems/order-service/pom.xml index e6453732b4..b9e5d36d3a 100644 --- a/reactive-systems/order-service/pom.xml +++ b/reactive-systems/order-service/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + reactive-systems 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/reactive-systems/pom.xml b/reactive-systems/pom.xml index 81462090b8..b984fc7cd8 100644 --- a/reactive-systems/pom.xml +++ b/reactive-systems/pom.xml @@ -10,8 +10,9 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 diff --git a/reactive-systems/shipping-service/pom.xml b/reactive-systems/shipping-service/pom.xml index f725ca72d1..5fac674bbc 100644 --- a/reactive-systems/shipping-service/pom.xml +++ b/reactive-systems/shipping-service/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + reactive-systems 0.0.1-SNAPSHOT - ../../parent-boot-2 From 054a3bcda4a3f4fc297b28977fb10f41e43ea1ac Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Thu, 17 Mar 2022 15:56:59 +0530 Subject: [PATCH 157/249] JAVA-10083 Changes as per review comments --- persistence-modules/hibernate-queries/pom.xml | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/persistence-modules/hibernate-queries/pom.xml b/persistence-modules/hibernate-queries/pom.xml index f0307a6eaf..4f5de5c06e 100644 --- a/persistence-modules/hibernate-queries/pom.xml +++ b/persistence-modules/hibernate-queries/pom.xml @@ -82,33 +82,12 @@ ${jmh-generator.version} - - com.sun.xml.bind - jaxb-core - ${com.sun.xml.version} - - - javax.xml.bind - jaxb-api - ${javax.xml.bind.version} - - - com.sun.xml.bind - jaxb-impl - ${com.sun.xml.version} - - 5.0.2.RELEASE 1.10.6.RELEASE - - 5.2.10.Final 9.0.0.M26 - 2.3.4 - 2.3.0.1 - 2.3.1 6.0.6 2.2.3 From 7c6e2a770df722a9a6bfe732eee170baa24a56c6 Mon Sep 17 00:00:00 2001 From: kwoyke Date: Thu, 17 Mar 2022 11:44:37 +0100 Subject: [PATCH 158/249] JAVA-10455: Upgrade parent-boot-2 to Spring Boot 2.6.4 (#11932) --- parent-boot-2/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index b7f33de237..85f1805a00 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -88,7 +88,7 @@ 3.3.0 1.0.22.RELEASE - 2.6.3 + 2.6.4 1.9.1 From 2ba43ea76b7a6678dc90e32974ba97fbc8a0d080 Mon Sep 17 00:00:00 2001 From: sampadawagde Date: Thu, 17 Mar 2022 22:06:38 +0530 Subject: [PATCH 159/249] JAVA-10132: Align module names, folder names and artifact id --- jakarta-ee/pom.xml | 47 ++++++++---------- persistence-modules/fauna/pom.xml | 26 ++++++---- spring-cloud/pom.xml | 2 +- .../README.md | 0 .../pom.xml | 0 .../.gitignore | 0 .../.mvn/wrapper/MavenWrapperDownloader.java | 0 .../.mvn/wrapper/maven-wrapper.jar | Bin .../.mvn/wrapper/maven-wrapper.properties | 0 .../spring-cloud-loadbalancer-client/mvnw | 0 .../spring-cloud-loadbalancer-client/mvnw.cmd | 0 .../spring-cloud-loadbalancer-client/pom.xml | 0 .../client/ClientApplication.java | 0 .../src/main/resources/application.properties | 0 .../.gitignore | 0 .../.mvn/wrapper/MavenWrapperDownloader.java | 0 .../.mvn/wrapper/maven-wrapper.jar | Bin .../.mvn/wrapper/maven-wrapper.properties | 0 .../spring-cloud-loadbalancer-server/mvnw | 0 .../spring-cloud-loadbalancer-server/mvnw.cmd | 0 .../spring-cloud-loadbalancer-server/pom.xml | 0 .../server/ServerApplication.java | 0 .../src/main/resources/application.properties | 0 23 files changed, 38 insertions(+), 37 deletions(-) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/README.md (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/pom.xml (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-client/.gitignore (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-client/.mvn/wrapper/MavenWrapperDownloader.java (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-client/.mvn/wrapper/maven-wrapper.jar (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-client/.mvn/wrapper/maven-wrapper.properties (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-client/mvnw (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-client/mvnw.cmd (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-client/pom.xml (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-client/src/main/java/com/baeldung/spring/cloud/loadbalancer/client/ClientApplication.java (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-client/src/main/resources/application.properties (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-server/.gitignore (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-server/.mvn/wrapper/MavenWrapperDownloader.java (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-server/.mvn/wrapper/maven-wrapper.jar (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-server/.mvn/wrapper/maven-wrapper.properties (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-server/mvnw (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-server/mvnw.cmd (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-server/pom.xml (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-server/src/main/java/com/baeldung/spring/cloud/loadbalancer/server/ServerApplication.java (100%) rename spring-cloud/{spring-cloud-load-balancer => spring-cloud-loadbalancer}/spring-cloud-loadbalancer-server/src/main/resources/application.properties (100%) diff --git a/jakarta-ee/pom.xml b/jakarta-ee/pom.xml index 074ca1eec8..dea4437345 100644 --- a/jakarta-ee/pom.xml +++ b/jakarta-ee/pom.xml @@ -1,28 +1,13 @@ - + 4.0.0 - com.baeldung - mvc-2.0 + jakarta-ee 1.0-SNAPSHOT + jakarta-ee war - mvc-2.0 - - - 9.0.0 - 2.0.0 - 2.0.0 - 5.8.2 - C:/glassfish6 - admin - mvn-domain - 1.10.19 - - ${local.glassfish.home}\\domains\\${local.glassfish.domain}\\config\\domain-passwords - - - jakarta.platform @@ -30,13 +15,11 @@ ${jakartaee-api.version} provided - jakarta.mvc jakarta.mvc-api ${jakarta.mvc-api.version} - org.eclipse.krazo krazo-jersey @@ -54,7 +37,6 @@ ${mockito.version} test - @@ -67,7 +49,7 @@ ${local.glassfish.home} admin - + password @@ -108,4 +90,19 @@ - + + + 9.0.0 + 2.0.0 + 2.0.0 + 5.8.2 + C:/glassfish6 + admin + mvn-domain + 1.10.19 + + ${local.glassfish.home}\\domains\\${local.glassfish.domain}\\config\\domain-passwords + + + + \ No newline at end of file diff --git a/persistence-modules/fauna/pom.xml b/persistence-modules/fauna/pom.xml index 67aabb7501..ff18865e5f 100644 --- a/persistence-modules/fauna/pom.xml +++ b/persistence-modules/fauna/pom.xml @@ -1,21 +1,21 @@ - 4.0.0 + com.baeldung + fauna + 0.0.1-SNAPSHOT + fauna + Blogging Service built with FaunaDB + org.springframework.boot spring-boot-starter-parent 2.6.2 - + - com.baeldung - fauna-blog - 0.0.1-SNAPSHOT - fauna-blog - Blogging Service built with FaunaDB - - 17 - + org.springframework.boot @@ -53,4 +53,8 @@ - + + 17 + + + \ No newline at end of file diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml index 75010fbd34..c5ebb4116a 100644 --- a/spring-cloud/pom.xml +++ b/spring-cloud/pom.xml @@ -17,7 +17,7 @@ - spring-cloud-load-balancer + spring-cloud-loadbalancer spring-cloud-config spring-cloud-eureka spring-cloud-hystrix diff --git a/spring-cloud/spring-cloud-load-balancer/README.md b/spring-cloud/spring-cloud-loadbalancer/README.md similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/README.md rename to spring-cloud/spring-cloud-loadbalancer/README.md diff --git a/spring-cloud/spring-cloud-load-balancer/pom.xml b/spring-cloud/spring-cloud-loadbalancer/pom.xml similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/pom.xml rename to spring-cloud/spring-cloud-loadbalancer/pom.xml diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/.gitignore b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/.gitignore similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/.gitignore rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/.gitignore diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/.mvn/wrapper/MavenWrapperDownloader.java b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/.mvn/wrapper/MavenWrapperDownloader.java similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/.mvn/wrapper/MavenWrapperDownloader.java rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/.mvn/wrapper/MavenWrapperDownloader.java diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/.mvn/wrapper/maven-wrapper.jar b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/.mvn/wrapper/maven-wrapper.jar rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/.mvn/wrapper/maven-wrapper.jar diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/.mvn/wrapper/maven-wrapper.properties b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/.mvn/wrapper/maven-wrapper.properties rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/.mvn/wrapper/maven-wrapper.properties diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/mvnw b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/mvnw similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/mvnw rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/mvnw diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/mvnw.cmd b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/mvnw.cmd similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/mvnw.cmd rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/mvnw.cmd diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/pom.xml b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/pom.xml similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/pom.xml rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/pom.xml diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/src/main/java/com/baeldung/spring/cloud/loadbalancer/client/ClientApplication.java b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/src/main/java/com/baeldung/spring/cloud/loadbalancer/client/ClientApplication.java similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/src/main/java/com/baeldung/spring/cloud/loadbalancer/client/ClientApplication.java rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/src/main/java/com/baeldung/spring/cloud/loadbalancer/client/ClientApplication.java diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/src/main/resources/application.properties b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/src/main/resources/application.properties similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-client/src/main/resources/application.properties rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-client/src/main/resources/application.properties diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/.gitignore b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/.gitignore similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/.gitignore rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/.gitignore diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/.mvn/wrapper/MavenWrapperDownloader.java b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/.mvn/wrapper/MavenWrapperDownloader.java similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/.mvn/wrapper/MavenWrapperDownloader.java rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/.mvn/wrapper/MavenWrapperDownloader.java diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/.mvn/wrapper/maven-wrapper.jar b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/.mvn/wrapper/maven-wrapper.jar rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/.mvn/wrapper/maven-wrapper.jar diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/.mvn/wrapper/maven-wrapper.properties b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/.mvn/wrapper/maven-wrapper.properties rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/.mvn/wrapper/maven-wrapper.properties diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/mvnw b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/mvnw similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/mvnw rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/mvnw diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/mvnw.cmd b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/mvnw.cmd similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/mvnw.cmd rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/mvnw.cmd diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/pom.xml b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/pom.xml similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/pom.xml rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/pom.xml diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/src/main/java/com/baeldung/spring/cloud/loadbalancer/server/ServerApplication.java b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/src/main/java/com/baeldung/spring/cloud/loadbalancer/server/ServerApplication.java similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/src/main/java/com/baeldung/spring/cloud/loadbalancer/server/ServerApplication.java rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/src/main/java/com/baeldung/spring/cloud/loadbalancer/server/ServerApplication.java diff --git a/spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/src/main/resources/application.properties b/spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/src/main/resources/application.properties similarity index 100% rename from spring-cloud/spring-cloud-load-balancer/spring-cloud-loadbalancer-server/src/main/resources/application.properties rename to spring-cloud/spring-cloud-loadbalancer/spring-cloud-loadbalancer-server/src/main/resources/application.properties From d01b0734d32a6084917cb18a24fb62a426985b14 Mon Sep 17 00:00:00 2001 From: AttilaUhrin Date: Fri, 18 Mar 2022 04:16:47 +0100 Subject: [PATCH 160/249] [BAEL-5373] A Guide to @DBRef in MongoDB (#11909) * Add implementation for BAEL-5373. * Fix test class name. * Change collection names to be aligned with article. --- .../mongodb/dbref/DbRefApplication.java | 13 ++++ .../baeldung/mongodb/dbref/DbRefTester.java | 26 +++++++ .../baeldung/mongodb/dbref/model/Person.java | 49 ++++++++++++ .../com/baeldung/mongodb/dbref/model/Pet.java | 29 ++++++++ .../dbref/repository/PersonRepository.java | 9 +++ .../mongodb/dbref/DbRefIntegrationTest.java | 74 +++++++++++++++++++ 6 files changed, 200 insertions(+) create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/DbRefApplication.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/DbRefTester.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/model/Person.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/model/Pet.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/repository/PersonRepository.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/mongodb/dbref/DbRefIntegrationTest.java diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/DbRefApplication.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/DbRefApplication.java new file mode 100644 index 0000000000..b358b3b974 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/DbRefApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.mongodb.dbref; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DbRefApplication { + + public static void main(String... args) { + SpringApplication.run(DbRefApplication.class, args); + } + +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/DbRefTester.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/DbRefTester.java new file mode 100644 index 0000000000..58641e1258 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/DbRefTester.java @@ -0,0 +1,26 @@ +package com.baeldung.mongodb.dbref; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; + +import com.baeldung.mongodb.dbref.repository.PersonRepository; + +@Component +public class DbRefTester implements ApplicationRunner { + + private static final Logger logger = LoggerFactory.getLogger(DbRefTester.class); + + @Autowired + private PersonRepository personRepository; + + @Override + public void run(ApplicationArguments args) throws Exception { + logger.info("{}", personRepository.findAll()); + + } + +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/model/Person.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/model/Person.java new file mode 100644 index 0000000000..7b7826e716 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/model/Person.java @@ -0,0 +1,49 @@ +package com.baeldung.mongodb.dbref.model; + +import java.util.List; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.DBRef; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document(collection = "Person") +public class Person { + + @Id + private String id; + + private String name; + + @DBRef + private List pets; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public List getPets() { + return pets; + } + + public void setPets(List pets) { + this.pets = pets; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "Person [id=" + id + ", name=" + name + ", pets=" + pets + "]"; + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/model/Pet.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/model/Pet.java new file mode 100644 index 0000000000..1b83d4ca23 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/model/Pet.java @@ -0,0 +1,29 @@ +package com.baeldung.mongodb.dbref.model; + +public class Pet { + + private String id; + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public String toString() { + return "Pet [id=" + id + ", name=" + name + "]"; + } + +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/repository/PersonRepository.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/repository/PersonRepository.java new file mode 100644 index 0000000000..2ef5a9dbd6 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/repository/PersonRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.mongodb.dbref.repository; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.mongodb.dbref.model.Person; + +public interface PersonRepository extends MongoRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/mongodb/dbref/DbRefIntegrationTest.java b/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/mongodb/dbref/DbRefIntegrationTest.java new file mode 100644 index 0000000000..c357c0283c --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/mongodb/dbref/DbRefIntegrationTest.java @@ -0,0 +1,74 @@ +package com.baeldung.mongodb.dbref; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.mongodb.dbref.model.Person; +import com.baeldung.mongodb.dbref.model.Pet; +import com.baeldung.mongodb.dbref.repository.PersonRepository; +import com.mongodb.BasicDBObjectBuilder; +import com.mongodb.DBObject; +import com.mongodb.DBRef; + +@RunWith(SpringRunner.class) +@SpringBootTest +@DirtiesContext +public class DbRefIntegrationTest { + + @Autowired + PersonRepository personRepository; + + @Autowired + private MongoTemplate mongoTemplate; + + @Test + public void givenPetsAndPersonInDatabase_whenListPersons_thenReferenceIsFetched() { + // given + DBObject catInDatabase = BasicDBObjectBuilder.start() + .add("name", "Loki") + .get(); + + DBObject dogInDatabase = BasicDBObjectBuilder.start() + .add("name", "Max") + .get(); + + mongoTemplate.save(catInDatabase, "Cat"); + mongoTemplate.save(dogInDatabase, "Dog"); + + List petsReference = new ArrayList(); + petsReference.add(new DBRef("Cat", catInDatabase.get("_id"))); + petsReference.add(new DBRef("Dog", dogInDatabase.get("_id"))); + + DBObject personInDatabase = BasicDBObjectBuilder.start() + .add("name", "Bob") + .add("pets", petsReference) + .get(); + + mongoTemplate.save(personInDatabase, "Person"); + + // when + List persons = personRepository.findAll(); + + // then + assertThat(persons).hasSize(1); + Person person = persons.get(0); + assertEquals("Bob", person.getName()); + + List pets = person.getPets(); + assertThat(pets).hasSize(2); + assertThat(pets).anyMatch(pet -> "Loki".equals(pet.getName())); + assertThat(pets).anyMatch(pet -> "Max".equals(pet.getName())); + } + +} From c6a8b181b8cce33c0a1bd3d77a8f9bcdd178c635 Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Fri, 18 Mar 2022 08:00:13 +0100 Subject: [PATCH 161/249] JAVA-10238: Use random port in the integration test --- .../rpc/finagle/FinagleIntegrationTest.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/libraries-rpc/src/test/java/com/baeldung/rpc/finagle/FinagleIntegrationTest.java b/libraries-rpc/src/test/java/com/baeldung/rpc/finagle/FinagleIntegrationTest.java index 8dcdb19e7e..a73761f9f7 100644 --- a/libraries-rpc/src/test/java/com/baeldung/rpc/finagle/FinagleIntegrationTest.java +++ b/libraries-rpc/src/test/java/com/baeldung/rpc/finagle/FinagleIntegrationTest.java @@ -10,16 +10,23 @@ import com.twitter.util.Future; import org.junit.Test; import scala.runtime.BoxedUnit; +import java.io.IOException; +import java.net.ServerSocket; + import static org.junit.Assert.assertEquals; public class FinagleIntegrationTest { + + private static final int DEFAULT_PORT = 8079; + @Test public void givenServerAndClient_whenRequestSent_thenClientShouldReceiveResponseFromServer() throws Exception { // given + int port = randomPort(); Service serverService = new LogFilter().andThen(new GreetingService()); - Http.serve(":8080", serverService); + Http.serve(":" + port, serverService); - Service clientService = new LogFilter().andThen(Http.newService(":8080")); + Service clientService = new LogFilter().andThen(Http.newService(":" + port)); // when Request request = Request.apply(Method.Get(), "/?name=John"); @@ -37,4 +44,13 @@ public class FinagleIntegrationTest { }) ); } + + private int randomPort() { + try (ServerSocket socket = new ServerSocket(0)) { + return socket.getLocalPort(); + + } catch (IOException e) { + return DEFAULT_PORT; + } + } } From 1b9bbe538b7863c12b9bd2a51ac3e8a89a808de6 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Sat, 19 Mar 2022 16:50:31 +0000 Subject: [PATCH 162/249] [JAVA-8146] Update artifact versions --- spring-reactive/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-reactive/pom.xml b/spring-reactive/pom.xml index d755c03ae0..37df1a820d 100644 --- a/spring-reactive/pom.xml +++ b/spring-reactive/pom.xml @@ -94,9 +94,9 @@ - 3.4.12 - 1.2.2.RELEASE - 2.2.19 + 3.4.16 + 1.3.10 + 2.2.21 \ No newline at end of file From 10bde9d0af4fe39a18cbc2f90a7caf9f7e4b04ae Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Sat, 19 Mar 2022 18:27:30 +0000 Subject: [PATCH 163/249] [JAVA-10500] Investigate and reduce springdoc build time --- .../spring-boot-springdoc/pom.xml | 55 ----------- .../restdocopenapi/FooController.java | 5 +- .../src/main/resources/logback.xml | 5 +- .../restdoc/SpringRestDocsUnitTest.java | 96 +++++++++++-------- .../baeldung/springdoc/SpringContextTest.java | 14 +-- .../{logback.xml => logback-test.xml} | 0 6 files changed, 66 insertions(+), 109 deletions(-) rename spring-boot-modules/spring-boot-springdoc/src/test/resources/{logback.xml => logback-test.xml} (100%) diff --git a/spring-boot-modules/spring-boot-springdoc/pom.xml b/spring-boot-modules/spring-boot-springdoc/pom.xml index d13efba450..e7d4a35d97 100644 --- a/spring-boot-modules/spring-boot-springdoc/pom.xml +++ b/spring-boot-modules/spring-boot-springdoc/pom.xml @@ -37,10 +37,6 @@ spring-boot-starter-test test - - org.hibernate - hibernate-core - org.springdoc @@ -63,21 +59,6 @@ spring-restdocs-restassured test - - - org.springdoc - springdoc-openapi-kotlin - ${springdoc.version} - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-reflect - @@ -109,41 +90,6 @@ - - - kotlin-maven-plugin - org.jetbrains.kotlin - ${kotlin.version} - - - spring - - ${java.version} - - - - compile - compile - - compile - - - - test-compile - test-compile - - test-compile - - - - - - org.jetbrains.kotlin - kotlin-maven-allopen - ${kotlin.version} - - - @@ -208,7 +154,6 @@ 1.6.4 1.5.6 - 1.6.0 ${project.build.directory}/generated-snippets diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/restdocopenapi/FooController.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/restdocopenapi/FooController.java index 55c2cccb3c..892eb05f8d 100644 --- a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/restdocopenapi/FooController.java +++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/restdocopenapi/FooController.java @@ -40,7 +40,8 @@ public class FooController { public ResponseEntity getFooById(@PathVariable("id") Long id) { Optional foo = repository.findById(id); - return foo.isPresent() ? new ResponseEntity<>(foo.get(), HttpStatus.OK) : new ResponseEntity<>(HttpStatus.NOT_FOUND); + return foo.map(value -> new ResponseEntity<>(value, HttpStatus.OK)) + .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND)); } @PostMapping @@ -70,7 +71,7 @@ public class FooController { @PutMapping("/{id}") public ResponseEntity updateFoo(@PathVariable("id") long id, @RequestBody Foo foo) { - boolean isFooPresent = repository.existsById(Long.valueOf(id)); + boolean isFooPresent = repository.existsById(id); if (!isFooPresent) { return new ResponseEntity<>(HttpStatus.NOT_FOUND); diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/resources/logback.xml b/spring-boot-modules/spring-boot-springdoc/src/main/resources/logback.xml index 6a07b178e9..73dd672c1a 100644 --- a/spring-boot-modules/spring-boot-springdoc/src/main/resources/logback.xml +++ b/spring-boot-modules/spring-boot-springdoc/src/main/resources/logback.xml @@ -7,10 +7,7 @@ - - - - + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-springdoc/src/test/java/com/baeldung/restdocopenapi/restdoc/SpringRestDocsUnitTest.java b/spring-boot-modules/spring-boot-springdoc/src/test/java/com/baeldung/restdocopenapi/restdoc/SpringRestDocsUnitTest.java index 4d37abf78a..41e870e2e8 100644 --- a/spring-boot-modules/spring-boot-springdoc/src/test/java/com/baeldung/restdocopenapi/restdoc/SpringRestDocsUnitTest.java +++ b/spring-boot-modules/spring-boot-springdoc/src/test/java/com/baeldung/restdocopenapi/restdoc/SpringRestDocsUnitTest.java @@ -1,6 +1,32 @@ package com.baeldung.restdocopenapi.restdoc; +import com.baeldung.restdocopenapi.Foo; +import com.baeldung.restdocopenapi.FooController; +import com.baeldung.restdocopenapi.FooRepository; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.hateoas.MediaTypes; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.restdocs.constraints.ConstraintDescriptions; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import static java.util.Collections.singletonList; import static org.hamcrest.Matchers.containsString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete; @@ -15,99 +41,89 @@ import static org.springframework.restdocs.payload.PayloadDocumentation.requestF import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.util.StringUtils.collectionToDelimitedString; -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.hateoas.MediaTypes; -import org.springframework.restdocs.RestDocumentationContextProvider; -import org.springframework.restdocs.RestDocumentationExtension; -import org.springframework.restdocs.constraints.ConstraintDescriptions; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -import com.baeldung.restdocopenapi.Application; -import com.baeldung.restdocopenapi.Foo; -import com.fasterxml.jackson.databind.ObjectMapper; - @ExtendWith({ RestDocumentationExtension.class, SpringExtension.class }) -@SpringBootTest(classes = Application.class) -public class SpringRestDocsUnitTest { +@WebMvcTest(FooController.class) +class SpringRestDocsUnitTest { private MockMvc mockMvc; - + + @MockBean + private FooRepository fooRepository; + @Autowired private ObjectMapper objectMapper; @BeforeEach - public void setup(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) { + void setup(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) { this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) .apply(documentationConfiguration(restDocumentation)) .build(); } @Test - public void whenGetFoo_thenSuccessful() throws Exception { + void whenGetAllFoo_thenSuccessful() throws Exception { + when(fooRepository.findAll()) + .thenReturn(singletonList(new Foo(1, "Foo 1", "Foo 1"))); + this.mockMvc.perform(get("/foo")) - .andDo(print()) .andExpect(status().isOk()) .andExpect(content().string(containsString("Foo 1"))) .andDo(document("getAllFoos")); } @Test - public void whenGetFooById_thenSuccessful() throws Exception { + void whenGetFooById_thenSuccessful() throws Exception { ConstraintDescriptions desc = new ConstraintDescriptions(Foo.class); + when(fooRepository.findById(1L)) + .thenReturn(Optional.of(new Foo(1, "title", "body"))); + this.mockMvc.perform(get("/foo/{id}", 1)) .andExpect(status().isOk()) - .andDo(document("getAFoo", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), + .andDo(document("getAFoo", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), pathParameters(parameterWithName("id").description("id of foo to be searched")), responseFields(fieldWithPath("id").description("The id of the foo" + collectionToDelimitedString(desc.descriptionsForProperty("id"), ". ")), fieldWithPath("title").description("The title of the foo"), fieldWithPath("body").description("The body of the foo")))); } @Test - public void whenPostFoo_thenSuccessful() throws Exception { + void whenPostFoo_thenSuccessful() throws Exception { Map foo = new HashMap<>(); foo.put("id", 4L); foo.put("title", "New Foo"); foo.put("body", "Body of New Foo"); - + this.mockMvc.perform(post("/foo").contentType(MediaTypes.HAL_JSON) .content(this.objectMapper.writeValueAsString(foo))) .andExpect(status().isCreated()) .andDo(document("createFoo", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), requestFields(fieldWithPath("id").description("The id of the foo"), fieldWithPath("title").description("The title of the foo"), fieldWithPath("body").description("The body of the foo")))); } - + @Test - public void whenDeleteFoo_thenSuccessful() throws Exception { + void whenDeleteFoo_thenSuccessful() throws Exception { this.mockMvc.perform(delete("/foo/{id}", 2)) .andExpect(status().isNoContent()) .andDo(document("deleteFoo", pathParameters(parameterWithName("id").description("The id of the foo to delete")))); } - + @Test - public void whenUpdateFoo_thenSuccessful() throws Exception { - + void whenUpdateFoo_thenSuccessful() throws Exception { + + when(fooRepository.existsById(3L)).thenReturn(true); + when(fooRepository.save(any(Foo.class))) + .thenReturn(new Foo(3, "Updated Foo", "Body of updated Foo")); + ConstraintDescriptions desc = new ConstraintDescriptions(Foo.class); - + Map foo = new HashMap<>(); foo.put("title", "Updated Foo"); foo.put("body", "Body of Updated Foo"); - + this.mockMvc.perform(put("/foo/{id}", 3).contentType(MediaTypes.HAL_JSON) .content(this.objectMapper.writeValueAsString(foo))) .andExpect(status().isOk()) @@ -115,6 +131,4 @@ public class SpringRestDocsUnitTest { responseFields(fieldWithPath("id").description("The id of the updated foo" + collectionToDelimitedString(desc.descriptionsForProperty("id"), ". ")), fieldWithPath("title").description("The title of the updated foo"), fieldWithPath("body").description("The body of the updated foo")))); } - - } diff --git a/spring-boot-modules/spring-boot-springdoc/src/test/java/com/baeldung/springdoc/SpringContextTest.java b/spring-boot-modules/spring-boot-springdoc/src/test/java/com/baeldung/springdoc/SpringContextTest.java index 4cd84477b9..d7cd6bc30b 100644 --- a/spring-boot-modules/spring-boot-springdoc/src/test/java/com/baeldung/springdoc/SpringContextTest.java +++ b/spring-boot-modules/spring-boot-springdoc/src/test/java/com/baeldung/springdoc/SpringContextTest.java @@ -1,17 +1,17 @@ package com.baeldung.springdoc; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; -@RunWith(SpringRunner.class) +@ExtendWith(SpringExtension.class) @SpringBootTest -public class SpringContextTest { +class SpringContextTest { @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - + void whenSpringContextIsBootstrapped_thenNoExceptions() { + } } diff --git a/spring-boot-modules/spring-boot-springdoc/src/test/resources/logback.xml b/spring-boot-modules/spring-boot-springdoc/src/test/resources/logback-test.xml similarity index 100% rename from spring-boot-modules/spring-boot-springdoc/src/test/resources/logback.xml rename to spring-boot-modules/spring-boot-springdoc/src/test/resources/logback-test.xml From c6e2b905f5010c22fc21198433be3c26233e4734 Mon Sep 17 00:00:00 2001 From: ACHRAF TAITAI <43656331+achraftt@users.noreply.github.com> Date: Sun, 20 Mar 2022 08:45:32 +0100 Subject: [PATCH 164/249] BAEL-5413: populate a drop down with a list (#11947) --- .../dropDownList/DropDownListController.java | 24 +++++++++++++++++++ .../templates/dropDownList/dropDownList.html | 14 +++++++++++ 2 files changed, 38 insertions(+) create mode 100644 spring-web-modules/spring-thymeleaf-3/src/main/java/com/baeldung/thymeleaf/dropDownList/DropDownListController.java create mode 100644 spring-web-modules/spring-thymeleaf-3/src/main/resources/templates/dropDownList/dropDownList.html diff --git a/spring-web-modules/spring-thymeleaf-3/src/main/java/com/baeldung/thymeleaf/dropDownList/DropDownListController.java b/spring-web-modules/spring-thymeleaf-3/src/main/java/com/baeldung/thymeleaf/dropDownList/DropDownListController.java new file mode 100644 index 0000000000..ba1f1b0a49 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-3/src/main/java/com/baeldung/thymeleaf/dropDownList/DropDownListController.java @@ -0,0 +1,24 @@ +package com.baeldung.thymeleaf.dropDownList; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.util.ArrayList; +import java.util.List; + +@Controller +public class DropDownListController { + + @RequestMapping(value = "/populateDropDownList", method = RequestMethod.GET) public String populateList(Model model) { + List options = new ArrayList(); + options.add("option 1"); + options.add("option 2"); + options.add("option 3"); + options.add("option 4"); + model.addAttribute("options", options); + return "dropDownList/dropDownList.html"; + } + +} diff --git a/spring-web-modules/spring-thymeleaf-3/src/main/resources/templates/dropDownList/dropDownList.html b/spring-web-modules/spring-thymeleaf-3/src/main/resources/templates/dropDownList/dropDownList.html new file mode 100644 index 0000000000..cc2c504b32 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-3/src/main/resources/templates/dropDownList/dropDownList.html @@ -0,0 +1,14 @@ + + + +Populate a drop down with a list using thymeleaf + + +

Populate a drop down with a list using thymeleaf

+ + + From 2e4b518c4b039d0480bd5a25d50714e9d1956691 Mon Sep 17 00:00:00 2001 From: Azhwani <13301425+azhwani@users.noreply.github.com> Date: Sun, 20 Mar 2022 15:19:29 +0100 Subject: [PATCH 165/249] improve split string using pattern (#11945) --- .../split/SplitStringEveryNthChar.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/split/SplitStringEveryNthChar.java b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/split/SplitStringEveryNthChar.java index 3ac31d012a..0687926cd2 100644 --- a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/split/SplitStringEveryNthChar.java +++ b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/split/SplitStringEveryNthChar.java @@ -3,8 +3,9 @@ package com.baeldung.split; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.regex.Matcher; +import java.util.regex.MatchResult; import java.util.regex.Pattern; +import java.util.stream.Collectors; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; @@ -29,16 +30,11 @@ public class SplitStringEveryNthChar { } public static List usingPattern(String text, int n) { - List results = new ArrayList<>(); - - Pattern pattern = Pattern.compile(".{1," + n + "}"); - Matcher matcher = pattern.matcher(text); - while (matcher.find()) { - String match = text.substring(matcher.start(), matcher.end()); - results.add(match); - } - - return results; + return Pattern.compile(".{1," + n + "}") + .matcher(text) + .results() + .map(MatchResult::group) + .collect(Collectors.toList()); } public static List usingGuava(String text, int n) { From 79857f04ae7e40341b89488989b1a80dfc143cc9 Mon Sep 17 00:00:00 2001 From: Attila Uhrin Date: Mon, 21 Mar 2022 17:43:35 +0100 Subject: [PATCH 166/249] Fix integration tests. --- .../main/java/com/baeldung/mongodb/dbref/DbRefApplication.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/DbRefApplication.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/DbRefApplication.java index b358b3b974..a9101b36a0 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/DbRefApplication.java +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/dbref/DbRefApplication.java @@ -2,8 +2,10 @@ package com.baeldung.mongodb.dbref; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; @SpringBootApplication +@EnableMongoRepositories(basePackages = { "com.baeldung" }) public class DbRefApplication { public static void main(String... args) { From f7420526f4a2f93f6d7405887f5d0cba52fee304 Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Tue, 22 Mar 2022 10:01:46 +0100 Subject: [PATCH 167/249] JAVA-10236: Fix a typo --- .../java/com/baeldung/springnativeintro/SpringNativeApp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-native/src/main/java/com/baeldung/springnativeintro/SpringNativeApp.java b/spring-native/src/main/java/com/baeldung/springnativeintro/SpringNativeApp.java index fa54d34f9f..c2bbd8fa43 100644 --- a/spring-native/src/main/java/com/baeldung/springnativeintro/SpringNativeApp.java +++ b/spring-native/src/main/java/com/baeldung/springnativeintro/SpringNativeApp.java @@ -3,7 +3,7 @@ package com.baeldung.springnativeintro; public class SpringNativeApp { public static void main(String[] args) { - System.out.println("Hello, World! This is a Baledung Spring Native Application"); + System.out.println("Hello, World! This is a Baeldung Spring Native Application"); } } From 6810dd9c66852922d64fdd2f60949d5f17670fa8 Mon Sep 17 00:00:00 2001 From: PentaKon Date: Tue, 22 Mar 2022 11:06:23 +0200 Subject: [PATCH 168/249] Change log statements to assert statements on test app --- .../com/baeldung/resultsetrowcount/RowCounterApp.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/RowCounterApp.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/RowCounterApp.java index 8e22bb01af..3e142ad354 100644 --- a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/RowCounterApp.java +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultsetrowcount/RowCounterApp.java @@ -1,8 +1,5 @@ package com.baeldung.resultsetrowcount; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; @@ -10,18 +7,16 @@ import java.sql.Statement; class RowCounterApp { - static Logger logger = LoggerFactory.getLogger(RowCounterApp.class); - public static void main(String[] args) throws SQLException { Connection conn = createDummyDB(); String selectQuery = "SELECT * FROM STORAGE"; StandardRowCounter standardCounter = new StandardRowCounter(conn); - logger.info("Standard counter count: {}", standardCounter.getQueryRowCount(selectQuery)); + assert standardCounter.getQueryRowCount(selectQuery) == 3; ScrollableRowCounter scrollableCounter = new ScrollableRowCounter(conn); - logger.info("Scrollable counter count: {}", scrollableCounter.getQueryRowCount(selectQuery)); + assert scrollableCounter.getQueryRowCount(selectQuery) == 3; } static Connection createDummyDB() throws SQLException { From 8f7a2b766251f41a94057ab8bf44f3da54df5a7b Mon Sep 17 00:00:00 2001 From: kwoyke Date: Tue, 22 Mar 2022 13:54:59 +0100 Subject: [PATCH 169/249] JAVA-9857: Remove overriden spring-boot.version property (#11956) --- persistence-modules/spring-data-jpa-filtering/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/persistence-modules/spring-data-jpa-filtering/pom.xml b/persistence-modules/spring-data-jpa-filtering/pom.xml index 9c10f4a997..287a3136fd 100644 --- a/persistence-modules/spring-data-jpa-filtering/pom.xml +++ b/persistence-modules/spring-data-jpa-filtering/pom.xml @@ -67,7 +67,6 @@ com.baeldung.boot.Application 1.10.6 42.2.5 - 2.6.1 \ No newline at end of file From 084b7f155725124feaebe0a9886ce41585b7dcca Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Tue, 22 Mar 2022 19:10:52 +0530 Subject: [PATCH 170/249] JAVA-10592 Updated Mockito Version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index daaf9db6d2..8d065849a2 100644 --- a/pom.xml +++ b/pom.xml @@ -1460,7 +1460,7 @@ 3.21.0 2.2 1.3 - 4.1.0 + 4.4.0 1.11.20 From 4ab85e1ccc37c27bcdb3bc365e3cf58ac3dc2c96 Mon Sep 17 00:00:00 2001 From: etrandafir93 <75391049+etrandafir93@users.noreply.github.com> Date: Tue, 22 Mar 2022 17:59:07 +0200 Subject: [PATCH 171/249] BAEL-5465: tests for subtracting days from date (#11954) * BAEL-5465: tests for subtracting days from date * BAEL-5465: upated readme --- .../core-java-date-operations-2/README.md | 1 + .../SubtractDaysFromDateUnitTest.java | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 core-java-modules/core-java-date-operations-2/src/test/java/com/baeldung/subtractdays/SubtractDaysFromDateUnitTest.java diff --git a/core-java-modules/core-java-date-operations-2/README.md b/core-java-modules/core-java-date-operations-2/README.md index 557e4c3517..7c742a4f68 100644 --- a/core-java-modules/core-java-date-operations-2/README.md +++ b/core-java-modules/core-java-date-operations-2/README.md @@ -11,4 +11,5 @@ This module contains articles about date operations in Java. - [How to determine day of week by passing specific date in Java?](https://www.baeldung.com/java-get-day-of-week) - [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year) - [Getting the Week Number From Any Date](https://www.baeldung.com/java-get-week-number) +- [Subtract Days from a Date in Java](https://www.baeldung.com/java-subtract-days-from-a-date) - [[<-- Prev]](/core-java-modules/core-java-date-operations-1) diff --git a/core-java-modules/core-java-date-operations-2/src/test/java/com/baeldung/subtractdays/SubtractDaysFromDateUnitTest.java b/core-java-modules/core-java-date-operations-2/src/test/java/com/baeldung/subtractdays/SubtractDaysFromDateUnitTest.java new file mode 100644 index 0000000000..3532712963 --- /dev/null +++ b/core-java-modules/core-java-date-operations-2/src/test/java/com/baeldung/subtractdays/SubtractDaysFromDateUnitTest.java @@ -0,0 +1,49 @@ +package com.baeldung.subtractdays; + +import static org.junit.Assert.assertEquals; + +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import org.joda.time.DateTime; +import org.junit.Test; + +public class SubtractDaysFromDateUnitTest { + + @Test + public void givenCalendarDate_whenSubtractingFiveDays_dateIsChangedCorrectly() { + Calendar calendar = Calendar.getInstance(); + calendar.set(2022, Calendar.APRIL, 20); + + calendar.add(Calendar.DATE, -5); + + assertEquals(15, calendar.get(Calendar.DAY_OF_MONTH)); + assertEquals(Calendar.APRIL, calendar.get(Calendar.MONTH)); + assertEquals(2022, calendar.get(Calendar.YEAR)); + } + + @Test + public void givenJodaDateTime_whenSubtractingFiveDays_dateIsChangedCorrectly() { + DateTime dateTime = new DateTime(2022, 4, 20, 12, 0, 0); + + dateTime = dateTime.minusDays(5); + + assertEquals(15, dateTime.getDayOfMonth()); + assertEquals(4, dateTime.getMonthOfYear()); + assertEquals(2022, dateTime.getYear()); + } + + @Test + public void givenLocalDateTime_whenSubtractingFiveDays_dateIsChangedCorrectly() { + LocalDate localDateTime = LocalDate.of(2022, 4, 20); + + localDateTime = localDateTime.minusDays(5); + + assertEquals(15, localDateTime.getDayOfMonth()); + assertEquals(4, localDateTime.getMonthValue()); + assertEquals(2022, localDateTime.getYear()); + } +} From e5c34a56c218efdd6ba2d3a6da2af4ee80cd78a9 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Tue, 22 Mar 2022 19:27:49 -0300 Subject: [PATCH 172/249] https://jira.baeldung.com/browse/BAEL-5403 Editor Review changes: * reverted SpringBootPersistenceApplication.java * created SpringBootJsonConvertFileApplication.java in article package: com.baeldung.boot.json.convertfile --- .../SpringBootPersistenceApplication.java | 49 +--------------- .../SpringBootJsonConvertFileApplication.java | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+), 48 deletions(-) create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/SpringBootJsonConvertFileApplication.java diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/SpringBootPersistenceApplication.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/SpringBootPersistenceApplication.java index bbda5823f8..2dff3f37df 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/SpringBootPersistenceApplication.java +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/SpringBootPersistenceApplication.java @@ -1,60 +1,13 @@ package com.baeldung; -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.ApplicationArguments; -import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.ApplicationContext; - -import com.baeldung.boot.json.convertfile.ImportUtils; -import com.baeldung.boot.json.convertfile.service.ImportJsonService; @SpringBootApplication -public class SpringBootPersistenceApplication implements ApplicationRunner { - private Logger log = LogManager.getLogger(this.getClass()); - private static final String RESOURCE_PREFIX = "classpath:"; - - @Autowired - private ApplicationContext context; +public class SpringBootPersistenceApplication { public static void main(String ... args) { SpringApplication.run(SpringBootPersistenceApplication.class, args); } - @Override - public void run(ApplicationArguments args) throws Exception { - if (args.containsOption("import")) { - if (!args.containsOption("collection")) - throw new IllegalArgumentException("required option: --collection with collection name when using --import"); - - String collection = args.getOptionValues("collection") - .get(0); - - List sources = args.getOptionValues("import"); - for (String source : sources) { - List jsonLines = new ArrayList<>(); - if (source.startsWith(RESOURCE_PREFIX)) { - String resource = source.substring(RESOURCE_PREFIX.length()); - jsonLines = ImportUtils.linesFromResource(resource); - } else { - jsonLines = ImportUtils.lines(new File(source)); - } - - if (jsonLines == null || jsonLines.isEmpty()) { - log.warn(source + " - no input to import"); - } else { - ImportJsonService importService = context.getBean(ImportJsonService.class); - String result = importService.importTo(collection, jsonLines); - log.info(source + " - import result: " + result); - } - } - } - } } diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/SpringBootJsonConvertFileApplication.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/SpringBootJsonConvertFileApplication.java new file mode 100644 index 0000000000..40613c056b --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/json/convertfile/SpringBootJsonConvertFileApplication.java @@ -0,0 +1,58 @@ +package com.baeldung.boot.json.convertfile; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import com.baeldung.boot.json.convertfile.service.ImportJsonService; + +@SpringBootApplication +public class SpringBootJsonConvertFileApplication implements ApplicationRunner { + private Logger log = LogManager.getLogger(this.getClass()); + private static final String RESOURCE_PREFIX = "classpath:"; + + @Autowired + private ImportJsonService importService; + + public static void main(String ... args) { + SpringApplication.run(SpringBootJsonConvertFileApplication.class, args); + } + + @Override + public void run(ApplicationArguments args) throws Exception { + if (args.containsOption("import")) { + if (!args.containsOption("collection")) + throw new IllegalArgumentException("required option: --collection with collection name when using --import"); + + String collection = args.getOptionValues("collection") + .get(0); + + List sources = args.getOptionValues("import"); + for (String source : sources) { + List jsonLines = new ArrayList<>(); + if (source.startsWith(RESOURCE_PREFIX)) { + String resource = source.substring(RESOURCE_PREFIX.length()); + jsonLines = ImportUtils.linesFromResource(resource); + } else { + jsonLines = ImportUtils.lines(new File(source)); + } + + if (jsonLines == null || jsonLines.isEmpty()) { + log.warn(source + " - no input to import"); + } else { + // ImportJsonService importService = context.getBean(ImportJsonService.class); + String result = importService.importTo(collection, jsonLines); + log.info(source + " - import result: " + result); + } + } + } + } +} From ec6ff847660f0ea4e60980a2370ace46f548bfe8 Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Wed, 23 Mar 2022 08:33:59 +0530 Subject: [PATCH 173/249] JAVA-10377 Moved code for spring-response-header article to spring-rest-http --- spring-web-modules/spring-rest-http/README.md | 2 +- .../baeldung/responseheaders/ResponseHeadersApplication.java | 0 .../controllers/FilterResponseHeaderController.java | 0 .../responseheaders/controllers/ResponseHeaderController.java | 0 .../responseheaders/filter/AddResponseHeaderFilter.java | 0 .../com/baeldung/responseheaders/ResponseHeaderLiveTest.java | 2 +- .../src/test/java/com/baeldung/SpringContextTest.java | 4 +--- 7 files changed, 3 insertions(+), 5 deletions(-) rename spring-web-modules/{spring-resttemplate => spring-rest-http}/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java (100%) rename spring-web-modules/{spring-resttemplate => spring-rest-http}/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java (100%) rename spring-web-modules/{spring-resttemplate => spring-rest-http}/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java (100%) rename spring-web-modules/{spring-resttemplate => spring-rest-http}/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java (100%) diff --git a/spring-web-modules/spring-rest-http/README.md b/spring-web-modules/spring-rest-http/README.md index 43355d27cd..4c160ee513 100644 --- a/spring-web-modules/spring-rest-http/README.md +++ b/spring-web-modules/spring-rest-http/README.md @@ -7,7 +7,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: -- [How to Set a Header on a Response with Spring 5](https://www.baeldung.com/spring-response-header) - The tests contained for this article rely on the sample application within the [spring-resttemplate](/spring-resttemplate) module +- [How to Set a Header on a Response with Spring 5](https://www.baeldung.com/spring-response-header) - [Returning Custom Status Codes from Spring Controllers](https://www.baeldung.com/spring-mvc-controller-custom-http-status-code) - [Spring RequestMapping](https://www.baeldung.com/spring-requestmapping) - [Guide to DeferredResult in Spring](https://www.baeldung.com/spring-deferred-result) diff --git a/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java b/spring-web-modules/spring-rest-http/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java similarity index 100% rename from spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java rename to spring-web-modules/spring-rest-http/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java diff --git a/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java b/spring-web-modules/spring-rest-http/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java similarity index 100% rename from spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java rename to spring-web-modules/spring-rest-http/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java diff --git a/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java b/spring-web-modules/spring-rest-http/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java similarity index 100% rename from spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java rename to spring-web-modules/spring-rest-http/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java diff --git a/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java b/spring-web-modules/spring-rest-http/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java similarity index 100% rename from spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java rename to spring-web-modules/spring-rest-http/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java diff --git a/spring-web-modules/spring-rest-http/src/test/java/com/baeldung/responseheaders/ResponseHeaderLiveTest.java b/spring-web-modules/spring-rest-http/src/test/java/com/baeldung/responseheaders/ResponseHeaderLiveTest.java index bed0de55bd..2b57dbc99f 100644 --- a/spring-web-modules/spring-rest-http/src/test/java/com/baeldung/responseheaders/ResponseHeaderLiveTest.java +++ b/spring-web-modules/spring-rest-http/src/test/java/com/baeldung/responseheaders/ResponseHeaderLiveTest.java @@ -19,7 +19,7 @@ import org.springframework.test.context.junit4.SpringRunner; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class ResponseHeaderLiveTest { - private static final String BASE_URL = "http://localhost:8082/spring-rest"; + private static final String BASE_URL = "http://localhost:8080"; private static final String SINGLE_BASE_URL = BASE_URL + "/single-response-header"; private static final String FILTER_BASE_URL = BASE_URL + "/filter-response-header"; private static final String SERVICE_SINGLE_RESPONSE_HEADER = "Baeldung-Example-Header"; diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java index dc176f5322..af7bcf9538 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java @@ -5,10 +5,8 @@ import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.responseheaders.ResponseHeadersApplication; - @RunWith(SpringRunner.class) -@SpringBootTest(classes = { ResponseHeadersApplication.class }) +@SpringBootTest public class SpringContextTest { @Test From 7b880dd135ba0f8ca5641cb32b24520f7ea6fa75 Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Wed, 23 Mar 2022 08:39:37 +0530 Subject: [PATCH 174/249] JAVA-10377 Removed @RunWith as there is no specific configuration class needed to run this test --- .../src/test/java/com/baeldung/SpringContextTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java index af7bcf9538..68b7f14916 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java @@ -1,11 +1,8 @@ package com.baeldung; import org.junit.Test; -import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringRunner.class) @SpringBootTest public class SpringContextTest { From 3cadc58b03687bdfb02106439ba22b69223263d0 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 24 Mar 2022 00:03:36 +0800 Subject: [PATCH 175/249] Update README.md --- persistence-modules/java-mongodb/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-mongodb/README.md b/persistence-modules/java-mongodb/README.md index 6f6bcba250..a58806f743 100644 --- a/persistence-modules/java-mongodb/README.md +++ b/persistence-modules/java-mongodb/README.md @@ -18,3 +18,4 @@ This module contains articles about MongoDB in Java. - [Check Collection Existence in MongoDB](https://www.baeldung.com/java-check-collection-existence-mongodb) - [Case Insensitive Sorting in MongoDB](https://www.baeldung.com/java-mongodb-case-insensitive-sorting) - [Push and Set Operations in Same MongoDB Update](https://www.baeldung.com/java-mongodb-push-set) +- [Push Operations in MongoDB](https://www.baeldung.com/mongodb-push-operations) From 6e2b15f5d7d7ee78d6f7586b5c45b2a170860246 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 24 Mar 2022 00:06:02 +0800 Subject: [PATCH 176/249] Update README.md --- spring-boot-modules/spring-boot-camel/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-camel/README.md b/spring-boot-modules/spring-boot-camel/README.md index f9594a95a6..c5f50e8339 100644 --- a/spring-boot-modules/spring-boot-camel/README.md +++ b/spring-boot-modules/spring-boot-camel/README.md @@ -25,3 +25,4 @@ or return code of 201 and the response: `{"id": 10,"name": "Hello, World"}` - if ## Relevant articles: - [Apache Camel with Spring Boot](https://www.baeldung.com/apache-camel-spring-boot) +- [Apache Camel Routes Testing in Spring Boot](https://www.baeldung.com/spring-boot-apache-camel-routes-testing) From d09205d6faf2b142bd96cc9917b83ed7467b1d21 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 24 Mar 2022 00:07:25 +0800 Subject: [PATCH 177/249] Update README.md --- persistence-modules/spring-boot-persistence-mongodb/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-boot-persistence-mongodb/README.md b/persistence-modules/spring-boot-persistence-mongodb/README.md index 97241ad464..f5eaeff89c 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/README.md +++ b/persistence-modules/spring-boot-persistence-mongodb/README.md @@ -5,4 +5,5 @@ - [Upload and Retrieve Files Using MongoDB and Spring Boot](https://www.baeldung.com/spring-boot-mongodb-upload-file) - [GridFS in Spring Data MongoDB](http://www.baeldung.com/spring-data-mongodb-gridfs) - [ZonedDateTime with Spring Data MongoDB](https://www.baeldung.com/spring-data-mongodb-zoneddatetime) +- [A Guide to @DBRef in MongoDB](https://www.baeldung.com/spring-mongodb-dbref-annotation) From fc49f07cc168ef18b2438ba68ec6aba0a3daaec1 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 24 Mar 2022 00:09:04 +0800 Subject: [PATCH 178/249] Update README.md --- apache-tomcat/sso/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apache-tomcat/sso/README.md b/apache-tomcat/sso/README.md index 2b515178e0..7fe194b2f8 100644 --- a/apache-tomcat/sso/README.md +++ b/apache-tomcat/sso/README.md @@ -1,5 +1,7 @@ ### Related articles +- [SSO with Apache Tomcat](https://www.baeldung.com/apache-tomcat-sso) + ### Launch Example using Docker -$ docker-compose up \ No newline at end of file +$ docker-compose up From ffe4390ed884d2e91826de087887ff47c4ad48e2 Mon Sep 17 00:00:00 2001 From: Kapil Khandelwal Date: Thu, 24 Mar 2022 02:40:32 +0530 Subject: [PATCH 179/249] BAEL-5398: Bulk Update of Documents in MongoDB with Java (#11963) --- .../baeldung/mongo/update/BulkOperations.java | 82 +++++++++++++++++ .../baeldung/mongo/BulkOperationLiveTest.java | 92 +++++++++++++++++++ .../src/test/resources/populations.json | 4 + 3 files changed, 178 insertions(+) create mode 100644 persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/update/BulkOperations.java create mode 100644 persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/BulkOperationLiveTest.java create mode 100644 persistence-modules/java-mongodb-2/src/test/resources/populations.json diff --git a/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/update/BulkOperations.java b/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/update/BulkOperations.java new file mode 100644 index 0000000000..78ab8f20da --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/update/BulkOperations.java @@ -0,0 +1,82 @@ +package com.baeldung; + +import java.util.ArrayList; +import java.util.List; + +import org.bson.Document; + +import com.mongodb.MongoClient; +import com.mongodb.bulk.BulkWriteResult; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.DeleteOneModel; +import com.mongodb.client.model.InsertOneModel; +import com.mongodb.client.model.ReplaceOneModel; +import com.mongodb.client.model.UpdateManyModel; +import com.mongodb.client.model.UpdateOneModel; +import com.mongodb.client.model.WriteModel; + +public class BulkOperations { + + private static MongoClient mongoClient; + private static MongoDatabase database; + private static MongoCollection collection; + private static String testCollectionName; + private static String databaseName; + + public static void setUp() { + + databaseName = "baeldung"; + testCollectionName = "populations"; + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + database = mongoClient.getDatabase(databaseName); + collection = database.getCollection(testCollectionName); + + } + + } + + public static void bulkOperations() { + + List> writeOperations = new ArrayList>(); + writeOperations.add(new InsertOneModel(new Document("cityId", 1128).append("cityName", "Kathmandu") + .append("countryName", "Nepal") + .append("continentName", "Asia") + .append("population", 12))); + writeOperations.add(new InsertOneModel(new Document("cityId", 1130).append("cityName", "Mumbai") + .append("countryName", "India") + .append("continentName", "Asia") + .append("population", 55))); + writeOperations.add(new UpdateOneModel(new Document("cityName", "New Delhi"), // filter to update document + new Document("$set", new Document("status", "High Population")) // update + )); + writeOperations.add(new UpdateManyModel(new Document("cityName", "London"), // filter to update multiple documents + new Document("$set", new Document("status", "Low Population")) // update + )); + writeOperations.add(new DeleteOneModel(new Document("cityName", "Mexico City"))); + writeOperations.add(new ReplaceOneModel(new Document("cityName", "New York"), new Document("cityId", 1124).append("cityName", "New York") + .append("countryName", "United States") + .append("continentName", "North America") + .append("population", 28))); + + BulkWriteResult bulkWriteResult = collection.bulkWrite(writeOperations); + System.out.println("bulkWriteResult:- " + bulkWriteResult); + } + + public static void main(String args[]) { + + // + // Connect to cluster (default is localhost:27017) + // + setUp(); + + // + // Bulk operations + // + + bulkOperations(); + + } +} + diff --git a/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/BulkOperationLiveTest.java b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/BulkOperationLiveTest.java new file mode 100644 index 0000000000..8b7029a2df --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/BulkOperationLiveTest.java @@ -0,0 +1,92 @@ +package com.baeldung.mongo; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +import org.bson.Document; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.DeleteOneModel; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.InsertOneModel; +import com.mongodb.client.model.ReplaceOneModel; +import com.mongodb.client.model.UpdateManyModel; +import com.mongodb.client.model.UpdateOneModel; +import com.mongodb.client.model.WriteModel; +import com.mongodb.client.result.UpdateResult; + +public class BulkOperationLiveTest { + + private static MongoClient mongoClient; + private static MongoDatabase db; + private static MongoCollection collection; + private static final String DATASET_JSON = "/populations.json"; + + @BeforeClass + public static void setup() throws IOException { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + db = mongoClient.getDatabase("baeldung"); + collection = db.getCollection("populations"); + collection.drop(); + + InputStream is = BulkOperationLiveTest.class.getResourceAsStream(DATASET_JSON); + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + reader.lines() + .forEach(line -> collection.insertOne(Document.parse(line))); + reader.close(); + } + } + + @Test + public void givenPopulationCollection_whenBulkOperations_thenCheckingForDocument() { + + List> writeOperations = new ArrayList>(); + writeOperations.add(new InsertOneModel(new Document("cityId", 1128).append("cityName", "Kathmandu") + .append("countryName", "Nepal") + .append("continentName", "Asia") + .append("population", 12))); + writeOperations.add(new InsertOneModel(new Document("cityId", 1130).append("cityName", "Mumbai") + .append("countryName", "India") + .append("continentName", "Asia") + .append("population", 55))); + writeOperations.add(new UpdateOneModel(new Document("cityName", "New Delhi"), // filter to update document + new Document("$set", new Document("status", "High Population")) // update + )); + writeOperations.add(new UpdateManyModel(new Document("cityName", "London"), // filter to update multiple documents + new Document("$set", new Document("status", "Low Population")) // update + )); + writeOperations.add(new DeleteOneModel(new Document("cityName", "Mexico City"))); + writeOperations.add(new ReplaceOneModel(new Document("cityName", "New York"), new Document("cityId", 1124).append("cityName", "New York") + .append("countryName", "United States") + .append("continentName", "North America") + .append("population", 28))); + + Document orderDetail = collection.find(Filters.eq("cityId", 1124)) + .first(); + assertNotNull(orderDetail); + assertFalse(orderDetail.isEmpty()); + + } + + @AfterClass + public static void cleanUp() { + mongoClient.close(); + } + +} + diff --git a/persistence-modules/java-mongodb-2/src/test/resources/populations.json b/persistence-modules/java-mongodb-2/src/test/resources/populations.json new file mode 100644 index 0000000000..200daa206b --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/test/resources/populations.json @@ -0,0 +1,4 @@ +{ "cityId":1124, "cityName":"New York", "countryName":"United States","continentName":"North America","population":22 } +{ "cityId":1125, "cityName":"Mexico City", "countryName":"Mexico", "continentName":"North America","population":25 } +{ "cityId":1126, "cityName":"New Delhi", "countryName":"India","continentName":"Asia","population":45 } +{ "cityId":1134, "cityName":"London", "countryName":"England", "continentName":"Europe", "population":32 } From a026580eedcdbca26e94e5e3a231a58c68717a1f Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Thu, 24 Mar 2022 11:36:03 +0500 Subject: [PATCH 180/249] Updated README.md Moved https://www.baeldung.com/spring-junit-failed-to-load-applicationcontext to spring-boot-testing-2 --- spring-boot-modules/spring-boot-testing/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/spring-boot-modules/spring-boot-testing/README.md b/spring-boot-modules/spring-boot-testing/README.md index 2fb96992c9..19f5ca0f59 100644 --- a/spring-boot-modules/spring-boot-testing/README.md +++ b/spring-boot-modules/spring-boot-testing/README.md @@ -15,5 +15,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Prevent ApplicationRunner or CommandLineRunner Beans From Executing During Junit Testing](https://www.baeldung.com/spring-junit-prevent-runner-beans-testing-execution) - [Testing in Spring Boot](https://www.baeldung.com/spring-boot-testing) - [Fixing the NoSuchMethodError JUnit Error](https://www.baeldung.com/junit-nosuchmethoderror) -- [Failed to Load ApplicationContext for JUnit Test of Spring Controller](https://www.baeldung.com/spring-junit-failed-to-load-applicationcontext) - More articles: [[more -->]](../spring-boot-testing-2) From 600312556999c71d27bbf99c2cba1d7f405d5f44 Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Thu, 24 Mar 2022 11:36:20 +0500 Subject: [PATCH 181/249] Updated README.md Moved over https://www.baeldung.com/spring-junit-failed-to-load-applicationcontext from spring-boot-testing --- spring-boot-modules/spring-boot-testing-2/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-boot-modules/spring-boot-testing-2/README.md b/spring-boot-modules/spring-boot-testing-2/README.md index 33664a4448..afc75f6727 100644 --- a/spring-boot-modules/spring-boot-testing-2/README.md +++ b/spring-boot-modules/spring-boot-testing-2/README.md @@ -9,4 +9,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [Setting the Log Level in Spring Boot when Testing](https://www.baeldung.com/spring-boot-testing-log-level) -- More articles: [[<-- prev]](../spring-boot-testing) \ No newline at end of file +- [Failed to Load ApplicationContext for JUnit Test of Spring Controller](https://www.baeldung.com/spring-junit-failed-to-load-applicationcontext) +- More articles: [[<-- prev]](../spring-boot-testing) From b541fce0a5d50a93e483970f1e9fede67ebff3ea Mon Sep 17 00:00:00 2001 From: Kapil Khandelwal Date: Fri, 25 Mar 2022 04:27:57 +0530 Subject: [PATCH 182/249] BAEL-5372: A Guide to Upsert in MongoDB (#11974) --- .../mongo/update/UpsertOperations.java | 111 ++++++++++++++++ .../mongo/update/UpsertOperationLiveTest.java | 118 ++++++++++++++++++ .../src/test/resources/vehicle.json | 3 + 3 files changed, 232 insertions(+) create mode 100644 persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/update/UpsertOperations.java create mode 100644 persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/update/UpsertOperationLiveTest.java create mode 100644 persistence-modules/java-mongodb-2/src/test/resources/vehicle.json diff --git a/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/update/UpsertOperations.java b/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/update/UpsertOperations.java new file mode 100644 index 0000000000..1034742225 --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/update/UpsertOperations.java @@ -0,0 +1,111 @@ +package com.baeldung.mongo; + +import org.bson.Document; + +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.FindOneAndUpdateOptions; +import com.mongodb.client.model.ReturnDocument; +import com.mongodb.client.model.UpdateOptions; +import com.mongodb.client.model.Updates; +import com.mongodb.client.result.UpdateResult; + +public class UpsertOperations { + + private static MongoClient mongoClient; + private static MongoDatabase database; + private static MongoCollection collection; + private static String testCollectionName; + private static String databaseName; + + public static void setUp() { + + databaseName = "baeldung"; + testCollectionName = "vehicle"; + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + database = mongoClient.getDatabase(databaseName); + collection = database.getCollection(testCollectionName); + + } + + } + + public static void updateOperations() { + UpdateOptions options = new UpdateOptions().upsert(true); + UpdateResult updateResult = collection.updateOne(Filters.eq("modelName", "X5"), Updates.combine(Updates.set("companyName", "Hero Honda")), options); + System.out.println("updateResult:- " + updateResult); + + } + + public static void updateSetOnInsertOperations() { + + UpdateOptions options = new UpdateOptions().upsert(true); + UpdateResult updateSetOnInsertResult = collection.updateOne(Filters.eq("modelName", "GTPR"), + Updates.combine(Updates.set("companyName", "Hero Honda"), Updates.setOnInsert("launchYear", 2022), Updates.setOnInsert("type", "Bike"), Updates.setOnInsert("registeredNo", "EPS 5562")), options); + + System.out.println("updateSetOnInsertResult:- " + updateSetOnInsertResult); + + } + + public static void findOneAndUpdateOperations() { + + FindOneAndUpdateOptions upsertOptions = new FindOneAndUpdateOptions(); + upsertOptions.returnDocument(ReturnDocument.AFTER); + upsertOptions.upsert(true); + + Document resultDocument = collection.findOneAndUpdate(Filters.eq("modelName", "X7"), Updates.set("companyName", "Hero Honda"), upsertOptions); + System.out.println("resultDocument:- " + resultDocument); + + } + + public static void replaceOneOperations() { + + UpdateOptions options = new UpdateOptions().upsert(true); + Document replaceDocument = new Document(); + replaceDocument.append("modelName", "GTPP") + .append("companyName", "Hero Honda") + .append("launchYear", 2022) + .append("type", "Bike") + .append("registeredNo", "EPS 5562"); + UpdateResult updateReplaceResult = collection.replaceOne(Filters.eq("modelName", "GTPP"), replaceDocument, options); + + System.out.println("updateReplaceResult:- " + updateReplaceResult); + } + + public static void main(String args[]) { + + // + // Connect to cluster (default is localhost:27017) + // + setUp(); + + // + // Update with upsert operation + // + + updateOperations(); + + // + // Update with upsert operation using setOnInsert + // + + updateSetOnInsertOperations(); + + // + // Update with upsert operation using findOneAndUpdate + // + + findOneAndUpdateOperations(); + + // + // Update with upsert operation using replaceOneOperations + // + + replaceOneOperations(); + + } +} + diff --git a/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/update/UpsertOperationLiveTest.java b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/update/UpsertOperationLiveTest.java new file mode 100644 index 0000000000..393d230a7b --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/update/UpsertOperationLiveTest.java @@ -0,0 +1,118 @@ +package com.baeldung.mongo; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +import org.bson.Document; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.DeleteOneModel; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.FindOneAndUpdateOptions; +import com.mongodb.client.model.InsertOneModel; +import com.mongodb.client.model.ReplaceOneModel; +import com.mongodb.client.model.ReturnDocument; +import com.mongodb.client.model.UpdateManyModel; +import com.mongodb.client.model.UpdateOneModel; +import com.mongodb.client.model.UpdateOptions; +import com.mongodb.client.model.Updates; +import com.mongodb.client.model.WriteModel; +import com.mongodb.client.result.UpdateResult; + +public class UpsertOperationLiveTest { + + private static MongoClient mongoClient; + private static MongoDatabase db; + private static MongoCollection collection; + private static final String DATASET_JSON = "/vehicle.json"; + + @BeforeClass + public static void setup() throws IOException { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + db = mongoClient.getDatabase("baeldung"); + collection = db.getCollection("vehicle"); + collection.drop(); + + InputStream is = BulkOperationLiveTest.class.getResourceAsStream(DATASET_JSON); + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + reader.lines() + .forEach(line -> collection.insertOne(Document.parse(line))); + reader.close(); + } + } + + @Test + public void givenVehicleCollection_whenupdateOperations_thenCheckingForDocument() { + UpdateOptions options = new UpdateOptions().upsert(true); + UpdateResult updateResult = collection.updateOne(Filters.eq("modelName", "X5"), Updates.combine(Updates.set("companyName", "Hero Honda")), options); + Document vehicleDetail = collection.find(Filters.eq("modelName", "X5")) + .first(); + assertNotNull(vehicleDetail); + assertFalse(vehicleDetail.isEmpty()); + + } + + @Test + public void givenVehicleCollection_whenupdateSetOnInsertOperations_thenCheckingForDocument() { + + UpdateOptions options = new UpdateOptions().upsert(true); + UpdateResult updateSetOnInsertResult = collection.updateOne(Filters.eq("modelName", "GTPR"), + Updates.combine(Updates.set("companyName", "Hero Honda"), Updates.setOnInsert("launchYear", 2022), Updates.setOnInsert("type", "Bike"), Updates.setOnInsert("registeredNo", "EPS 5562")), options); + + Document vehicleDetail = collection.find(Filters.eq("modelName", "GTPR")) + .first(); + assertNotNull(vehicleDetail); + assertFalse(vehicleDetail.isEmpty()); + } + + @Test + public void givenVehicleCollection_whenfindOneAndUpdateOperations_thenCheckingForDocument() { + + FindOneAndUpdateOptions upsertOptions = new FindOneAndUpdateOptions(); + upsertOptions.returnDocument(ReturnDocument.AFTER); + upsertOptions.upsert(true); + + Document resultDocument = collection.findOneAndUpdate(Filters.eq("modelName", "X7"), Updates.set("companyName", "Hero Honda1"), upsertOptions); + Document vehicleDetail = collection.find(Filters.eq("modelName", "X7")) + .first(); + assertNotNull(vehicleDetail); + assertFalse(vehicleDetail.isEmpty()); + } + + @Test + public void givenVehicleCollection_whenreplaceOneOperations_thenCheckingForDocument() { + + UpdateOptions options = new UpdateOptions().upsert(true); + Document replaceDocument = new Document(); + replaceDocument.append("modelName", "GTPP") + .append("companyName", "Hero Honda") + .append("launchYear", 2022) + .append("type", "Bike") + .append("registeredNo", "EPS 5562"); + UpdateResult updateReplaceResult = collection.replaceOne(Filters.eq("modelName", "GTPP"), replaceDocument, options); + + Document vehicleDetail = collection.find(Filters.eq("modelName", "GTPP")) + .first(); + assertNotNull(vehicleDetail); + assertFalse(vehicleDetail.isEmpty()); + } + + @AfterClass + public static void cleanUp() { + mongoClient.close(); + } +} + diff --git a/persistence-modules/java-mongodb-2/src/test/resources/vehicle.json b/persistence-modules/java-mongodb-2/src/test/resources/vehicle.json new file mode 100644 index 0000000000..3dc71b911b --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/test/resources/vehicle.json @@ -0,0 +1,3 @@ +{ "companyName":"Nissan", "modelName":"GTR", "launchYear":2016,"type":"Sports", "registeredNo":"EPS 5561" } +{ "companyName":"BMW", "modelName":"X5", "launchYear":2020, "type":"SUV", "registeredNo":"LLS 6899" } +{ "companyName":"Honda", "modelName":"Gold Wing", "launchYear":2018, "type":"Bike", "registeredNo":"LKS 2477"} From bcb342693c15d8248dbb44b163a759be4f31e88d Mon Sep 17 00:00:00 2001 From: etrandafir93 <75391049+etrandafir93@users.noreply.github.com> Date: Fri, 25 Mar 2022 17:09:52 +0100 Subject: [PATCH 183/249] BAEL-5465: removed link from readme, reordered tests (#11977) --- .../core-java-date-operations-2/README.md | 1 - .../SubtractDaysFromDateUnitTest.java | 22 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/core-java-modules/core-java-date-operations-2/README.md b/core-java-modules/core-java-date-operations-2/README.md index 7c742a4f68..557e4c3517 100644 --- a/core-java-modules/core-java-date-operations-2/README.md +++ b/core-java-modules/core-java-date-operations-2/README.md @@ -11,5 +11,4 @@ This module contains articles about date operations in Java. - [How to determine day of week by passing specific date in Java?](https://www.baeldung.com/java-get-day-of-week) - [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year) - [Getting the Week Number From Any Date](https://www.baeldung.com/java-get-week-number) -- [Subtract Days from a Date in Java](https://www.baeldung.com/java-subtract-days-from-a-date) - [[<-- Prev]](/core-java-modules/core-java-date-operations-1) diff --git a/core-java-modules/core-java-date-operations-2/src/test/java/com/baeldung/subtractdays/SubtractDaysFromDateUnitTest.java b/core-java-modules/core-java-date-operations-2/src/test/java/com/baeldung/subtractdays/SubtractDaysFromDateUnitTest.java index 3532712963..9afb6e8db0 100644 --- a/core-java-modules/core-java-date-operations-2/src/test/java/com/baeldung/subtractdays/SubtractDaysFromDateUnitTest.java +++ b/core-java-modules/core-java-date-operations-2/src/test/java/com/baeldung/subtractdays/SubtractDaysFromDateUnitTest.java @@ -13,6 +13,17 @@ import org.junit.Test; public class SubtractDaysFromDateUnitTest { + @Test + public void givenLocalDateTime_whenSubtractingFiveDays_dateIsChangedCorrectly() { + LocalDate localDateTime = LocalDate.of(2022, 4, 20); + + localDateTime = localDateTime.minusDays(5); + + assertEquals(15, localDateTime.getDayOfMonth()); + assertEquals(4, localDateTime.getMonthValue()); + assertEquals(2022, localDateTime.getYear()); + } + @Test public void givenCalendarDate_whenSubtractingFiveDays_dateIsChangedCorrectly() { Calendar calendar = Calendar.getInstance(); @@ -35,15 +46,4 @@ public class SubtractDaysFromDateUnitTest { assertEquals(4, dateTime.getMonthOfYear()); assertEquals(2022, dateTime.getYear()); } - - @Test - public void givenLocalDateTime_whenSubtractingFiveDays_dateIsChangedCorrectly() { - LocalDate localDateTime = LocalDate.of(2022, 4, 20); - - localDateTime = localDateTime.minusDays(5); - - assertEquals(15, localDateTime.getDayOfMonth()); - assertEquals(4, localDateTime.getMonthValue()); - assertEquals(2022, localDateTime.getYear()); - } } From e57b05c025ed2b147fb67bcf729b0fefbc0a0160 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 26 Mar 2022 14:52:38 +0530 Subject: [PATCH 184/249] JAVA-10082 Create new module hibernate-annotations-2 from spring-hibernate-5 module --- .../hibernate-annotations/README.md | 1 + .../hibernate-annotations/pom.xml | 42 ++++++++++- .../immutable/PersistenceConfig.java | 69 +++++++++++++++++++ .../hibernate/immutable/entities/Event.java | 0 .../immutable/entities/EventGeneratedId.java | 0 .../immutable/util/HibernateUtil.java | 0 .../src/main/resources/immutable.cfg.xml | 0 .../main/resources/persistence-h2.properties | 15 ++++ .../java/com/baeldung/SpringContextTest.java | 18 +++++ .../HibernateImmutableIntegrationTest.java | 9 +++ .../spring-hibernate-5/README.md | 1 - 11 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/PersistenceConfig.java rename persistence-modules/{spring-hibernate-5 => hibernate-annotations}/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java (100%) rename persistence-modules/{spring-hibernate-5 => hibernate-annotations}/src/main/java/com/baeldung/hibernate/immutable/entities/EventGeneratedId.java (100%) rename persistence-modules/{spring-hibernate-5 => hibernate-annotations}/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java (100%) rename persistence-modules/{spring-hibernate-5 => hibernate-annotations}/src/main/resources/immutable.cfg.xml (100%) create mode 100644 persistence-modules/hibernate-annotations/src/main/resources/persistence-h2.properties create mode 100644 persistence-modules/hibernate-annotations/src/test/java/com/baeldung/SpringContextTest.java rename persistence-modules/{spring-hibernate-5 => hibernate-annotations}/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java (93%) diff --git a/persistence-modules/hibernate-annotations/README.md b/persistence-modules/hibernate-annotations/README.md index 7d7740a069..c7efe77e22 100644 --- a/persistence-modules/hibernate-annotations/README.md +++ b/persistence-modules/hibernate-annotations/README.md @@ -9,3 +9,4 @@ This module contains articles about Annotations used in Hibernate. - [Hibernate One to Many Annotation Tutorial](https://www.baeldung.com/hibernate-one-to-many) - [Hibernate @WhereJoinTable Annotation](https://www.baeldung.com/hibernate-wherejointable) - [Usage of the Hibernate @LazyCollection Annotation](https://www.baeldung.com/hibernate-lazycollection) +- [@Immutable in Hibernate](http://www.baeldung.com/hibernate-immutable) diff --git a/persistence-modules/hibernate-annotations/pom.xml b/persistence-modules/hibernate-annotations/pom.xml index 634cd64cca..909f632e61 100644 --- a/persistence-modules/hibernate-annotations/pom.xml +++ b/persistence-modules/hibernate-annotations/pom.xml @@ -16,10 +16,26 @@
+ + + org.springframework + spring-context + ${org.springframework.version} + + + org.springframework.data + spring-data-jpa + ${org.springframework.data.version} + org.hibernate hibernate-core ${hibernate-core.version} + + + org.hsqldb + hsqldb + ${hsqldb.version} com.h2database @@ -41,14 +57,38 @@ hibernate-spatial ${hibernate-core.version} + + org.apache.tomcat + tomcat-dbcp + ${tomcat-dbcp.version} + + + + + com.google.guava + guava + ${guava.version} + + + + org.springframework + spring-test + ${org.springframework.version} + test + + + 5.0.2.RELEASE + 1.10.6.RELEASE 5.4.7.Final true 2.1.7.RELEASE - 5.4.7.Final + 1.4.200 + 9.0.0.M26 + 2.3.4 \ No newline at end of file diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/PersistenceConfig.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/PersistenceConfig.java new file mode 100644 index 0000000000..cd46574ebf --- /dev/null +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/PersistenceConfig.java @@ -0,0 +1,69 @@ +package com.baeldung.hibernate.immutable; + +import com.google.common.base.Preconditions; +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.orm.hibernate5.HibernateTransactionManager; +import org.springframework.orm.hibernate5.LocalSessionFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; +import java.util.Properties; + +@Configuration +@EnableTransactionManagement +@PropertySource({ "classpath:persistence-h2.properties" }) +@ComponentScan({ "com.baeldung.hibernate.immutable"}) +public class PersistenceConfig { + + @Autowired + private Environment env; + + @Bean + public LocalSessionFactoryBean sessionFactory() { + final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); + sessionFactory.setDataSource(dataSource()); + sessionFactory.setPackagesToScan(new String[] { "com.baeldung.hibernate.immutable" }); + sessionFactory.setHibernateProperties(hibernateProperties()); + return sessionFactory; + } + + @Bean + public DataSource dataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); + dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); + + return dataSource; + } + + @Bean + public PlatformTransactionManager hibernateTransactionManager() { + final HibernateTransactionManager transactionManager = new HibernateTransactionManager(); + transactionManager.setSessionFactory(sessionFactory().getObject()); + return transactionManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + private final Properties hibernateProperties() { + final Properties hibernateProperties = new Properties(); + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + hibernateProperties.setProperty("hibernate.show_sql", "false"); + return hibernateProperties; + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java similarity index 100% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java rename to persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/entities/EventGeneratedId.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/entities/EventGeneratedId.java similarity index 100% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/entities/EventGeneratedId.java rename to persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/entities/EventGeneratedId.java diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java similarity index 100% rename from persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java rename to persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/immutable.cfg.xml b/persistence-modules/hibernate-annotations/src/main/resources/immutable.cfg.xml similarity index 100% rename from persistence-modules/spring-hibernate-5/src/main/resources/immutable.cfg.xml rename to persistence-modules/hibernate-annotations/src/main/resources/immutable.cfg.xml diff --git a/persistence-modules/hibernate-annotations/src/main/resources/persistence-h2.properties b/persistence-modules/hibernate-annotations/src/main/resources/persistence-h2.properties new file mode 100644 index 0000000000..4bc5e98f56 --- /dev/null +++ b/persistence-modules/hibernate-annotations/src/main/resources/persistence-h2.properties @@ -0,0 +1,15 @@ +# jdbc.X +jdbc.driverClassName=org.h2.Driver +jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +jdbc.eventGeneratedId=sa +jdbc.user=sa +jdbc.pass= + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=false +hibernate.hbm2ddl.auto=create-drop +hibernate.cache.use_second_level_cache=true +hibernate.cache.use_query_cache=true +hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory + diff --git a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/SpringContextTest.java new file mode 100644 index 0000000000..4bf62dd830 --- /dev/null +++ b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/SpringContextTest.java @@ -0,0 +1,18 @@ +package com.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import com.baeldung.hibernate.immutable.PersistenceConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +public class SpringContextTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java similarity index 93% rename from persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java rename to persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java index 1572f23ed1..270a235ef0 100644 --- a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java +++ b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java @@ -52,6 +52,7 @@ public class HibernateImmutableIntegrationTest { @Test public void updateEvent() { createEvent(); + openNewSession(); Event event = (Event) session.createQuery("FROM Event WHERE title='New Event'").list().get(0); event.setTitle("Private Event"); session.update(event); @@ -99,6 +100,7 @@ public class HibernateImmutableIntegrationTest { @Test public void updateEventGenerated() { createEventGenerated(); + openNewSession(); EventGeneratedId eventGeneratedId = (EventGeneratedId) session.createQuery("FROM EventGeneratedId WHERE name LIKE '%John%'").list().get(0); eventGeneratedId.setName("Mike"); @@ -121,4 +123,11 @@ public class HibernateImmutableIntegrationTest { session.save(eventGeneratedId); } + private static void openNewSession() { + session.getTransaction().commit(); + session.close(); + session = HibernateUtil.getSessionFactory().openSession(); + session.beginTransaction(); + } + } diff --git a/persistence-modules/spring-hibernate-5/README.md b/persistence-modules/spring-hibernate-5/README.md index 124d71a21e..e2344fd585 100644 --- a/persistence-modules/spring-hibernate-5/README.md +++ b/persistence-modules/spring-hibernate-5/README.md @@ -10,5 +10,4 @@ This module contains articles about Hibernate 5 with Spring. - [Hibernate Second-Level Cache](http://www.baeldung.com/hibernate-second-level-cache) - [Deleting Objects with Hibernate](http://www.baeldung.com/delete-with-hibernate) - [Spring, Hibernate and a JNDI Datasource](http://www.baeldung.com/spring-persistence-jpa-jndi-datasource) -- [@Immutable in Hibernate](http://www.baeldung.com/hibernate-immutable) - [Bootstrapping Hibernate 5 with Spring](https://www.baeldung.com/hibernate-5-spring) From a410e2e4a6ff18c54aa49dd0295df0661d77c49c Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 26 Mar 2022 14:59:41 +0530 Subject: [PATCH 185/249] JAVA-10082 Removing unused property --- persistence-modules/hibernate-annotations/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/persistence-modules/hibernate-annotations/pom.xml b/persistence-modules/hibernate-annotations/pom.xml index 909f632e61..ed158216fb 100644 --- a/persistence-modules/hibernate-annotations/pom.xml +++ b/persistence-modules/hibernate-annotations/pom.xml @@ -85,7 +85,6 @@ 5.4.7.Final true 2.1.7.RELEASE - 1.4.200 9.0.0.M26 2.3.4 From b69b16801ef40584173d695b62550d60ce6e495a Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Sat, 26 Mar 2022 22:21:18 +0530 Subject: [PATCH 186/249] JAVA-10378 Refactored, cleaned-up HttpClientConnectionManagementLiveTest to be inline with the live article --- ...ttpClientConnectionManagementLiveTest.java | 472 ++++++++---------- 1 file changed, 215 insertions(+), 257 deletions(-) diff --git a/httpclient/src/test/java/com/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java b/httpclient/src/test/java/com/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java index 823b506113..57a8f0a806 100644 --- a/httpclient/src/test/java/com/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java +++ b/httpclient/src/test/java/com/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java @@ -1,5 +1,12 @@ package com.baeldung.httpclient.conn; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + import org.apache.http.HeaderElement; import org.apache.http.HeaderElementIterator; import org.apache.http.HttpClientConnection; @@ -13,6 +20,7 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.SocketConfig; import org.apache.http.conn.ConnectionKeepAliveStrategy; +import org.apache.http.conn.ConnectionPoolTimeoutException; import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.client.CloseableHttpClient; @@ -25,177 +33,80 @@ import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpCoreContext; import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.util.EntityUtils; -import org.junit.After; -import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import java.io.IOException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.assertTrue; - public class HttpClientConnectionManagementLiveTest { - private static final String SERVER1 = "http://www.petrikainulainen.net/"; - private static final String SERVER7 = "http://www.baeldung.com/"; - - private BasicHttpClientConnectionManager basicConnManager; - private PoolingHttpClientConnectionManager poolingConnManager; - - private HttpClientContext context; - private HttpRoute route; - private HttpClientConnection conn1; - private HttpClientConnection conn; - private HttpClientConnection conn2; - - private CloseableHttpResponse response; - private HttpGet get1; - private HttpGet get2; - - private CloseableHttpClient client; - - @Before - public final void before() { - get1 = new HttpGet(SERVER1); - get2 = new HttpGet(SERVER7); - route = new HttpRoute(new HttpHost("www.baeldung.com", 80)); - } - - @After - public final void after() throws IllegalStateException, IOException { - if (conn != null) { - conn.close(); - } - if (conn1 != null) { - conn1.close(); - } - if (conn2 != null) { - conn2.close(); - } - if (poolingConnManager != null) { - poolingConnManager.shutdown(); - } - if (basicConnManager != null) { - basicConnManager.shutdown(); - } - if (client != null) { - client.close(); - } - if (response != null) { - response.close(); - } - } - - // 2 + // Example 2.1. Getting a Connection Request for a Low Level Connection (HttpClientConnection) @Test - // 2.1 IN ARTCLE - public final void whenLowLevelConnectionIsEstablished_thenNoExceptions() throws IOException, HttpException, InterruptedException, ExecutionException { - basicConnManager = new BasicHttpClientConnectionManager(); - final ConnectionRequest connRequest = basicConnManager.requestConnection(route, null); - assertTrue(connRequest.get(1000, TimeUnit.SECONDS) != null); - } - - @Test - // @Ignore - // 2.2 IN ARTICLE - public final void whenOpeningLowLevelConnectionWithSocketTimeout_thenNoExceptions() throws InterruptedException, ExecutionException, IOException, HttpException { - basicConnManager = new BasicHttpClientConnectionManager(); - context = HttpClientContext.create(); - final ConnectionRequest connRequest = basicConnManager.requestConnection(route, null); - conn = connRequest.get(1000, TimeUnit.SECONDS); - if (!conn.isOpen()) { - basicConnManager.connect(conn, route, 1000, context); + public final void whenLowLevelConnectionIsEstablished_thenNoExceptions() throws ConnectionPoolTimeoutException, InterruptedException, ExecutionException { + try (BasicHttpClientConnectionManager connManager = new BasicHttpClientConnectionManager()) { + HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 80)); + final ConnectionRequest connRequest = connManager.requestConnection(route, null); + assertNotNull(connRequest.get(1000, TimeUnit.SECONDS)); } - conn.setSocketTimeout(30000); - - assertTrue(conn.getSocketTimeout() == 30000); - assertTrue(conn.isOpen()); } - // 3 - + // Example 3.1. Setting the PoolingHttpClientConnectionManager on a HttpClient @Test - // Example 3.1. - public final void whenPollingConnectionManagerIsConfiguredOnHttpClient_thenNoExceptions() throws InterruptedException, ClientProtocolException, IOException { - poolingConnManager = new PoolingHttpClientConnectionManager(); - client = HttpClients.custom().setConnectionManager(poolingConnManager).build(); - client.execute(get1); + public final void whenPollingConnectionManagerIsConfiguredOnHttpClient_thenNoExceptions() throws ClientProtocolException, IOException { + PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); + CloseableHttpClient client = HttpClients.custom() + .setConnectionManager(poolingConnManager) + .build(); + client.execute(new HttpGet("https://www.baeldung.com")); - assertTrue(poolingConnManager.getTotalStats().getLeased() == 1); + assertTrue(poolingConnManager.getTotalStats() + .getLeased() == 1); } + // Example 3.2. Using Two HttpClients to Connect to One Target Host Each @Test - // @Ignore - // Example 3.2. TESTER VERSION - /*tester*/ public final void whenTwoConnectionsForTwoRequests_thenTwoConnectionsAreLeased() throws InterruptedException { - poolingConnManager = new PoolingHttpClientConnectionManager(); - final CloseableHttpClient client1 = HttpClients.custom().setConnectionManager(poolingConnManager).build(); - final CloseableHttpClient client2 = HttpClients.custom().setConnectionManager(poolingConnManager).build(); - final TesterVersion_MultiHttpClientConnThread thread1 = new TesterVersion_MultiHttpClientConnThread(client1, get1, poolingConnManager); - final TesterVersion_MultiHttpClientConnThread thread2 = new TesterVersion_MultiHttpClientConnThread(client2, get2, poolingConnManager); - thread1.start(); - thread2.start(); - thread1.join(); - thread2.join(1000); - assertTrue(poolingConnManager.getTotalStats().getLeased() == 2); - } - - @Test - // @Ignore - // Example 3.2. ARTICLE VERSION public final void whenTwoConnectionsForTwoRequests_thenNoExceptions() throws InterruptedException { - poolingConnManager = new PoolingHttpClientConnectionManager(); - final CloseableHttpClient client1 = HttpClients.custom().setConnectionManager(poolingConnManager).build(); - final CloseableHttpClient client2 = HttpClients.custom().setConnectionManager(poolingConnManager).build(); - final MultiHttpClientConnThread thread1 = new MultiHttpClientConnThread(client1, get1); - final MultiHttpClientConnThread thread2 = new MultiHttpClientConnThread(client2, get2); + HttpGet get1 = new HttpGet("https://www.baeldung.com"); + HttpGet get2 = new HttpGet("https://www.google.com"); + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); + CloseableHttpClient client1 = HttpClients.custom() + .setConnectionManager(connManager) + .build(); + CloseableHttpClient client2 = HttpClients.custom() + .setConnectionManager(connManager) + .build(); + + MultiHttpClientConnThread thread1 = new MultiHttpClientConnThread(client1, get1); + MultiHttpClientConnThread thread2 = new MultiHttpClientConnThread(client2, get2); thread1.start(); thread2.start(); thread1.join(); thread2.join(); + + assertTrue(connManager.getTotalStats() + .getLeased() == 0); } - // 4 - + // Example 4.1. Increasing the Number of Connections that Can be Open and Managed Beyond the default Limits @Test - // Example 4.1 public final void whenIncreasingConnectionPool_thenNoEceptions() { - poolingConnManager = new PoolingHttpClientConnectionManager(); - poolingConnManager.setMaxTotal(5); - poolingConnManager.setDefaultMaxPerRoute(4); - - final HttpHost localhost = new HttpHost("locahost", 80); - poolingConnManager.setMaxPerRoute(new HttpRoute(localhost), 5); + try (PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager()) { + connManager.setMaxTotal(5); + connManager.setDefaultMaxPerRoute(4); + HttpHost host = new HttpHost("www.baeldung.com", 80); + connManager.setMaxPerRoute(new HttpRoute(host), 5); + } } + // Example 4.2. Using Threads to Execute Connections @Test - // @Ignore - // 4.2 Tester Version - /*tester*/ public final void whenExecutingSameRequestsInDifferentThreads_thenUseDefaultConnLimit() throws InterruptedException, IOException { - poolingConnManager = new PoolingHttpClientConnectionManager(); - client = HttpClients.custom().setConnectionManager(poolingConnManager).build(); - final TesterVersion_MultiHttpClientConnThread thread1 = new TesterVersion_MultiHttpClientConnThread(client, new HttpGet("http://www.google.com"), poolingConnManager); - final TesterVersion_MultiHttpClientConnThread thread2 = new TesterVersion_MultiHttpClientConnThread(client, new HttpGet("http://www.google.com"), poolingConnManager); - final TesterVersion_MultiHttpClientConnThread thread3 = new TesterVersion_MultiHttpClientConnThread(client, new HttpGet("http://www.google.com"), poolingConnManager); - thread1.start(); - thread2.start(); - thread3.start(); - thread1.join(10000); - thread2.join(10000); - thread3.join(10000); - } - - @Test - // 4.2 Article version public final void whenExecutingSameRequestsInDifferentThreads_thenExecuteReuqest() throws InterruptedException { - final HttpGet get = new HttpGet("http://www.google.com"); - poolingConnManager = new PoolingHttpClientConnectionManager(); - client = HttpClients.custom().setConnectionManager(poolingConnManager).build(); - final MultiHttpClientConnThread thread1 = new MultiHttpClientConnThread(client, get); - final MultiHttpClientConnThread thread2 = new MultiHttpClientConnThread(client, get); - final MultiHttpClientConnThread thread3 = new MultiHttpClientConnThread(client, get); + HttpGet get = new HttpGet("http://www.baeldung.com"); + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); + CloseableHttpClient client = HttpClients.custom() + .setConnectionManager(connManager) + .build(); + MultiHttpClientConnThread thread1 = new MultiHttpClientConnThread(client, get); + MultiHttpClientConnThread thread2 = new MultiHttpClientConnThread(client, get); + MultiHttpClientConnThread thread3 = new MultiHttpClientConnThread(client, get); thread1.start(); thread2.start(); thread3.start(); @@ -204,12 +115,9 @@ public class HttpClientConnectionManagementLiveTest { thread3.join(); } - // 5 - + // Example 5.1. A Custom Keep Alive Strategy @Test - // @Ignore - // 5.1 - public final void whenCustomizingKeepAliveStrategy_thenNoExceptions() throws ClientProtocolException, IOException { + public final void whenCustomizingKeepAliveStrategy_thenNoExceptions() { final ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() { @Override public long getKeepAliveDuration(final HttpResponse myResponse, final HttpContext myContext) { @@ -231,50 +139,175 @@ public class HttpClientConnectionManagementLiveTest { } }; - client = HttpClients.custom().setKeepAliveStrategy(myStrategy).setConnectionManager(poolingConnManager).build(); - client.execute(get1); - client.execute(get2); + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); + HttpClients.custom() + .setKeepAliveStrategy(myStrategy) + .setConnectionManager(connManager) + .build(); } - // 6 - + // Example 6.1. BasicHttpClientConnectionManager Connection Reuse @Test - // @Ignore - // 6.1 - public final void givenBasicHttpClientConnManager_whenConnectionReuse_thenNoExceptions() throws InterruptedException, ExecutionException, IOException, HttpException { - basicConnManager = new BasicHttpClientConnectionManager(); - context = HttpClientContext.create(); - - final ConnectionRequest connRequest = basicConnManager.requestConnection(route, null); - conn = connRequest.get(10, TimeUnit.SECONDS); + public final void givenBasicHttpClientConnManager_whenConnectionReuse_thenNoExceptions() throws IOException, HttpException, InterruptedException, ExecutionException { + BasicHttpClientConnectionManager basicConnManager = new BasicHttpClientConnectionManager(); + HttpClientContext context = HttpClientContext.create(); + // low level + HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 443)); + ConnectionRequest connRequest = basicConnManager.requestConnection(route, null); + HttpClientConnection conn = connRequest.get(10, TimeUnit.SECONDS); basicConnManager.connect(conn, route, 1000, context); basicConnManager.routeComplete(conn, route, context); - final HttpRequestExecutor exeRequest = new HttpRequestExecutor(); - context.setTargetHost((new HttpHost("http://httpbin.org", 80))); - final HttpGet get = new HttpGet("http://httpbin.org"); + HttpRequestExecutor exeRequest = new HttpRequestExecutor(); + context.setTargetHost((new HttpHost("www.baeldung.com", 80))); + HttpGet get = new HttpGet("http://www.baeldung.com"); exeRequest.execute(get, conn, context); - conn.isResponseAvailable(1000); + basicConnManager.releaseConnection(conn, null, 1, TimeUnit.SECONDS); - // - client = HttpClients.custom().setConnectionManager(basicConnManager).build(); + // high level + CloseableHttpClient client = HttpClients.custom() + .setConnectionManager(basicConnManager) + .build(); client.execute(get); } + // Example 6.2. PoolingHttpClientConnectionManager: Re-Using Connections with Threads + @Test + public final void whenConnectionsNeededGreaterThanMaxTotal_thenLeaseMasTotalandReuse() throws InterruptedException { + HttpGet get = new HttpGet("http://echo.200please.com"); + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); + connManager.setDefaultMaxPerRoute(5); + connManager.setMaxTotal(5); + CloseableHttpClient client = HttpClients.custom() + .setConnectionManager(connManager) + .build(); + MultiHttpClientConnThread[] threads = new MultiHttpClientConnThread[10]; + for (int i = 0; i < threads.length; i++) { + threads[i] = new MultiHttpClientConnThread(client, get, connManager); + } + for (MultiHttpClientConnThread thread : threads) { + thread.start(); + } + for (MultiHttpClientConnThread thread : threads) { + thread.join(1000); + } + } + + // Example 7.1. Setting Socket Timeout to 5 Seconds + @Test + public final void whenConfiguringTimeOut_thenNoExceptions() { + HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 80)); + try (PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager()) { + connManager.setSocketConfig(route.getTargetHost(), SocketConfig.custom() + .setSoTimeout(5000) + .build()); + assertTrue(connManager.getSocketConfig(route.getTargetHost()) + .getSoTimeout() == 5000); + } + } + + // Example 8.1. Setting the HttpClient to Check for Stale Connections + @Test + public final void whenHttpClientChecksStaleConns_thenNoExceptions() { + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); + HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setStaleConnectionCheckEnabled(true) + .build()) + .setConnectionManager(connManager) + .build(); + } + + // Example 8.2. Using a Stale Connection Monitor Thread + @Test + public final void whenCustomizedIdleConnMonitor_thenNoExceptions() throws InterruptedException { + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); + HttpClients.custom() + .setConnectionManager(connManager) + .build(); + IdleConnectionMonitorThread staleMonitor = new IdleConnectionMonitorThread(connManager); + staleMonitor.start(); + staleMonitor.join(1000); + } + + // Example 9.1. Closing Connection and Releasing Resources + @Test(expected = IllegalStateException.class) + public final void whenClosingConnectionsandManager_thenCloseWithNoExceptions1() throws InterruptedException, ExecutionException, IOException, HttpException { + PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); + CloseableHttpClient client = HttpClients.custom() + .setConnectionManager(connManager) + .build(); + final HttpGet get = new HttpGet("http://google.com"); + CloseableHttpResponse response = client.execute(get); + + EntityUtils.consume(response.getEntity()); + response.close(); + client.close(); + connManager.close(); + connManager.shutdown(); + + client.execute(get); + + assertTrue(response.getEntity() == null); + } + + @Test + // Example 3.2. TESTER VERSION + public final void whenTwoConnectionsForTwoRequests_thenTwoConnectionsAreLeased() throws InterruptedException { + HttpGet get1 = new HttpGet("https://www.baeldung.com"); + HttpGet get2 = new HttpGet("https://www.google.com"); + + PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); + final CloseableHttpClient client1 = HttpClients.custom() + .setConnectionManager(poolingConnManager) + .build(); + final CloseableHttpClient client2 = HttpClients.custom() + .setConnectionManager(poolingConnManager) + .build(); + + final TesterVersion_MultiHttpClientConnThread thread1 = new TesterVersion_MultiHttpClientConnThread(client1, get1, poolingConnManager); + final TesterVersion_MultiHttpClientConnThread thread2 = new TesterVersion_MultiHttpClientConnThread(client2, get2, poolingConnManager); + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(1000); + assertTrue(poolingConnManager.getTotalStats() + .getLeased() == 2); + } + + @Test + // Example 4.2 Tester Version + public final void whenExecutingSameRequestsInDifferentThreads_thenUseDefaultConnLimit() throws InterruptedException { + PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); + CloseableHttpClient client = HttpClients.custom() + .setConnectionManager(poolingConnManager) + .build(); + final TesterVersion_MultiHttpClientConnThread thread1 = new TesterVersion_MultiHttpClientConnThread(client, new HttpGet("http://www.google.com"), poolingConnManager); + final TesterVersion_MultiHttpClientConnThread thread2 = new TesterVersion_MultiHttpClientConnThread(client, new HttpGet("http://www.google.com"), poolingConnManager); + final TesterVersion_MultiHttpClientConnThread thread3 = new TesterVersion_MultiHttpClientConnThread(client, new HttpGet("http://www.google.com"), poolingConnManager); + thread1.start(); + thread2.start(); + thread3.start(); + thread1.join(10000); + thread2.join(10000); + thread3.join(10000); + } + @Test - // @Ignore // 6.2 TESTER VERSION - /*tester*/ public final void whenConnectionsNeededGreaterThanMaxTotal_thenReuseConnections() throws InterruptedException { - poolingConnManager = new PoolingHttpClientConnectionManager(); + public final void whenConnectionsNeededGreaterThanMaxTotal_thenReuseConnections() throws InterruptedException { + PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); poolingConnManager.setDefaultMaxPerRoute(5); poolingConnManager.setMaxTotal(5); - client = HttpClients.custom().setConnectionManager(poolingConnManager).build(); + CloseableHttpClient client = HttpClients.custom() + .setConnectionManager(poolingConnManager) + .build(); final MultiHttpClientConnThread[] threads = new MultiHttpClientConnThread[10]; int countConnMade = 0; for (int i = 0; i < threads.length; i++) { - threads[i] = new MultiHttpClientConnThread(client, get1, poolingConnManager); + threads[i] = new MultiHttpClientConnThread(client, new HttpGet("http://www.baeldung.com/"), poolingConnManager); } for (final MultiHttpClientConnThread thread : threads) { thread.start(); @@ -288,58 +321,16 @@ public class HttpClientConnectionManagementLiveTest { } } - @Test - // 6.2 ARTICLE VERSION - // @Ignore - public final void whenConnectionsNeededGreaterThanMaxTotal_thenLeaseMasTotalandReuse() throws InterruptedException { - final HttpGet get = new HttpGet("http://echo.200please.com"); - poolingConnManager = new PoolingHttpClientConnectionManager(); - poolingConnManager.setDefaultMaxPerRoute(5); - poolingConnManager.setMaxTotal(5); - client = HttpClients.custom().setConnectionManager(poolingConnManager).build(); - final MultiHttpClientConnThread[] threads = new MultiHttpClientConnThread[10]; - for (int i = 0; i < threads.length; i++) { - threads[i] = new MultiHttpClientConnThread(client, get, poolingConnManager); - } - for (final MultiHttpClientConnThread thread : threads) { - thread.start(); - } - for (final MultiHttpClientConnThread thread : threads) { - thread.join(10000); - } - } - - // 7 - - @Test - // 7.1 - public final void whenConfiguringTimeOut_thenNoExceptions() { - route = new HttpRoute(new HttpHost("localhost", 80)); - poolingConnManager = new PoolingHttpClientConnectionManager(); - poolingConnManager.setSocketConfig(route.getTargetHost(), SocketConfig.custom().setSoTimeout(5000).build()); - assertTrue(poolingConnManager.getSocketConfig(route.getTargetHost()).getSoTimeout() == 5000); - } - - // 8 - - @Test - // @Ignore - // 8.1 - public final void whenHttpClientChecksStaleConns_thenNoExceptions() { - poolingConnManager = new PoolingHttpClientConnectionManager(); - poolingConnManager.setValidateAfterInactivity(1000); - client = HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom().build()).setConnectionManager(poolingConnManager).build(); - } - @Test @Ignore("Very Long Running") // 8.2 TESTER VERSION - /*tester*/ public final void whenCustomizedIdleConnMonitor_thenEliminateIdleConns() throws InterruptedException, IOException { - poolingConnManager = new PoolingHttpClientConnectionManager(); - client = HttpClients.custom().setConnectionManager(poolingConnManager).build(); + public final void whenCustomizedIdleConnMonitor_thenEliminateIdleConns() throws InterruptedException { + PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); + CloseableHttpClient client = HttpClients.custom() + .setConnectionManager(poolingConnManager) + .build(); final IdleConnectionMonitorThread staleMonitor = new IdleConnectionMonitorThread(poolingConnManager); final HttpGet get = new HttpGet("http://google.com"); - // test this with new HttpGet("http://iotechperu.com")----First test will fail b/c there is redirect connection at that site final TesterVersion_MultiHttpClientConnThread thread1 = new TesterVersion_MultiHttpClientConnThread(client, get, poolingConnManager); final TesterVersion_MultiHttpClientConnThread thread2 = new TesterVersion_MultiHttpClientConnThread(client, get, poolingConnManager); final TesterVersion_MultiHttpClientConnThread thread3 = new TesterVersion_MultiHttpClientConnThread(client, get, poolingConnManager); @@ -349,43 +340,10 @@ public class HttpClientConnectionManagementLiveTest { thread2.start(); thread2.join(); thread3.start(); - assertTrue(poolingConnManager.getTotalStats().getAvailable() == 1); + assertTrue(poolingConnManager.getTotalStats() + .getAvailable() == 1); thread3.join(32000); - assertTrue(poolingConnManager.getTotalStats().getAvailable() == 0); + assertTrue(poolingConnManager.getTotalStats() + .getAvailable() == 0); } - - @Test - // @Ignore - // 8.2 ARTICLE VERSION - public final void whenCustomizedIdleConnMonitor_thenNoExceptions() throws InterruptedException, IOException { - new HttpGet("http://google.com"); - poolingConnManager = new PoolingHttpClientConnectionManager(); - client = HttpClients.custom().setConnectionManager(poolingConnManager).build(); - final IdleConnectionMonitorThread staleMonitor = new IdleConnectionMonitorThread(poolingConnManager); - staleMonitor.start(); - staleMonitor.join(1000); - } - - // 9 - - @Test(expected = IllegalStateException.class) - // @Ignore - // 9.1 - public final void whenClosingConnectionsandManager_thenCloseWithNoExceptions1() throws InterruptedException, ExecutionException, IOException, HttpException { - poolingConnManager = new PoolingHttpClientConnectionManager(); - client = HttpClients.custom().setConnectionManager(poolingConnManager).build(); - final HttpGet get = new HttpGet("http://google.com"); - response = client.execute(get); - - EntityUtils.consume(response.getEntity()); - response.close(); - client.close(); - poolingConnManager.close(); - poolingConnManager.shutdown(); - - client.execute(get); - - assertTrue(response.getEntity() == null); - } - } From 95919f4a6d04f19c51da6378b59db0b602f312a4 Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Sat, 26 Mar 2022 22:25:43 +0530 Subject: [PATCH 187/249] JAVA-10378 Updated url for https://www.baeldung.com/httpclient-connection-management in README.md --- httpclient/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/httpclient/README.md b/httpclient/README.md index 23fe7c7271..3c5b0b3376 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -18,4 +18,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Advanced HttpClient Configuration](https://www.baeldung.com/httpclient-advanced-config) - [HttpClient 4 – Do Not Follow Redirects](https://www.baeldung.com/httpclient-stop-follow-redirect) - [Custom User-Agent in HttpClient 4](https://www.baeldung.com/httpclient-user-agent-header) +- [Apache HttpClient Connection Management](https://www.baeldung.com/httpclient-connection-management) - More articles: [[next -->]](../httpclient-2) From c9637e95fd2f43c54f485ea97e297c23fe33fda3 Mon Sep 17 00:00:00 2001 From: vaibhav007jain <72961247+vaibhav007jain@users.noreply.github.com> Date: Sun, 27 Mar 2022 09:03:29 +0530 Subject: [PATCH 188/249] BAEL-5463: added code for for-each loop in Java. (#11960) --- .../controlstructures/loops/ForEachLoop.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 core-java-modules/core-java-lang-syntax-2/src/main/java/com/baeldung/core/controlstructures/loops/ForEachLoop.java diff --git a/core-java-modules/core-java-lang-syntax-2/src/main/java/com/baeldung/core/controlstructures/loops/ForEachLoop.java b/core-java-modules/core-java-lang-syntax-2/src/main/java/com/baeldung/core/controlstructures/loops/ForEachLoop.java new file mode 100644 index 0000000000..88f49f60db --- /dev/null +++ b/core-java-modules/core-java-lang-syntax-2/src/main/java/com/baeldung/core/controlstructures/loops/ForEachLoop.java @@ -0,0 +1,57 @@ +package com.baeldung.core.controlstructures.loops; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class ForEachLoop { + + public static void main(String[] args) { + + int[] numbers = { 1, 2, 3, 4, 5 }; + List wordsList = new ArrayList<>(); + wordsList.add("Java"); + wordsList.add("is"); + wordsList.add("great!"); + + Set wordsSet = new HashSet<>(); + wordsSet.addAll(wordsList); + + Map map = new HashMap<>(); + map.put(1, "Java"); + map.put(2, "is"); + map.put(3, "great!"); + + traverseArray(numbers); + traverseList(wordsList); + traverseSet(wordsSet); + traverseMap(map); + } + + private static void traverseMap(Map map) { + for (Map.Entry entry : map.entrySet()) { + System.out.println("number: " + entry.getKey() + " - " + "word: " + entry.getValue()); + } + } + + private static void traverseSet(Set wordsSet) { + for (String word : wordsSet) { + System.out.println(word + " "); + } + } + + private static void traverseList(List wordsList) { + for (String word : wordsList) { + System.out.println(word + " "); + } + } + + private static void traverseArray(int[] numbers) { + for (int number : numbers) { + System.out.println(number + " "); + } + } +} From 1377f718eb7b81d2bb1da56b5923288423a0f567 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sun, 27 Mar 2022 10:55:35 +0530 Subject: [PATCH 189/249] JAVA-10922 Fix RestTemplateBasicLiveTest in spring-resttemplate module --- .../com/baeldung/resttemplate/configuration/FooController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/FooController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/FooController.java index dbef16b592..0931bf148c 100644 --- a/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/FooController.java +++ b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/FooController.java @@ -9,6 +9,7 @@ import java.util.Map; import com.baeldung.resttemplate.web.dto.Foo; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; @@ -114,7 +115,7 @@ public class FooController { return id; } - @RequestMapping(method = RequestMethod.POST, value = "/foos/form") + @RequestMapping(method = RequestMethod.POST, value = "/foos/form", produces = MediaType.TEXT_PLAIN_VALUE) @ResponseStatus(HttpStatus.CREATED) @ResponseBody public String submitFoo(@RequestParam("id") String id) { From 3eeb5c7d2bcabc577da00c2c537990d4148d6595 Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Sun, 27 Mar 2022 18:24:31 +0200 Subject: [PATCH 190/249] read user input (#11946) * read user input * rename the unittest class --- .../baeldung/userinput/UserInputHandler.java | 27 ++++++++++++++ .../userinput/UserInputHandlerUnitTest.java | 36 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 core-java-modules/core-java-io-4/src/main/java/com/baeldung/userinput/UserInputHandler.java create mode 100644 core-java-modules/core-java-io-4/src/test/java/com/baeldung/userinput/UserInputHandlerUnitTest.java diff --git a/core-java-modules/core-java-io-4/src/main/java/com/baeldung/userinput/UserInputHandler.java b/core-java-modules/core-java-io-4/src/main/java/com/baeldung/userinput/UserInputHandler.java new file mode 100644 index 0000000000..dfbb1fb03c --- /dev/null +++ b/core-java-modules/core-java-io-4/src/main/java/com/baeldung/userinput/UserInputHandler.java @@ -0,0 +1,27 @@ +package com.baeldung.userinput; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class UserInputHandler { + + public static List readUserInput() { + List userData = new ArrayList<>(); + System.out.println("Please enter your data below: (send 'bye' to exit) "); + Scanner input = new Scanner(System.in); + while (true) { + String line = input.nextLine(); + if ("bye".equalsIgnoreCase(line)) { + break; + } + userData.add(line); + } + return userData; + } + + public static void main(String[] args) { + List userData = readUserInput(); + System.out.printf("User Input Data:\n%s", String.join("\n", userData)); + } +} diff --git a/core-java-modules/core-java-io-4/src/test/java/com/baeldung/userinput/UserInputHandlerUnitTest.java b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/userinput/UserInputHandlerUnitTest.java new file mode 100644 index 0000000000..b4520ec100 --- /dev/null +++ b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/userinput/UserInputHandlerUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.userinput; + + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + +public class UserInputHandlerUnitTest { + + @Test + public void givenDataInSystemIn_whenCallingReadUserInputMethod_thenHaveUserInputData() { + String[] inputLines = new String[]{ + "The first line.", + "The second line.", + "The last line.", + "bye", + "anything after 'bye' will be ignored" + }; + String[] expectedLines = Arrays.copyOf(inputLines, inputLines.length - 2); + List expected = Arrays.stream(expectedLines).collect(Collectors.toList()); + InputStream stdin = System.in; + try { + System.setIn(new ByteArrayInputStream(String.join("\n", inputLines).getBytes())); + List actual = UserInputHandler.readUserInput(); + assertThat(actual).isEqualTo(expected); + } finally { + System.setIn(stdin); + } + } +} \ No newline at end of file From f27e8e8dd9b47578b2f590c7aad54b1c5d54a1be Mon Sep 17 00:00:00 2001 From: lucaCambi77 Date: Mon, 28 Mar 2022 03:06:14 +0200 Subject: [PATCH 191/249] [ BAEL-5405 ] Logging MongoDB Queries with Spring Boot (#11952) * feat: spring data mongodb logging * fix: PMD * fix: typo * fix: move to main logging * fix: add manual config --- .../java/com/baeldung/logging/model/Book.java | 53 ++++++ .../com/baeldung/logging/GroupByAuthor.java | 32 ++++ .../com/baeldung/logging/LoggingUnitTest.java | 158 ++++++++++++++++++ 3 files changed, 243 insertions(+) create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/logging/model/Book.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/GroupByAuthor.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/LoggingUnitTest.java diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/logging/model/Book.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/logging/model/Book.java new file mode 100644 index 0000000000..d15c7f47c5 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/logging/model/Book.java @@ -0,0 +1,53 @@ +package com.baeldung.logging.model; + +import java.util.Objects; + +import org.bson.types.ObjectId; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.MongoId; + +@Document(collection = "book") +public class Book { + + @MongoId + private ObjectId id; + + private String bookName; + + private String authorName; + + public ObjectId getId() { + return id; + } + + public String getBookName() { + return bookName; + } + + public void setBookName(String bookName) { + this.bookName = bookName; + } + + public String getAuthorName() { + return authorName; + } + + public void setAuthorName(String authorName) { + this.authorName = authorName; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Book book = (Book) o; + return Objects.equals(id, book.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/GroupByAuthor.java b/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/GroupByAuthor.java new file mode 100644 index 0000000000..170e76f23e --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/GroupByAuthor.java @@ -0,0 +1,32 @@ +package com.baeldung.logging; + +import org.springframework.data.annotation.Id; + +public class GroupByAuthor { + + @Id + private String authorName; + private int authCount; + + public GroupByAuthor(String authorName, int authCount) { + this.authorName = authorName; + this.authCount = authCount; + } + + public String getAuthorName() { + return authorName; + } + + public void setAuthorName(String authorName) { + this.authorName = authorName; + } + + public int getAuthCount() { + return authCount; + } + + public void setAuthCount(int authCount) { + this.authCount = authCount; + } + +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/LoggingUnitTest.java b/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/LoggingUnitTest.java new file mode 100644 index 0000000000..577e039176 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/LoggingUnitTest.java @@ -0,0 +1,158 @@ +package com.baeldung.logging; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.group; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregation; +import static org.springframework.data.mongodb.core.query.Criteria.where; +import static org.springframework.data.mongodb.core.query.Query.query; +import static org.springframework.data.mongodb.core.query.Update.update; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.aggregation.Aggregation; +import org.springframework.data.mongodb.core.aggregation.AggregationResults; +import org.springframework.data.mongodb.core.aggregation.GroupOperation; +import org.springframework.test.context.TestPropertySource; + +import com.baeldung.logging.model.Book; +import com.mongodb.client.MongoClients; + +import de.flapdoodle.embed.mongo.MongodExecutable; +import de.flapdoodle.embed.mongo.MongodStarter; +import de.flapdoodle.embed.mongo.config.ImmutableMongodConfig; +import de.flapdoodle.embed.mongo.config.MongodConfig; +import de.flapdoodle.embed.mongo.config.Net; +import de.flapdoodle.embed.mongo.distribution.Version; +import de.flapdoodle.embed.process.runtime.Network; + +@SpringBootTest +@TestPropertySource(properties = { "logging.level.org.springframework.data.mongodb.core.MongoTemplate=DEBUG" }) +public class LoggingUnitTest { + + private static final String CONNECTION_STRING = "mongodb://%s:%d"; + + private MongodExecutable mongodExecutable; + private MongoTemplate mongoTemplate; + + @AfterEach + void clean() { + mongodExecutable.stop(); + } + + @BeforeEach + void setup() throws Exception { + String ip = "localhost"; + int port = 27017; + + ImmutableMongodConfig mongodConfig = MongodConfig.builder() + .version(Version.Main.PRODUCTION) + .net(new Net(ip, port, Network.localhostIsIPv6())) + .build(); + + MongodStarter starter = MongodStarter.getDefaultInstance(); + mongodExecutable = starter.prepare(mongodConfig); + mongodExecutable.start(); + mongoTemplate = new MongoTemplate(MongoClients.create(String.format(CONNECTION_STRING, ip, port)), "test"); + } + + @Test + void whenInsertDocument_thenFindByIdOk() { + Book book = new Book(); + book.setBookName("Book"); + book.setAuthorName("Author"); + + mongoTemplate.insert(book); + + assertThat(mongoTemplate.findById(book.getId(), Book.class)).isEqualTo(book); + } + + @Test + void givenExistingDocument_whenUpdateDocument_thenFieldIsUpdatedOk() { + Book book = new Book(); + book.setBookName("Book"); + book.setAuthorName("Author"); + + mongoTemplate.insert(book); + + String authorNameUpdate = "AuthorNameUpdate"; + + book.setAuthorName(authorNameUpdate); + mongoTemplate.updateFirst(query(where("bookName").is("Book")), update("authorName", authorNameUpdate), Book.class); + + assertThat(mongoTemplate.findById(book.getId(), Book.class)).extracting(Book::getAuthorName) + .isEqualTo(authorNameUpdate); + } + + @Test + void whenInsertMultipleDocuments_thenFindAllOk() { + Book book = new Book(); + book.setBookName("Book"); + book.setAuthorName("Author"); + + Book book1 = new Book(); + book1.setBookName("Book1"); + book1.setAuthorName("Author1"); + + mongoTemplate.insert(Arrays.asList(book, book1), Book.class); + + assertThat(mongoTemplate.findAll(Book.class) + .size()).isEqualTo(2); + } + + @Test + void givenExistingDocument_whenRemoveDocument_thenDocumentIsDeleted() { + Book book = new Book(); + book.setBookName("Book"); + book.setAuthorName("Author"); + + mongoTemplate.insert(book); + + mongoTemplate.remove(book); + + assertThat(mongoTemplate.findAll(Book.class) + .size()).isEqualTo(0); + } + + @Test + void whenAggregateByField_thenGroupByCountIsOk() { + Book book = new Book(); + book.setBookName("Book"); + book.setAuthorName("Author"); + + Book book1 = new Book(); + book1.setBookName("Book1"); + book1.setAuthorName("Author"); + + Book book2 = new Book(); + book2.setBookName("Book2"); + book2.setAuthorName("Author"); + + mongoTemplate.insert(Arrays.asList(book, book1, book2), Book.class); + + GroupOperation groupByAuthor = group("authorName").count() + .as("authCount"); + + Aggregation aggregation = newAggregation(groupByAuthor); + + AggregationResults aggregationResults = mongoTemplate.aggregate(aggregation, "book", GroupByAuthor.class); + + List groupByAuthorList = StreamSupport.stream(aggregationResults.spliterator(), false) + .collect(Collectors.toList()); + + assertThat(groupByAuthorList.stream() + .filter(l -> l.getAuthorName() + .equals("Author")) + .findFirst() + .orElse(null)).extracting(GroupByAuthor::getAuthCount) + .isEqualTo(3); + } + +} From 0c229c433ff4ba7e0bab1dfe3bad37859915188c Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Mon, 28 Mar 2022 03:16:58 +0200 Subject: [PATCH 192/249] add SetDiff for BAEL-5464 article (#11969) * add SetDiff for BAEL-5464 article * rename the method --- .../main/java/com/baeldung/set/SetDiff.java | 28 +++++++++ .../com/baeldung/set/SetDiffUnitTest.java | 61 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/SetDiff.java create mode 100644 core-java-modules/core-java-collections-set/src/test/java/com/baeldung/set/SetDiffUnitTest.java diff --git a/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/SetDiff.java b/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/SetDiff.java new file mode 100644 index 0000000000..4a62c99efd --- /dev/null +++ b/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/SetDiff.java @@ -0,0 +1,28 @@ +package com.baeldung.set; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +public class SetDiff { + + public static Set findSymmetricDiff(Set set1, Set set2) { + Map map = new HashMap<>(); + set1.forEach(e -> putKey(map, e)); + set2.forEach(e -> putKey(map, e)); + return map.entrySet().stream() + .filter(e -> e.getValue() == 1) + .map(Map.Entry::getKey) + .collect(Collectors.toSet()); + } + + private static void putKey(Map map, T key) { + if (map.containsKey(key)) { + map.replace(key, Integer.MAX_VALUE); + } else { + map.put(key, 1); + } + } + +} diff --git a/core-java-modules/core-java-collections-set/src/test/java/com/baeldung/set/SetDiffUnitTest.java b/core-java-modules/core-java-collections-set/src/test/java/com/baeldung/set/SetDiffUnitTest.java new file mode 100644 index 0000000000..c217950a35 --- /dev/null +++ b/core-java-modules/core-java-collections-set/src/test/java/com/baeldung/set/SetDiffUnitTest.java @@ -0,0 +1,61 @@ +package com.baeldung.set; + +import com.google.common.collect.Sets; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.SetUtils; +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SetDiffUnitTest { + private final static Set immutableSet1 = Set.of("Kotlin", "Java", "Rust", "Python", "C++"); + private final static Set immutableSet2 = Set.of("Kotlin", "Java", "Rust", "Ruby", "C#"); + private final static Set expectedOnlyInSet1 = Set.of("Python", "C++"); + private final static Set expectedDiff = Set.of("Python", "C++", "Ruby", "C#"); + + @Test + public void givenAnotherSet_whenRemoveAll_shouldGetDiff() { + Set set1 = Stream.of("Kotlin", "Java", "Rust", "Python", "C++").collect(Collectors.toSet()); + Set set2 = Stream.of("Kotlin", "Java", "Rust", "Ruby", "C#").collect(Collectors.toSet()); + Set expectedOnlyInSet1 = Set.of("Python", "C++"); + set1.removeAll(set2); + assertThat(set1).isEqualTo(expectedOnlyInSet1); + } + + @Test + public void givenAnotherSet_whenUsingStreamFilter_shouldGet() { + Set actualOnlyInSet1 = immutableSet1.stream().filter(e -> !immutableSet2.contains(e)).collect(Collectors.toSet()); + assertThat(actualOnlyInSet1).isEqualTo(expectedOnlyInSet1); + } + + @Test + public void givenAnotherSet_whenCallingGuavaMethod_shouldGetDiff() { + Set actualOnlyInSet1 = Sets.difference(immutableSet1, immutableSet2); + assertThat(actualOnlyInSet1).isEqualTo(expectedOnlyInSet1); + } + + @Test + public void givenAnotherSet_whenCallingCommonsMethod_shouldGetDiff() { + Set actualOnlyInSet1 = new HashSet<>(CollectionUtils.removeAll(immutableSet1, immutableSet2)); + assertThat(actualOnlyInSet1).isEqualTo(expectedOnlyInSet1); + } + + + @Test + public void givenTwoSets_whenCallingFindDisjunction_shouldGetDisjunction() { + Set actualDiff = SetDiff.findSymmetricDiff(immutableSet1, immutableSet2); + assertThat(actualDiff).isEqualTo(expectedDiff); + } + + @Test + public void givenTwoSets_whenCallingCommonsMethod_shouldGetDisjunction() { + Set actualDiff = SetUtils.disjunction(immutableSet1, immutableSet2); + assertThat(actualDiff).isEqualTo(expectedDiff); + } + +} From 8f2cc51af441cb5700f34610aba8d57225cf80f7 Mon Sep 17 00:00:00 2001 From: Bhaskara Date: Mon, 28 Mar 2022 20:45:16 +0530 Subject: [PATCH 193/249] BAEL-5298 (#11965) * BAEL-5298 * Renamed the tests * Changed the Parent to parent-boot-2 Co-authored-by: Bhaskara Navuluri --- feign/pom.xml | 96 ++++++++++++++++-- .../feign/soap/FeignSoapApplication.java | 14 +++ .../com/baeldung/feign/soap/SoapClient.java | 14 +++ .../baeldung/feign/soap/UsersEndpoint.java | 36 +++++++ .../feign/soap/WebServicesConfiguration.java | 52 ++++++++++ .../src/main/resources/application.properties | 7 ++ feign/src/main/resources/users.xsd | 44 +++++++++ .../feign/clients/BookClientLiveTest.java | 35 +++---- .../retry/Custom5xxErrorDecoderUnitTest.java | 21 ++-- .../baeldung/feign/soap/FeignLiveTest.java | 99 +++++++++++++++++++ 10 files changed, 376 insertions(+), 42 deletions(-) create mode 100644 feign/src/main/java/com/baeldung/feign/soap/FeignSoapApplication.java create mode 100644 feign/src/main/java/com/baeldung/feign/soap/SoapClient.java create mode 100644 feign/src/main/java/com/baeldung/feign/soap/UsersEndpoint.java create mode 100644 feign/src/main/java/com/baeldung/feign/soap/WebServicesConfiguration.java create mode 100644 feign/src/main/resources/application.properties create mode 100644 feign/src/main/resources/users.xsd create mode 100644 feign/src/test/java/com/baeldung/feign/soap/FeignLiveTest.java diff --git a/feign/pom.xml b/feign/pom.xml index cf28890868..026afdfc7a 100644 --- a/feign/pom.xml +++ b/feign/pom.xml @@ -1,7 +1,5 @@ - + 4.0.0 com.baeldung.feign feign @@ -9,10 +7,17 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 + + 1.8 + 11.8 + 1.6.3 + + io.github.openfeign @@ -35,10 +40,85 @@ ${lombok.version} provided + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-web-services + + + wsdl4j + wsdl4j + ${wsdl4j.version} + + + io.github.openfeign + feign-hc5 + ${feign.version} + + + io.github.openfeign + feign-soap + ${feign.version} + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.codehaus.mojo + jaxb2-maven-plugin + 2.5.0 + + + xjc + + xjc + + + + + com.baeldung.feign.soap + + src/main/resources/users.xsd + - - 10.11 - + + + + org.jvnet.jaxb2.maven2 + maven-jaxb2-plugin + 0.14.0 + + + feign-soap-stub-generation + + generate + + + target/generated-sources/jaxb + + *.xsd + + + com.baeldung.feign.soap + target/generated-sources/jaxb + + + + + + + \ No newline at end of file diff --git a/feign/src/main/java/com/baeldung/feign/soap/FeignSoapApplication.java b/feign/src/main/java/com/baeldung/feign/soap/FeignSoapApplication.java new file mode 100644 index 0000000000..e10510bc2d --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/soap/FeignSoapApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.feign.soap; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication + +public class FeignSoapApplication { + + public static void main(String[] args) { + SpringApplication.run(FeignSoapApplication.class, args); + } + +} diff --git a/feign/src/main/java/com/baeldung/feign/soap/SoapClient.java b/feign/src/main/java/com/baeldung/feign/soap/SoapClient.java new file mode 100644 index 0000000000..b0dbb617ba --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/soap/SoapClient.java @@ -0,0 +1,14 @@ +package com.baeldung.feign.soap; + +import feign.Headers; +import feign.RequestLine; + +public interface SoapClient { + @RequestLine("POST") + @Headers({"SOAPAction: createUser", "Content-Type: text/xml;charset=UTF-8", "Accept: text/xml"}) + String createUserWithPlainText(String soapBody); + + @RequestLine("POST") + @Headers({"Content-Type: text/xml;charset=UTF-8"}) + CreateUserResponse createUserWithSoap(CreateUserRequest soapBody); +} diff --git a/feign/src/main/java/com/baeldung/feign/soap/UsersEndpoint.java b/feign/src/main/java/com/baeldung/feign/soap/UsersEndpoint.java new file mode 100644 index 0000000000..c39a4a265c --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/soap/UsersEndpoint.java @@ -0,0 +1,36 @@ +package com.baeldung.feign.soap; + +import org.springframework.ws.server.endpoint.annotation.Endpoint; +import org.springframework.ws.server.endpoint.annotation.PayloadRoot; +import org.springframework.ws.server.endpoint.annotation.RequestPayload; +import org.springframework.ws.server.endpoint.annotation.ResponsePayload; + +import java.util.HashMap; +import java.util.Map; + +@Endpoint +public class UsersEndpoint { + + private static final Map userMap = new HashMap<>(); + + @PayloadRoot(namespace = "http://www.baeldung.com/springbootsoap/feignclient", localPart = "getUserRequest") + @ResponsePayload + public GetUserResponse getUser(@RequestPayload GetUserRequest request) { + GetUserResponse response = new GetUserResponse(); + response.setUser(userMap.get(request.getId())); + return response; + } + + @PayloadRoot(namespace = "http://www.baeldung.com/springbootsoap/feignclient", localPart = "createUserRequest") + @ResponsePayload + public CreateUserResponse createUser(@RequestPayload CreateUserRequest request) { + CreateUserResponse response = new CreateUserResponse(); + if (request.getUser().getId().equalsIgnoreCase("500")) + throw new RuntimeException("This is a reserved user id"); + userMap.put(request.getUser().id, request.getUser()); + + response.setMessage("Success! Created the user with id - " + request.getUser().getId()); + return response; + } + +} diff --git a/feign/src/main/java/com/baeldung/feign/soap/WebServicesConfiguration.java b/feign/src/main/java/com/baeldung/feign/soap/WebServicesConfiguration.java new file mode 100644 index 0000000000..76ebfb392e --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/soap/WebServicesConfiguration.java @@ -0,0 +1,52 @@ +package com.baeldung.feign.soap; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.ws.config.annotation.EnableWs; +import org.springframework.ws.config.annotation.WsConfigurerAdapter; +import org.springframework.ws.transport.http.MessageDispatcherServlet; +import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; +import org.springframework.xml.xsd.SimpleXsdSchema; +import org.springframework.xml.xsd.XsdSchema; + +@EnableWs +@Configuration +public class WebServicesConfiguration extends WsConfigurerAdapter { + + @Value("${ws.api.path:/ws/api/v1/*}") + private String webserviceApiPath; + @Value("${ws.port.type.name:UsersPort}") + private String webservicePortTypeName; + @Value("${ws.target.namespace:http://www.baeldung.com/springbootsoap/feignclient}") + private String webserviceTargetNamespace; + @Value("${ws.location.uri:http://localhost:18080/ws/api/v1/}") + private String locationUri; + + @Bean + public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) { + MessageDispatcherServlet servlet = new MessageDispatcherServlet(); + servlet.setApplicationContext(applicationContext); + servlet.setTransformWsdlLocations(true); + return new ServletRegistrationBean<>(servlet, webserviceApiPath); + } + + @Bean(name = "users") + public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema usersSchema) { + DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition(); + wsdl11Definition.setPortTypeName(webservicePortTypeName); + wsdl11Definition.setTargetNamespace(webserviceTargetNamespace); + wsdl11Definition.setLocationUri(locationUri); + wsdl11Definition.setSchema(usersSchema); + return wsdl11Definition; + } + + @Bean + public XsdSchema userSchema() { + return new SimpleXsdSchema(new ClassPathResource("users.xsd")); + } + +} diff --git a/feign/src/main/resources/application.properties b/feign/src/main/resources/application.properties new file mode 100644 index 0000000000..a57c6e36a3 --- /dev/null +++ b/feign/src/main/resources/application.properties @@ -0,0 +1,7 @@ +server.port=18080 +# Custom properties begin here +ws.api.path=/ws/users/* +ws.port.type.name=UsersPort +ws.target.namespace=http://www.baeldung.com/springbootsoap/feignclient +ws.location.uri=http://localhost:${server.port}/ws/users/ +debug=false diff --git a/feign/src/main/resources/users.xsd b/feign/src/main/resources/users.xsd new file mode 100644 index 0000000000..0c7a139c9a --- /dev/null +++ b/feign/src/main/resources/users.xsd @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/feign/src/test/java/com/baeldung/feign/clients/BookClientLiveTest.java b/feign/src/test/java/com/baeldung/feign/clients/BookClientLiveTest.java index 6f6666de32..47caf308d0 100644 --- a/feign/src/test/java/com/baeldung/feign/clients/BookClientLiveTest.java +++ b/feign/src/test/java/com/baeldung/feign/clients/BookClientLiveTest.java @@ -4,8 +4,9 @@ import com.baeldung.feign.BookControllerFeignClientBuilder; import com.baeldung.feign.models.Book; import com.baeldung.feign.models.BookResource; import lombok.extern.slf4j.Slf4j; -import org.junit.Before; -import org.junit.Test; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.util.List; import java.util.UUID; @@ -13,49 +14,43 @@ import java.util.stream.Collectors; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * Consumes https://github.com/Baeldung/spring-hypermedia-api */ @Slf4j -public class BookClientLiveTest { +class BookClientLiveTest { private BookClient bookClient; - @Before - public void setup() { + @BeforeEach + void setup() { BookControllerFeignClientBuilder feignClientBuilder = new BookControllerFeignClientBuilder(); bookClient = feignClientBuilder.getBookClient(); } @Test - public void givenBookClient_shouldRunSuccessfully() throws Exception { - List books = bookClient.findAll() - .stream() - .map(BookResource::getBook) - .collect(Collectors.toList()); + void givenBookClient_shouldRunSuccessfully() throws Exception { + List books = bookClient.findAll().stream().map(BookResource::getBook).collect(Collectors.toList()); assertTrue(books.size() > 2); log.info("{}", books); } @Test - public void givenBookClient_shouldFindOneBook() throws Exception { - Book book = bookClient.findByIsbn("0151072558") - .getBook(); + void givenBookClient_shouldFindOneBook() throws Exception { + Book book = bookClient.findByIsbn("0151072558").getBook(); assertThat(book.getAuthor(), containsString("Orwell")); log.info("{}", book); } @Test - public void givenBookClient_shouldPostBook() throws Exception { - String isbn = UUID.randomUUID() - .toString(); + void givenBookClient_shouldPostBook() throws Exception { + String isbn = UUID.randomUUID().toString(); Book book = new Book(isbn, "Me", "It's me!", null, null); bookClient.create(book); - book = bookClient.findByIsbn(isbn) - .getBook(); + book = bookClient.findByIsbn(isbn).getBook(); assertThat(book.getAuthor(), is("Me")); log.info("{}", book); } diff --git a/feign/src/test/java/com/baeldung/feign/retry/Custom5xxErrorDecoderUnitTest.java b/feign/src/test/java/com/baeldung/feign/retry/Custom5xxErrorDecoderUnitTest.java index 8c43b42b76..d78bf60516 100644 --- a/feign/src/test/java/com/baeldung/feign/retry/Custom5xxErrorDecoderUnitTest.java +++ b/feign/src/test/java/com/baeldung/feign/retry/Custom5xxErrorDecoderUnitTest.java @@ -2,19 +2,17 @@ package com.baeldung.feign.retry; import feign.*; import feign.codec.ErrorDecoder; -import org.jetbrains.annotations.NotNull; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.nio.charset.Charset; -import java.util.Collection; import java.util.HashMap; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; -public class Custom5xxErrorDecoderUnitTest { +class Custom5xxErrorDecoderUnitTest { @Test - public void given5xxResponse_whenDecode_thenReturnRetryableException() { + void given5xxResponse_whenDecode_thenReturnRetryableException() { // given ErrorDecoder decoder = new Custom5xxErrorDecoder(); Response response = responseStub(500); @@ -27,7 +25,7 @@ public class Custom5xxErrorDecoderUnitTest { } @Test - public void given4xxResponse_whenDecode_thenReturnFeignException() { + void given4xxResponse_whenDecode_thenReturnFeignException() { // given ErrorDecoder decoder = new Custom5xxErrorDecoder(); Response response = responseStub(400); @@ -40,12 +38,7 @@ public class Custom5xxErrorDecoderUnitTest { assertFalse(exception instanceof RetryableException); } - @NotNull private Response responseStub(int status) { - return Response.builder() - .request(Request.create( - Request.HttpMethod.GET, "url", new HashMap<>(), new byte[0], Charset.defaultCharset(), new RequestTemplate())) - .status(status) - .build(); + return Response.builder().request(Request.create(Request.HttpMethod.GET, "url", new HashMap<>(), new byte[0], Charset.defaultCharset(), new RequestTemplate())).status(status).build(); } } diff --git a/feign/src/test/java/com/baeldung/feign/soap/FeignLiveTest.java b/feign/src/test/java/com/baeldung/feign/soap/FeignLiveTest.java new file mode 100644 index 0000000000..d9da31344b --- /dev/null +++ b/feign/src/test/java/com/baeldung/feign/soap/FeignLiveTest.java @@ -0,0 +1,99 @@ +package com.baeldung.feign.soap; + +import feign.Feign; +import feign.Logger; +import feign.hc5.ApacheHttp5Client; +import feign.jaxb.JAXBContextFactory; +import feign.slf4j.Slf4jLogger; +import feign.soap.SOAPDecoder; +import feign.soap.SOAPEncoder; +import feign.soap.SOAPErrorDecoder; +import org.junit.jupiter.api.Test; + +import javax.xml.ws.soap.SOAPFaultException; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +class FeignLiveTest { + @Test + void givenSOAPPayload_whenStringRequest_thenReturnSOAPResponse() { + //@formatter:off + String successMessage="Success! Created the user with id"; + SoapClient client = Feign.builder() + .client(new ApacheHttp5Client()) + .logger(new Slf4jLogger(SoapClient.class)) + .logLevel(Logger.Level.FULL) + .target(SoapClient.class, "http://localhost:18080/ws/users/"); + + assertDoesNotThrow(() -> client.createUserWithPlainText(soapPayload())); + + String soapResponse= client.createUserWithPlainText(soapPayload()); + + assertNotNull(soapResponse); + assertTrue(soapResponse.contains(successMessage)); + //@formatter:on + } + + @Test + void whenSoapRequest_thenReturnSoapResponse() { + JAXBContextFactory jaxbFactory = new JAXBContextFactory.Builder().withMarshallerJAXBEncoding("UTF-8").build(); + SoapClient client = Feign.builder() + .encoder(new SOAPEncoder(jaxbFactory)) + .errorDecoder(new SOAPErrorDecoder()) + .logger(new Slf4jLogger()) + .logLevel(Logger.Level.FULL) + .decoder(new SOAPDecoder(jaxbFactory)) + .target(SoapClient.class, "http://localhost:18080/ws/users/"); + CreateUserRequest request = new CreateUserRequest(); + + User user = new User(); + user.setId("501"); + user.setName("John Doe"); + user.setEmail("john.doe@gmail"); + request.setUser(user); + try { + CreateUserResponse response = client.createUserWithSoap(request); + assertNotNull(response); + assertNotNull(response.getMessage()); + assertTrue(response.getMessage().contains("Success")); + } catch (SOAPFaultException soapFaultException) { + fail(); + } + + } + + @Test + void whenSoapFault_thenThrowSOAPFaultException() { + JAXBContextFactory jaxbFactory = new JAXBContextFactory.Builder().withMarshallerJAXBEncoding("UTF-8").build(); + SoapClient client = Feign.builder() + .encoder(new SOAPEncoder(jaxbFactory)) + .errorDecoder(new SOAPErrorDecoder()) + .logger(new Slf4jLogger()) + .logLevel(Logger.Level.FULL) + .decoder(new SOAPDecoder(jaxbFactory)) + .target(SoapClient.class, "http://localhost:18080/ws/users/"); + CreateUserRequest request = new CreateUserRequest(); + + User user = new User(); + user.setId("500"); + user.setName("John Doe"); + user.setEmail("john.doe@gmail"); + request.setUser(user); + try { + client.createUserWithSoap(request); + } catch (SOAPFaultException soapFaultException) { + assertNotNull(soapFaultException.getMessage()); + assertTrue(soapFaultException.getMessage().contains("This is a reserved user id")); + } + + } + + private String soapPayload() { + return "\n" + " \n" + " \n" + " \n" + + " \n" + " 1\n" + " john doe\n" + " john.doe@gmail.com\n" + " \n" + " \n" + + " \n" + ""; + } +} From c2e38da0fb1524bb01f8ccc2f0368e7f03da197a Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 29 Mar 2022 20:36:29 +0530 Subject: [PATCH 194/249] JAVA-9809 Update tests in spring-resttemplate module --- .../spring-resttemplate/pom.xml | 18 ++++- .../java/com/baeldung/SpringContextTest.java | 6 +- .../java/com/baeldung/SpringTestConfig.java | 2 - .../client/TestRestTemplateBasicLiveTest.java | 10 +-- ...eServiceMockRestServiceServerUnitTest.java | 23 +++--- .../mock/EmployeeServiceUnitTest.java | 17 ++--- .../PactConsumerDrivenContractUnitTest.java | 76 +++++++++++++++++++ .../baeldung/pact/PactProviderLiveTest.java | 32 +++++--- .../RestTemplateBasicLiveTest.java | 27 +++---- .../resttemplate/RestTemplateLiveTest.java | 23 +++--- ...teResponseErrorHandlerIntegrationTest.java | 36 ++++----- 11 files changed, 181 insertions(+), 89 deletions(-) create mode 100644 spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactConsumerDrivenContractUnitTest.java diff --git a/spring-web-modules/spring-resttemplate/pom.xml b/spring-web-modules/spring-resttemplate/pom.xml index 4ad2f9dc58..e5a8ba5ea9 100644 --- a/spring-web-modules/spring-resttemplate/pom.xml +++ b/spring-web-modules/spring-resttemplate/pom.xml @@ -37,10 +37,16 @@ org.springframework.boot spring-boot-starter-test - + au.com.dius - pact-jvm-provider-junit_2.11 + pact-jvm-provider-junit5_2.12 ${pact.version} + + + au.com.dius + pact-jvm-consumer-junit5_2.12 + ${pact.version} + test @@ -112,6 +118,12 @@ org.springframework spring-test + + org.mockito + mockito-junit-jupiter + ${mockito.version} + test + @@ -263,7 +275,7 @@ 3.0.4 3.4.1 - 3.5.11 + 3.6.3 1.8 1.8 3.7.0 diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java index 68b7f14916..f59f7ac976 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java @@ -1,9 +1,11 @@ package com.baeldung; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -@SpringBootTest +import com.baeldung.resttemplate.RestTemplateConfigurationApplication; + +@SpringBootTest(classes= RestTemplateConfigurationApplication.class) public class SpringContextTest { @Test diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringTestConfig.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringTestConfig.java index c626d1021d..4cd7f3ef07 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringTestConfig.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringTestConfig.java @@ -1,10 +1,8 @@ package com.baeldung; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.springframework.web.client.RestTemplate; @Configuration @EnableAutoConfiguration diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/client/TestRestTemplateBasicLiveTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/client/TestRestTemplateBasicLiveTest.java index 406dd5979b..86f188d27a 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/client/TestRestTemplateBasicLiveTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/client/TestRestTemplateBasicLiveTest.java @@ -2,11 +2,11 @@ package com.baeldung.client; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertTrue; import com.baeldung.resttemplate.web.dto.Foo; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Assertions; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.HttpHeaders; @@ -27,7 +27,7 @@ public class TestRestTemplateBasicLiveTest { private static final String URL_SECURED_BY_AUTHENTICATION = "http://httpbin.org/basic-auth/user/passwd"; private static final String BASE_URL = "http://localhost:" + 8082 + "/spring-rest"; - @Before + @BeforeEach public void beforeTest() { restTemplate = new RestTemplate(); } @@ -98,7 +98,7 @@ public class TestRestTemplateBasicLiveTest { public void givenFooService_whenCallHeadForHeaders_thenReceiveAllHeaders() { TestRestTemplate testRestTemplate = new TestRestTemplate(); final HttpHeaders httpHeaders = testRestTemplate.headForHeaders(FOO_RESOURCE_URL); - assertTrue(httpHeaders.getContentType().includes(MediaType.APPLICATION_JSON)); + Assertions.assertTrue(httpHeaders.getContentType().includes(MediaType.APPLICATION_JSON)); } // POST diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/mock/EmployeeServiceMockRestServiceServerUnitTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/mock/EmployeeServiceMockRestServiceServerUnitTest.java index 309e0635a4..53ef50937c 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/mock/EmployeeServiceMockRestServiceServerUnitTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/mock/EmployeeServiceMockRestServiceServerUnitTest.java @@ -6,14 +6,10 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat import java.net.URI; -import com.baeldung.SpringTestConfig; -import com.baeldung.mock.EmployeeService; -import com.baeldung.resttemplate.web.model.Employee; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -21,15 +17,16 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.client.ExpectedCount; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.web.client.RestTemplate; +import com.baeldung.SpringTestConfig; +import com.baeldung.resttemplate.web.model.Employee; import com.fasterxml.jackson.databind.ObjectMapper; -@RunWith(SpringRunner.class) +@ExtendWith(SpringExtension.class) @SpringBootTest(classes = SpringTestConfig.class) public class EmployeeServiceMockRestServiceServerUnitTest { @@ -45,7 +42,7 @@ public class EmployeeServiceMockRestServiceServerUnitTest { private ObjectMapper mapper = new ObjectMapper(); - @Before + @BeforeEach public void init() { mockServer = MockRestServiceServer.createServer(restTemplate); } @@ -63,7 +60,7 @@ public class EmployeeServiceMockRestServiceServerUnitTest { Employee employee = empService.getEmployee("E001"); mockServer.verify(); - Assert.assertEquals(emp, employee); + Assertions.assertEquals(emp, employee); } } diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/mock/EmployeeServiceUnitTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/mock/EmployeeServiceUnitTest.java index 6e2072efe3..4c6e2fa5ca 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/mock/EmployeeServiceUnitTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/mock/EmployeeServiceUnitTest.java @@ -1,22 +1,21 @@ package com.baeldung.mock; -import com.baeldung.mock.EmployeeService; -import com.baeldung.resttemplate.web.model.Employee; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; -@RunWith(MockitoJUnitRunner.class) +import com.baeldung.resttemplate.web.model.Employee; + +@ExtendWith(MockitoExtension.class) public class EmployeeServiceUnitTest { private static final Logger logger = LoggerFactory.getLogger(EmployeeServiceUnitTest.class); @@ -35,7 +34,7 @@ public class EmployeeServiceUnitTest { Employee employee = empService.getEmployee("E001"); - Assert.assertEquals(emp, employee); + Assertions.assertEquals(emp, employee); } } diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactConsumerDrivenContractUnitTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactConsumerDrivenContractUnitTest.java new file mode 100644 index 0000000000..bda7d09c49 --- /dev/null +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactConsumerDrivenContractUnitTest.java @@ -0,0 +1,76 @@ +package com.baeldung.pact; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; + +import au.com.dius.pact.consumer.MockServer; +import au.com.dius.pact.consumer.Pact; +import au.com.dius.pact.consumer.dsl.PactDslWithProvider; +import au.com.dius.pact.consumer.junit5.PactConsumerTestExt; +import au.com.dius.pact.consumer.junit5.PactTestFor; +import au.com.dius.pact.model.RequestResponsePact; + +@ExtendWith(PactConsumerTestExt.class) +@PactTestFor(providerName = "test_provider", hostInterface="localhost", port = "8080") +public class PactConsumerDrivenContractUnitTest { + + @Pact(provider="test_provider", consumer = "test_consumer") + public RequestResponsePact createPact(PactDslWithProvider builder) { + Map headers = new HashMap<>(); + headers.put("Content-Type", "application/json"); + + return builder + .given("test GET") + .uponReceiving("GET REQUEST") + .path("/pact") + .method("GET") + .willRespondWith() + .status(200) + .headers(headers) + .body("{\"condition\": true, \"name\": \"tom\"}") + .given("test POST") + .uponReceiving("POST REQUEST") + .method("POST") + .headers(headers) + .body("{\"name\": \"Michael\"}") + .path("/pact") + .willRespondWith() + .status(201) + .toPact(); + } + + @Test + @PactTestFor + void givenGet_whenSendRequest_shouldReturn200WithProperHeaderAndBody(MockServer mockServer) { + // when + ResponseEntity response = new RestTemplate().getForEntity(mockServer.getUrl() + "/pact", String.class); + + // then + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThat(response.getHeaders().get("Content-Type").contains("application/json")).isTrue(); + assertThat(response.getBody()).contains("condition", "true", "name", "tom"); + + // and + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + String jsonBody = "{\"name\": \"Michael\"}"; + + // when + ResponseEntity postResponse = new RestTemplate().exchange(mockServer.getUrl() + "/pact", HttpMethod.POST, new HttpEntity<>(jsonBody, httpHeaders), String.class); + + // then + assertThat(postResponse.getStatusCode().value()).isEqualTo(201); + } + +} diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactProviderLiveTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactProviderLiveTest.java index 7ac9c1d9ce..044bdbd7fd 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactProviderLiveTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactProviderLiveTest.java @@ -1,34 +1,42 @@ package com.baeldung.pact; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.TestTemplate; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.SpringApplication; import org.springframework.web.context.ConfigurableWebApplicationContext; import com.baeldung.sampleapp.config.MainApplication; -import au.com.dius.pact.provider.junit.PactRunner; import au.com.dius.pact.provider.junit.Provider; import au.com.dius.pact.provider.junit.State; import au.com.dius.pact.provider.junit.loader.PactFolder; -import au.com.dius.pact.provider.junit.target.HttpTarget; -import au.com.dius.pact.provider.junit.target.Target; -import au.com.dius.pact.provider.junit.target.TestTarget; +import au.com.dius.pact.provider.junit5.HttpTestTarget; +import au.com.dius.pact.provider.junit5.PactVerificationContext; +import au.com.dius.pact.provider.junit5.PactVerificationInvocationContextProvider; -@RunWith(PactRunner.class) @Provider("test_provider") @PactFolder("pacts") public class PactProviderLiveTest { - - @TestTarget - public final Target target = new HttpTarget("http", "localhost", 8082, "/spring-rest"); - + private static ConfigurableWebApplicationContext application; - @BeforeClass + @BeforeAll public static void start() { application = (ConfigurableWebApplicationContext) SpringApplication.run(MainApplication.class); } + + @BeforeEach + void before(PactVerificationContext context) { + context.setTarget(new HttpTestTarget("localhost", 8082, "/spring-rest")); + } + + @TestTemplate + @ExtendWith(PactVerificationInvocationContextProvider.class) + void pactVerificationTestTemplate(PactVerificationContext context) { + context.verifyInteraction(); + } @State("test GET") public void toGetState() { diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java index 8d52394dd1..74f7c29d92 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java @@ -6,8 +6,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.fail; import java.io.IOException; import java.net.URI; @@ -16,8 +15,10 @@ import java.util.Set; import com.baeldung.resttemplate.web.handler.RestTemplateResponseErrorHandler; import com.baeldung.resttemplate.web.dto.Foo; -import org.junit.Before; -import org.junit.Test; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -44,7 +45,7 @@ public class RestTemplateBasicLiveTest { private RestTemplate restTemplate; private static final String fooResourceUrl = "http://localhost:" + APPLICATION_PORT + "/spring-rest/foos"; - @Before + @BeforeEach public void beforeTest() { restTemplate = new RestTemplate(); restTemplate.setErrorHandler(new RestTemplateResponseErrorHandler()); @@ -84,7 +85,7 @@ public class RestTemplateBasicLiveTest { @Test public void givenFooService_whenCallHeadForHeaders_thenReceiveAllHeadersForThatResource() { final HttpHeaders httpHeaders = restTemplate.headForHeaders(fooResourceUrl); - assertTrue(httpHeaders.getContentType() + Assertions.assertTrue(httpHeaders.getContentType() .includes(MediaType.APPLICATION_JSON)); } @@ -94,15 +95,15 @@ public class RestTemplateBasicLiveTest { public void givenFooService_whenPostForObject_thenCreatedObjectIsReturned() { final HttpEntity request = new HttpEntity<>(new Foo("bar")); final Foo foo = restTemplate.postForObject(fooResourceUrl, request, Foo.class); - assertThat(foo, notNullValue()); - assertThat(foo.getName(), is("bar")); + Assertions.assertNotNull(foo); + Assertions.assertEquals(foo.getName(), "bar"); } @Test public void givenFooService_whenPostForLocation_thenCreatedLocationIsReturned() { final HttpEntity request = new HttpEntity<>(new Foo("bar")); final URI location = restTemplate.postForLocation(fooResourceUrl, request, Foo.class); - assertThat(location, notNullValue()); + Assertions.assertNotNull(location); } @Test @@ -110,10 +111,10 @@ public class RestTemplateBasicLiveTest { final Foo foo = new Foo("bar"); final ResponseEntity response = restTemplate.postForEntity(fooResourceUrl, foo, Foo.class); - assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.CREATED); final Foo fooResponse = response.getBody(); - assertThat(fooResponse, notNullValue()); - assertThat(fooResponse.getName(), is("bar")); + Assertions.assertNotNull(fooResponse); + Assertions.assertEquals(fooResponse.getName(), "bar"); } @Test @@ -121,7 +122,7 @@ public class RestTemplateBasicLiveTest { final Set optionsForAllow = restTemplate.optionsForAllow(fooResourceUrl); final HttpMethod[] supportedMethods = { HttpMethod.GET, HttpMethod.POST, HttpMethod.HEAD }; - assertTrue(optionsForAllow.containsAll(Arrays.asList(supportedMethods))); + Assertions.assertTrue(optionsForAllow.containsAll(Arrays.asList(supportedMethods))); } // PUT diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateLiveTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateLiveTest.java index 8db31fd0a7..8d3661feed 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateLiveTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateLiveTest.java @@ -1,11 +1,8 @@ package com.baeldung.resttemplate; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -13,13 +10,13 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.web.client.RestTemplate; import com.baeldung.sampleapp.config.RestClientConfig; import com.baeldung.transfer.LoginForm; -@RunWith(SpringJUnit4ClassRunner.class) +@ExtendWith(SpringExtension.class) @ContextConfiguration(classes = RestClientConfig.class) public class RestTemplateLiveTest { @@ -35,9 +32,9 @@ public class RestTemplateLiveTest { ResponseEntity responseEntity = restTemplate.postForEntity("http://httpbin.org/post", requestEntity, String.class); - assertThat(responseEntity.getStatusCode(), is(equalTo(HttpStatus.OK))); - assertThat(responseEntity.getHeaders() - .get("Foo") - .get(0), is(equalTo("bar"))); - } + Assertions.assertEquals(responseEntity.getStatusCode(), HttpStatus.OK); + Assertions.assertEquals(responseEntity.getHeaders() + .get("Foo") + .get(0), "bar"); + } } diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/web/handler/RestTemplateResponseErrorHandlerIntegrationTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/web/handler/RestTemplateResponseErrorHandlerIntegrationTest.java index 688b6e9d56..abc6006b4b 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/web/handler/RestTemplateResponseErrorHandlerIntegrationTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/web/handler/RestTemplateResponseErrorHandlerIntegrationTest.java @@ -1,27 +1,28 @@ package com.baeldung.web.handler; -import com.baeldung.resttemplate.web.exception.NotFoundException; -import com.baeldung.resttemplate.web.handler.RestTemplateResponseErrorHandler; -import com.baeldung.resttemplate.web.model.Bar; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.client.RestClientTest; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.client.ExpectedCount; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.web.client.RestTemplate; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; +import com.baeldung.resttemplate.web.exception.NotFoundException; +import com.baeldung.resttemplate.web.handler.RestTemplateResponseErrorHandler; +import com.baeldung.resttemplate.web.model.Bar; -@RunWith(SpringRunner.class) +@ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { NotFoundException.class, Bar.class }) @RestClientTest public class RestTemplateResponseErrorHandlerIntegrationTest { @@ -29,10 +30,10 @@ public class RestTemplateResponseErrorHandlerIntegrationTest { @Autowired private MockRestServiceServer server; @Autowired private RestTemplateBuilder builder; - @Test(expected = NotFoundException.class) + @Test public void givenRemoteApiCall_when404Error_thenThrowNotFound() { - Assert.assertNotNull(this.builder); - Assert.assertNotNull(this.server); + Assertions.assertNotNull(this.builder); + Assertions.assertNotNull(this.server); RestTemplate restTemplate = this.builder .errorHandler(new RestTemplateResponseErrorHandler()) @@ -42,8 +43,9 @@ public class RestTemplateResponseErrorHandlerIntegrationTest { .expect(ExpectedCount.once(), requestTo("/bars/4242")) .andExpect(method(HttpMethod.GET)) .andRespond(withStatus(HttpStatus.NOT_FOUND)); - - Bar response = restTemplate.getForObject("/bars/4242", Bar.class); - this.server.verify(); + + Assertions.assertThrows(NotFoundException.class, () -> { + Bar response = restTemplate.getForObject("/bars/4242", Bar.class); + }); } } \ No newline at end of file From f89cbffe9da660f8cfb4515662f5d7e52f1833a3 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 29 Mar 2022 21:04:18 +0530 Subject: [PATCH 195/249] Fix for pact test and use Junit5 insead of Hamcrest library --- .../client/TestRestTemplateBasicLiveTest.java | 17 +++++------ .../PactConsumerDrivenContractUnitTest.java | 2 +- .../baeldung/pact/PactProviderLiveTest.java | 2 +- .../RestTemplateBasicLiveTest.java | 30 ++++++++----------- 4 files changed, 22 insertions(+), 29 deletions(-) diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/client/TestRestTemplateBasicLiveTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/client/TestRestTemplateBasicLiveTest.java index 86f188d27a..65c15d882b 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/client/TestRestTemplateBasicLiveTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/client/TestRestTemplateBasicLiveTest.java @@ -1,8 +1,5 @@ package com.baeldung.client; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; - import com.baeldung.resttemplate.web.dto.Foo; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -37,7 +34,7 @@ public class TestRestTemplateBasicLiveTest { public void givenTestRestTemplate_whenSendGetForEntity_thenStatusOk() { TestRestTemplate testRestTemplate = new TestRestTemplate(); ResponseEntity response = testRestTemplate.getForEntity(FOO_RESOURCE_URL + "/1", Foo.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.OK); } @Test @@ -46,7 +43,7 @@ public class TestRestTemplateBasicLiveTest { restTemplateBuilder.configure(restTemplate); TestRestTemplate testRestTemplate = new TestRestTemplate(restTemplateBuilder); ResponseEntity response = testRestTemplate.getForEntity(FOO_RESOURCE_URL + "/1", Foo.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.OK); } @Test @@ -55,7 +52,7 @@ public class TestRestTemplateBasicLiveTest { restTemplateBuilder.build(); TestRestTemplate testRestTemplate = new TestRestTemplate(restTemplateBuilder); ResponseEntity response = testRestTemplate.getForEntity(FOO_RESOURCE_URL + "/1", Foo.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.OK); } @Test @@ -65,7 +62,7 @@ public class TestRestTemplateBasicLiveTest { TestRestTemplate testRestTemplate = new TestRestTemplate(restTemplateBuilder, "user", "passwd"); ResponseEntity response = testRestTemplate.getForEntity(URL_SECURED_BY_AUTHENTICATION, String.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.OK); } @Test @@ -73,7 +70,7 @@ public class TestRestTemplateBasicLiveTest { TestRestTemplate testRestTemplate = new TestRestTemplate("user", "passwd"); ResponseEntity response = testRestTemplate.getForEntity(URL_SECURED_BY_AUTHENTICATION, String.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.OK); } @Test @@ -81,7 +78,7 @@ public class TestRestTemplateBasicLiveTest { TestRestTemplate testRestTemplate = new TestRestTemplate(); ResponseEntity response = testRestTemplate.withBasicAuth("user", "passwd"). getForEntity(URL_SECURED_BY_AUTHENTICATION, String.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.OK); } @Test @@ -90,7 +87,7 @@ public class TestRestTemplateBasicLiveTest { HttpClientOption.ENABLE_COOKIES); ResponseEntity response = testRestTemplate.getForEntity(URL_SECURED_BY_AUTHENTICATION, String.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.OK); } // HEAD diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactConsumerDrivenContractUnitTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactConsumerDrivenContractUnitTest.java index bda7d09c49..6e8703be0d 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactConsumerDrivenContractUnitTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactConsumerDrivenContractUnitTest.java @@ -22,7 +22,7 @@ import au.com.dius.pact.consumer.junit5.PactTestFor; import au.com.dius.pact.model.RequestResponsePact; @ExtendWith(PactConsumerTestExt.class) -@PactTestFor(providerName = "test_provider", hostInterface="localhost", port = "8080") +@PactTestFor(providerName = "test_provider", hostInterface="localhost") public class PactConsumerDrivenContractUnitTest { @Pact(provider="test_provider", consumer = "test_consumer") diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactProviderLiveTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactProviderLiveTest.java index 044bdbd7fd..c59a4ea59f 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactProviderLiveTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactProviderLiveTest.java @@ -17,7 +17,7 @@ import au.com.dius.pact.provider.junit5.PactVerificationContext; import au.com.dius.pact.provider.junit5.PactVerificationInvocationContextProvider; @Provider("test_provider") -@PactFolder("pacts") +@PactFolder("target/pacts") public class PactProviderLiveTest { private static ConfigurableWebApplicationContext application; diff --git a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java index 74f7c29d92..a433ac73c3 100644 --- a/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java +++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java @@ -2,10 +2,6 @@ package com.baeldung.resttemplate; import static org.apache.commons.codec.binary.Base64.encodeBase64; import static com.baeldung.client.Consts.APPLICATION_PORT; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.fail; import java.io.IOException; @@ -58,7 +54,7 @@ public class RestTemplateBasicLiveTest { public void givenResourceUrl_whenSendGetForRequestEntity_thenStatusOk() throws IOException { final ResponseEntity response = restTemplate.getForEntity(fooResourceUrl + "/1", Foo.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.OK); } @Test @@ -69,15 +65,15 @@ public class RestTemplateBasicLiveTest { final ObjectMapper mapper = new XmlMapper(); final JsonNode root = mapper.readTree(response.getBody()); final JsonNode name = root.path("name"); - assertThat(name.asText(), notNullValue()); + Assertions.assertNotNull(name.asText()); } @Test public void givenResourceUrl_whenRetrievingResource_thenCorrect() throws IOException { final Foo foo = restTemplate.getForObject(fooResourceUrl + "/1", Foo.class); - assertThat(foo.getName(), notNullValue()); - assertThat(foo.getId(), is(1L)); + Assertions.assertNotNull(foo.getName()); + Assertions.assertEquals(foo.getId(), 1L); } // HEAD, OPTIONS @@ -147,7 +143,7 @@ public class RestTemplateBasicLiveTest { // Check that Resource was updated final ResponseEntity updateResponse = restTemplate.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class); final Foo foo = updateResponse.getBody(); - assertThat(foo.getName(), is(updatedInstance.getName())); + Assertions.assertEquals(foo.getName(), updatedInstance.getName()); } @Test @@ -157,7 +153,7 @@ public class RestTemplateBasicLiveTest { // Create entity ResponseEntity response = restTemplate.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); - assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.CREATED); // Update entity final Foo updatedInstance = new Foo("newName"); @@ -170,7 +166,7 @@ public class RestTemplateBasicLiveTest { // Check that entity was updated response = restTemplate.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class); final Foo foo = response.getBody(); - assertThat(foo.getName(), is(updatedInstance.getName())); + Assertions.assertEquals(foo.getName(), updatedInstance.getName()); } // PATCH @@ -198,7 +194,7 @@ public class RestTemplateBasicLiveTest { // Check that Resource was updated final ResponseEntity updateResponse = restTemplate.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class); final Foo foo = updateResponse.getBody(); - assertThat(foo.getName(), is(updatedResource.getName())); + Assertions.assertEquals(foo.getName(), updatedResource.getName()); } // DELETE @@ -207,7 +203,7 @@ public class RestTemplateBasicLiveTest { public void givenFooService_whenCallDelete_thenEntityIsRemoved() { final Foo foo = new Foo("remove me"); final ResponseEntity response = restTemplate.postForEntity(fooResourceUrl, foo, Foo.class); - assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.CREATED); final String entityUrl = fooResourceUrl + "/" + response.getBody() .getId(); @@ -216,7 +212,7 @@ public class RestTemplateBasicLiveTest { restTemplate.getForEntity(entityUrl, Foo.class); fail(); } catch (final HttpClientErrorException ex) { - assertThat(ex.getStatusCode(), is(HttpStatus.INTERNAL_SERVER_ERROR)); + Assertions.assertEquals(ex.getStatusCode(), HttpStatus.INTERNAL_SERVER_ERROR); } } @@ -232,10 +228,10 @@ public class RestTemplateBasicLiveTest { ResponseEntity response = restTemplate.postForEntity( fooResourceUrl+"/form", request , String.class); - assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.CREATED); final String fooResponse = response.getBody(); - assertThat(fooResponse, notNullValue()); - assertThat(fooResponse, is("10")); + Assertions.assertNotNull(fooResponse); + Assertions.assertEquals(fooResponse, "10"); } private HttpHeaders prepareBasicAuthHeaders() { From 1df8b146ba9bc6813fccbf1c4758f1bf90a60581 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Tue, 29 Mar 2022 19:04:34 -0600 Subject: [PATCH 196/249] Add sample code for API prefix article (#11959) * Add sample code for API prefix article * Update README.md --- .../controllerprefix/ApiPrefixController.java | 25 ++++++++++++++++ .../ControllerPrefixDemoApp.java | 29 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/controllerprefix/ApiPrefixController.java create mode 100644 spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/controllerprefix/ControllerPrefixDemoApp.java diff --git a/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/controllerprefix/ApiPrefixController.java b/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/controllerprefix/ApiPrefixController.java new file mode 100644 index 0000000000..7577625955 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/controllerprefix/ApiPrefixController.java @@ -0,0 +1,25 @@ +package com.baeldung.controllerprefix; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; + +import java.util.Random; + +@Controller +@RequestMapping("/api") +public class ApiPrefixController { + + @GetMapping + public ModelAndView route(ModelMap model) { + if(new Random().nextBoolean()) { + return new ModelAndView("forward:/endpoint1", model); + } + else { + return new ModelAndView("forward:/endpoint2", model); + } + } +} + diff --git a/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/controllerprefix/ControllerPrefixDemoApp.java b/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/controllerprefix/ControllerPrefixDemoApp.java new file mode 100644 index 0000000000..070142d7ac --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/controllerprefix/ControllerPrefixDemoApp.java @@ -0,0 +1,29 @@ +package com.baeldung.controllerprefix; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@SpringBootApplication +public class ControllerPrefixDemoApp { + public static void main(String[] args) { + SpringApplication.run(ControllerPrefixDemoApp.class, args); + } +} + +@Controller +class EndpointController { + @GetMapping("/endpoint1") + @ResponseBody + public String endpoint1() { + return "Hello from endpoint 1"; + } + + @GetMapping("/endpoint2") + @ResponseBody + public String endpoint2() { + return "Hello from endpoint 2"; + } +} From 81e22da07c45a2dee8eeef6538384885a3e0d5ed Mon Sep 17 00:00:00 2001 From: psevestre Date: Thu, 31 Mar 2022 02:04:02 -0300 Subject: [PATCH 197/249] [BAEL-5259] Spring Security - Map Authorities from JWT (#11990) * [BAEL-4849] Article code * [BAEL-4968] Article code * [BAEL-4968] Article code * [BAEL-4968] Article code * [BAEL-4968] Remove extra comments * [BAEL-5259] simple test case * [BAEL-5259] DSL-based rewrite * [BAEL-5259] Code formatting * [BAEL-5259] Test case naming * WIP: Article code * [BAEL-5259] Tests * [BAEL-5259] Tests --- .../spring-security-oidc/pom.xml | 4 + .../SpringOidcJwtAuthoritiesApplication.java | 23 +++++ .../jwtauthorities/config/AccountToken.java | 23 +++++ .../CustomJwtAuthenticationConverter.java | 36 ++++++++ .../config/JwtMappingProperties.java | 49 ++++++++++ ...MappingJwtGrantedAuthoritiesConverter.java | 84 +++++++++++++++++ .../jwtauthorities/config/SecurityConfig.java | 75 +++++++++++++++ .../oidc/jwtauthorities/domain/Account.java | 26 ++++++ .../service/AccountService.java | 14 +++ .../web/controllers/UserRestController.java | 49 ++++++++++ .../src/main/resources/application.yml | 1 - .../resources/jwtauthorities-application.yml | 15 +++ ...tomJwtAuthenticationConverterUnitTest.java | 59 ++++++++++++ ...wtGrantedAuthoritiesConverterUnitTest.java | 91 +++++++++++++++++++ 14 files changed, 548 insertions(+), 1 deletion(-) create mode 100644 spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/SpringOidcJwtAuthoritiesApplication.java create mode 100644 spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/AccountToken.java create mode 100644 spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/CustomJwtAuthenticationConverter.java create mode 100644 spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/JwtMappingProperties.java create mode 100644 spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/MappingJwtGrantedAuthoritiesConverter.java create mode 100644 spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/SecurityConfig.java create mode 100644 spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/domain/Account.java create mode 100644 spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/service/AccountService.java create mode 100644 spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/web/controllers/UserRestController.java create mode 100644 spring-security-modules/spring-security-oidc/src/main/resources/jwtauthorities-application.yml create mode 100644 spring-security-modules/spring-security-oidc/src/test/java/com/baeldung/openid/oidc/jwtauthorities/config/CustomJwtAuthenticationConverterUnitTest.java create mode 100644 spring-security-modules/spring-security-oidc/src/test/java/com/baeldung/openid/oidc/jwtauthorities/config/MappingJwtGrantedAuthoritiesConverterUnitTest.java diff --git a/spring-security-modules/spring-security-oidc/pom.xml b/spring-security-modules/spring-security-oidc/pom.xml index 2a413b1d27..70031b7396 100644 --- a/spring-security-modules/spring-security-oidc/pom.xml +++ b/spring-security-modules/spring-security-oidc/pom.xml @@ -24,6 +24,10 @@ org.springframework.boot spring-boot-starter-oauth2-client + + org.springframework.boot + spring-boot-starter-oauth2-resource-server + \ No newline at end of file diff --git a/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/SpringOidcJwtAuthoritiesApplication.java b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/SpringOidcJwtAuthoritiesApplication.java new file mode 100644 index 0000000000..4fa58f3578 --- /dev/null +++ b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/SpringOidcJwtAuthoritiesApplication.java @@ -0,0 +1,23 @@ +/** + * + */ +package com.baeldung.openid.oidc.jwtauthorities; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; + +import com.baeldung.openid.oidc.discovery.SpringOidcDiscoveryApplication; +import com.baeldung.openid.oidc.utils.YamlLoaderInitializer; + +@SpringBootApplication +public class SpringOidcJwtAuthoritiesApplication { + + public static void main(String[] args) { + SpringApplication application = new SpringApplication(SpringOidcJwtAuthoritiesApplication.class); + ApplicationContextInitializer yamlInitializer = new YamlLoaderInitializer("jwtauthorities-application.yml"); + application.addInitializers(yamlInitializer); + application.run(args); + } +} diff --git a/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/AccountToken.java b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/AccountToken.java new file mode 100644 index 0000000000..a48a0889aa --- /dev/null +++ b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/AccountToken.java @@ -0,0 +1,23 @@ +package com.baeldung.openid.oidc.jwtauthorities.config; + +import java.util.Collection; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; + +import com.baeldung.openid.oidc.jwtauthorities.domain.Account; + +public class AccountToken extends JwtAuthenticationToken { + private static final long serialVersionUID = 1L; + private final Account account; + + public AccountToken(Jwt jwt, Collection authorities, String name, Account account) { + super(jwt, authorities, name); + this.account = account; + } + + public Account getAccount() { + return account; + } +} diff --git a/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/CustomJwtAuthenticationConverter.java b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/CustomJwtAuthenticationConverter.java new file mode 100644 index 0000000000..57b9809bc6 --- /dev/null +++ b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/CustomJwtAuthenticationConverter.java @@ -0,0 +1,36 @@ +package com.baeldung.openid.oidc.jwtauthorities.config; + +import java.util.Collection; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.jwt.JwtClaimNames; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; + +import com.baeldung.openid.oidc.jwtauthorities.domain.Account; +import com.baeldung.openid.oidc.jwtauthorities.service.AccountService; + +public class CustomJwtAuthenticationConverter implements Converter { + + private final Converter> jwtGrantedAuthoritiesConverter; + private final String principalClaimName; + private AccountService accountService; + + public CustomJwtAuthenticationConverter(AccountService accountService, Converter> jwtGrantedAuthoritiesConverter, String principalClaimName) { + this.accountService = accountService; + this.jwtGrantedAuthoritiesConverter = jwtGrantedAuthoritiesConverter; + this.principalClaimName = principalClaimName != null ? principalClaimName : JwtClaimNames.SUB; + } + + @Override + public AbstractAuthenticationToken convert(Jwt source) { + + Collection authorities = jwtGrantedAuthoritiesConverter.convert(source); + String principalClaimValue = source.getClaimAsString(this.principalClaimName); + Account acc = accountService.findAccountByPrincipal(principalClaimValue); + return new AccountToken(source, authorities, principalClaimValue, acc); + } + +} diff --git a/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/JwtMappingProperties.java b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/JwtMappingProperties.java new file mode 100644 index 0000000000..71a7004300 --- /dev/null +++ b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/JwtMappingProperties.java @@ -0,0 +1,49 @@ +package com.baeldung.openid.oidc.jwtauthorities.config; + +import java.util.Map; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "baeldung.jwt.mapping") +public class JwtMappingProperties { + + private String authoritiesPrefix; + private String authoritiesClaimName; + private String principalClaimName; + private Map scopes; + + public String getAuthoritiesClaimName() { + return authoritiesClaimName; + } + + public void setAuthoritiesClaimName(String authoritiesClaimName) { + this.authoritiesClaimName = authoritiesClaimName; + } + + public String getAuthoritiesPrefix() { + return authoritiesPrefix; + } + + public void setAuthoritiesPrefix(String authoritiesPrefix) { + this.authoritiesPrefix = authoritiesPrefix; + } + + + public String getPrincipalClaimName() { + return principalClaimName; + } + + public void setPrincipalClaimName(String principalClaimName) { + this.principalClaimName = principalClaimName; + } + + public Map getScopes() { + return scopes; + } + + public void setScopes(Map scopes) { + this.scopes = scopes; + } + + +} diff --git a/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/MappingJwtGrantedAuthoritiesConverter.java b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/MappingJwtGrantedAuthoritiesConverter.java new file mode 100644 index 0000000000..0b47082294 --- /dev/null +++ b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/MappingJwtGrantedAuthoritiesConverter.java @@ -0,0 +1,84 @@ +package com.baeldung.openid.oidc.jwtauthorities.config; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.jwt.Jwt; + +public class MappingJwtGrantedAuthoritiesConverter implements Converter> { + + private static final Collection WELL_KNOWN_AUTHORITIES_CLAIM_NAMES = Arrays.asList("scope", "scp"); + + private final Map scopes; + private String authoritiesClaimName = null; + private String authorityPrefix = "SCOPE_"; + + MappingJwtGrantedAuthoritiesConverter(Map scopes) { + this.scopes = scopes == null ? Collections.emptyMap(): scopes; + } + + public void setAuthoritiesClaimName(String authoritiesClaimName) { + this.authoritiesClaimName = authoritiesClaimName; + } + + public void setAuthorityPrefix(String authorityPrefix) { + this.authorityPrefix = authorityPrefix; + } + + @Override + public Collection convert(Jwt jwt) { + + Collection tokenScopes = parseScopesClaim(jwt); + if ( tokenScopes.isEmpty()) { + return Collections.emptyList(); + } + + return tokenScopes.stream() + .map(s -> scopes.getOrDefault(s, s)) + .map(s -> this.authorityPrefix + s) + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toCollection(HashSet::new)); + } + + protected Collection parseScopesClaim(Jwt jwt) { + + String scopeClaim; + + if ( this.authoritiesClaimName == null ) { + scopeClaim = WELL_KNOWN_AUTHORITIES_CLAIM_NAMES.stream() + .filter( claim -> jwt.hasClaim(claim)) + .findFirst() + .orElse(null); + + if ( scopeClaim == null ) { + return Collections.emptyList(); + } + } + else { + scopeClaim = this.authoritiesClaimName; + } + + Object v = jwt.getClaim(scopeClaim); + if ( v == null ) { + return Collections.emptyList(); + } + + if ( v instanceof String) { + return Arrays.asList(v.toString().split(" ")); + } + else if ( v instanceof Collection ) { + return ((Collection)v).stream() + .map( s -> s.toString()) + .collect(Collectors.toCollection(HashSet::new)); + } + return Collections.emptyList(); + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/SecurityConfig.java b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/SecurityConfig.java new file mode 100644 index 0000000000..7495831b54 --- /dev/null +++ b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/config/SecurityConfig.java @@ -0,0 +1,75 @@ +package com.baeldung.openid.oidc.jwtauthorities.config; + +import java.util.Collection; +import java.util.List; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.converter.Converter; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; +import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.util.StringUtils; + +import com.baeldung.openid.oidc.jwtauthorities.service.AccountService; + +@Configuration +@EnableConfigurationProperties(JwtMappingProperties.class) +@EnableMethodSecurity +public class SecurityConfig { + + private final JwtMappingProperties mappingProps; + private final AccountService accountService; + + public SecurityConfig(JwtMappingProperties mappingProps, AccountService accountService) { + this.mappingProps = mappingProps; + this.accountService = accountService; + } + + @Bean + public String jwtGrantedAuthoritiesPrefix() { + return mappingProps.getAuthoritiesPrefix(); + } + + @Bean + public Converter> jwtGrantedAuthoritiesConverter() { + MappingJwtGrantedAuthoritiesConverter converter = new MappingJwtGrantedAuthoritiesConverter(mappingProps.getScopes()); + + if (StringUtils.hasText(mappingProps.getAuthoritiesPrefix())) { + converter.setAuthorityPrefix(mappingProps.getAuthoritiesPrefix() + .trim()); + } + + if (StringUtils.hasText(mappingProps.getAuthoritiesClaimName())) { + converter.setAuthoritiesClaimName(mappingProps.getAuthoritiesClaimName()); + } + return converter; + } + + @Bean + public Converter customJwtAuthenticationConverter(AccountService accountService) { + return new CustomJwtAuthenticationConverter( + accountService, + jwtGrantedAuthoritiesConverter(), + mappingProps.getPrincipalClaimName()); + } + + @Bean + SecurityFilterChain customJwtSecurityChain(HttpSecurity http) throws Exception { + // @formatter:off + return http.oauth2ResourceServer(oauth2 -> { + oauth2.jwt() + .jwtAuthenticationConverter(customJwtAuthenticationConverter(accountService)); + }) + .build(); + // @formatter:on + } + +} diff --git a/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/domain/Account.java b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/domain/Account.java new file mode 100644 index 0000000000..f0227c8628 --- /dev/null +++ b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/domain/Account.java @@ -0,0 +1,26 @@ +package com.baeldung.openid.oidc.jwtauthorities.domain; + +public class Account { + + private final Long id; + private final String branch; + private final String accountNumber; + + public Account(Long id, String branch, String accountNumber) { + this.id = id; + this.branch = branch; + this.accountNumber = accountNumber; + } + + public Long getId() { + return id; + } + + public String getBranch() { + return branch; + } + + public String getAccountNumber() { + return accountNumber; + } +} diff --git a/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/service/AccountService.java b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/service/AccountService.java new file mode 100644 index 0000000000..e10a26209c --- /dev/null +++ b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/service/AccountService.java @@ -0,0 +1,14 @@ +package com.baeldung.openid.oidc.jwtauthorities.service; + +import org.springframework.stereotype.Service; + +import com.baeldung.openid.oidc.jwtauthorities.domain.Account; + +@Service +public class AccountService { + + public Account findAccountByPrincipal(String principal) { + // NOTE: real-world code would typically perform some sort of DB lookup + return new Account(1l, "0001", "101888444-0"); + } +} diff --git a/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/web/controllers/UserRestController.java b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/web/controllers/UserRestController.java new file mode 100644 index 0000000000..a3b4d1d5cd --- /dev/null +++ b/spring-security-modules/spring-security-oidc/src/main/java/com/baeldung/openid/oidc/jwtauthorities/web/controllers/UserRestController.java @@ -0,0 +1,49 @@ +package com.baeldung.openid.oidc.jwtauthorities.web.controllers; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.openid.oidc.jwtauthorities.config.AccountToken; +import com.baeldung.openid.oidc.jwtauthorities.domain.Account; + +@RestController +@RequestMapping("/user") +public class UserRestController { + + @GetMapping("/authorities") + @PreAuthorize("hasAuthority(@jwtGrantedAuthoritiesPrefix + 'profile.read')") + public Map getPrincipalInfo( JwtAuthenticationToken principal) { + + Collection authorities = principal.getAuthorities() + .stream() + .map(GrantedAuthority::getAuthority) + .collect(Collectors.toList()); + + Map info = new HashMap<>(); + info.put("name", principal.getName()); + info.put("authorities", authorities); + info.put("tokenAttributes", principal.getTokenAttributes()); + + if ( principal instanceof AccountToken ) { + info.put( "account", ((AccountToken)principal).getAccount()); + } + + return info; + } + + @GetMapping("/account/{accountNumber}") + @PreAuthorize("authentication.account.accountNumber == #accountNumber") + public Account getAccountById(@PathVariable("accountNumber") String accountNumber, AccountToken authentication) { + return authentication.getAccount(); + } +} diff --git a/spring-security-modules/spring-security-oidc/src/main/resources/application.yml b/spring-security-modules/spring-security-oidc/src/main/resources/application.yml index f303fcecd1..bb23047dfe 100644 --- a/spring-security-modules/spring-security-oidc/src/main/resources/application.yml +++ b/spring-security-modules/spring-security-oidc/src/main/resources/application.yml @@ -4,4 +4,3 @@ server: logging: level: org.springframework.web.client.RestTemplate: DEBUG - \ No newline at end of file diff --git a/spring-security-modules/spring-security-oidc/src/main/resources/jwtauthorities-application.yml b/spring-security-modules/spring-security-oidc/src/main/resources/jwtauthorities-application.yml new file mode 100644 index 0000000000..384b406465 --- /dev/null +++ b/spring-security-modules/spring-security-oidc/src/main/resources/jwtauthorities-application.yml @@ -0,0 +1,15 @@ +spring: + security: + oauth2: + resourceserver: + jwt: +# issuer-uri: https://sts.windows.net/2e9fde3a-38ec-44f9-8bcd-c184dc1e8033/ + issuer-uri: http://localhost:8083/auth/realms/baeldung +baeldung: + jwt: + mapping: + authorities-prefix: "MY_SCOPE_" + principal-claim-name: preferred_username + scopes: + profile: profile.read + "profile_read": profile.read diff --git a/spring-security-modules/spring-security-oidc/src/test/java/com/baeldung/openid/oidc/jwtauthorities/config/CustomJwtAuthenticationConverterUnitTest.java b/spring-security-modules/spring-security-oidc/src/test/java/com/baeldung/openid/oidc/jwtauthorities/config/CustomJwtAuthenticationConverterUnitTest.java new file mode 100644 index 0000000000..09f1efa228 --- /dev/null +++ b/spring-security-modules/spring-security-oidc/src/test/java/com/baeldung/openid/oidc/jwtauthorities/config/CustomJwtAuthenticationConverterUnitTest.java @@ -0,0 +1,59 @@ +package com.baeldung.openid.oidc.jwtauthorities.config; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; +import org.springframework.security.oauth2.jwt.Jwt; + +import com.baeldung.openid.oidc.jwtauthorities.service.AccountService; + +class CustomJwtAuthenticationConverterUnitTest { + + @Test + void testGivenCustomJwtAuthenticationConverter_whenConvert_thenReturnAccountToken() { + + AccountService accountService = new AccountService(); + MappingJwtGrantedAuthoritiesConverter authoritiesConverter = new MappingJwtGrantedAuthoritiesConverter(new HashMap<>()); + + CustomJwtAuthenticationConverter converter = new CustomJwtAuthenticationConverter( + accountService, authoritiesConverter, null); + + Jwt jwt = Jwt.withTokenValue("NOTUSED") + .header("typ", "JWT") + .subject("user") + .claim("scp", "openid email profile") + .build(); + + Object auth = converter.convert(jwt); + assertTrue(auth instanceof AccountToken, "Authentication must be instance of AccountToken"); + AccountToken token = AccountToken.class.cast(auth); + + assertEquals("user", token.getName()); + } + + @Test + void testGivenCustomPrincipalClaimName_whenConvert_thenReturnAccountToken() { + + AccountService accountService = new AccountService(); + MappingJwtGrantedAuthoritiesConverter authoritiesConverter = new MappingJwtGrantedAuthoritiesConverter(new HashMap<>()); + + CustomJwtAuthenticationConverter converter = new CustomJwtAuthenticationConverter( + accountService, authoritiesConverter, "preferred_username"); + + Jwt jwt = Jwt.withTokenValue("NOTUSED") + .header("typ", "JWT") + .claim("preferred_username", "user") + .claim("scp", "openid email profile") + .build(); + + Object auth = converter.convert(jwt); + assertTrue(auth instanceof AccountToken, "Authentication must be instance of AccountToken"); + AccountToken token = AccountToken.class.cast(auth); + + assertEquals("user", token.getName()); + } + +} diff --git a/spring-security-modules/spring-security-oidc/src/test/java/com/baeldung/openid/oidc/jwtauthorities/config/MappingJwtGrantedAuthoritiesConverterUnitTest.java b/spring-security-modules/spring-security-oidc/src/test/java/com/baeldung/openid/oidc/jwtauthorities/config/MappingJwtGrantedAuthoritiesConverterUnitTest.java new file mode 100644 index 0000000000..90b943ce53 --- /dev/null +++ b/spring-security-modules/spring-security-oidc/src/test/java/com/baeldung/openid/oidc/jwtauthorities/config/MappingJwtGrantedAuthoritiesConverterUnitTest.java @@ -0,0 +1,91 @@ +package com.baeldung.openid.oidc.jwtauthorities.config; + +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.jwt.Jwt; + +class MappingJwtGrantedAuthoritiesConverterUnitTest { + + @Test + void testGivenConverterWithScopeMap_whenConvert_thenResultHasMappedAuthorities() { + Jwt jwt = Jwt.withTokenValue("NOTUSED") + .header("typ", "JWT") + .subject("user") + .claim("scp", "openid email profile") + .build(); + + Map scopeMap = new HashMap<>(); + scopeMap.put("profile", "profile.read"); + MappingJwtGrantedAuthoritiesConverter converter = new MappingJwtGrantedAuthoritiesConverter(scopeMap); + Collection result = converter.convert(jwt); + + assertTrue("Result must contain the authoriry 'SCOPE_profile.read'", + result.contains(new SimpleGrantedAuthority("SCOPE_profile.read"))); + } + + @Test + void testGivenConverterWithCustomScopeClaim_whenConvert_thenResultHasAuthorities() { + Jwt jwt = Jwt.withTokenValue("NOTUSED") + .header("typ", "JWT") + .subject("user") + .claim("myscope_claim", "openid email profile") + .build(); + + Map scopeMap = new HashMap<>(); + MappingJwtGrantedAuthoritiesConverter converter = new MappingJwtGrantedAuthoritiesConverter(scopeMap); + converter.setAuthoritiesClaimName("myscope_claim"); + Collection result = converter.convert(jwt); + + assertTrue("Result must contain the authoriry 'SCOPE_profile'", + result.contains(new SimpleGrantedAuthority("SCOPE_profile"))); + } + + @Test + void testGivenTokenWithNonMappedScope_whenConvert_thenResultHasOriginalScope() { + Jwt jwt = Jwt.withTokenValue("NOTUSED") + .header("typ", "JWT") + .subject("user") + .claim("scp", "openid email profile custom") + .build(); + + Map scopeMap = new HashMap<>(); + scopeMap.put("profile", "profile.read"); + MappingJwtGrantedAuthoritiesConverter converter = new MappingJwtGrantedAuthoritiesConverter(scopeMap); + Collection result = converter.convert(jwt); + + assertTrue("Result must contain the authority SCOPE_custom", + result.contains(new SimpleGrantedAuthority("SCOPE_custom"))); + } + + + @Test + void testGivenConverterWithCustomPrefix_whenConvert_thenAllAuthoritiesMustHaveTheCustomPrefix() { + Jwt jwt = Jwt.withTokenValue("NOTUSED") + .header("typ", "JWT") + .subject("user") + .claim("scp", "openid email profile custom") + .build(); + + Map scopeMap = new HashMap<>(); + scopeMap.put("profile", "profile.read"); + MappingJwtGrantedAuthoritiesConverter converter = new MappingJwtGrantedAuthoritiesConverter(scopeMap); + converter.setAuthorityPrefix("MY_SCOPE"); + Collection result = converter.convert(jwt); + + long count = result.stream() + .map(GrantedAuthority::getAuthority) + .filter(s -> !s.startsWith("MY_SCOPE")) + .count(); + + assertTrue("All authorities names must start with custom prefix", count == 0 ); + } + +} From 3a271415eb0d0387e3b84eaac879a567abe74689 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:39:46 +0800 Subject: [PATCH 198/249] Update README.md --- persistence-modules/core-java-persistence-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/core-java-persistence-2/README.md b/persistence-modules/core-java-persistence-2/README.md index f245392cb3..6622f9733f 100644 --- a/persistence-modules/core-java-persistence-2/README.md +++ b/persistence-modules/core-java-persistence-2/README.md @@ -6,3 +6,4 @@ - [Inserting Null Into an Integer Column Using JDBC](https://www.baeldung.com/jdbc-insert-null-into-integer-column) - [A Guide to Auto-Commit in JDBC](https://www.baeldung.com/java-jdbc-auto-commit) - [JDBC Connection Status](https://www.baeldung.com/jdbc-connection-status) +- [Get the Number of Rows in a ResultSet](https://www.baeldung.com/java-resultset-number-of-rows) From 5b7362578ed5f416d155bebf1ef8891eed4a531b Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:41:58 +0800 Subject: [PATCH 199/249] Update README.md --- persistence-modules/spring-boot-persistence-mongodb/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-boot-persistence-mongodb/README.md b/persistence-modules/spring-boot-persistence-mongodb/README.md index f5eaeff89c..485ff92905 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/README.md +++ b/persistence-modules/spring-boot-persistence-mongodb/README.md @@ -6,4 +6,5 @@ - [GridFS in Spring Data MongoDB](http://www.baeldung.com/spring-data-mongodb-gridfs) - [ZonedDateTime with Spring Data MongoDB](https://www.baeldung.com/spring-data-mongodb-zoneddatetime) - [A Guide to @DBRef in MongoDB](https://www.baeldung.com/spring-mongodb-dbref-annotation) +- [Import Data to MongoDB From JSON File Using Java](https://www.baeldung.com/java-import-json-mongodb) From f5be3c8fed705e3ad44cf7014972345707bb85cb Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:44:26 +0800 Subject: [PATCH 200/249] Update README.md --- core-java-modules/core-java-date-operations-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-date-operations-2/README.md b/core-java-modules/core-java-date-operations-2/README.md index 557e4c3517..056c91e60d 100644 --- a/core-java-modules/core-java-date-operations-2/README.md +++ b/core-java-modules/core-java-date-operations-2/README.md @@ -11,4 +11,5 @@ This module contains articles about date operations in Java. - [How to determine day of week by passing specific date in Java?](https://www.baeldung.com/java-get-day-of-week) - [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year) - [Getting the Week Number From Any Date](https://www.baeldung.com/java-get-week-number) +- [Subtract Days from a Date in Java](https://www.baeldung.com/java-subtract-days-from-date) - [[<-- Prev]](/core-java-modules/core-java-date-operations-1) From 4affc4906cf2f0b9655c399098d31d435e2a122c Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:46:23 +0800 Subject: [PATCH 201/249] Update README.md --- core-java-modules/core-java-lang-syntax-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-lang-syntax-2/README.md b/core-java-modules/core-java-lang-syntax-2/README.md index 940629c1dc..0e7b9985cc 100644 --- a/core-java-modules/core-java-lang-syntax-2/README.md +++ b/core-java-modules/core-java-lang-syntax-2/README.md @@ -13,4 +13,5 @@ This module contains articles about Java syntax - [Introduction to Basic Syntax in Java](https://www.baeldung.com/java-syntax) - [Java ‘protected’ Access Modifier](https://www.baeldung.com/java-protected-access-modifier) - [Using the Not Operator in If Conditions in Java](https://www.baeldung.com/java-using-not-in-if-conditions) +- [The for-each Loop in Java](https://www.baeldung.com/java-for-each-loop) - [[<-- Prev]](/core-java-modules/core-java-lang-syntax) From 0f2f185443027ae21406951c15caf8ad10877004 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:48:05 +0800 Subject: [PATCH 202/249] Update README.md --- core-java-modules/core-java-io-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-io-4/README.md b/core-java-modules/core-java-io-4/README.md index 39b820b3ba..65a46eeed3 100644 --- a/core-java-modules/core-java-io-4/README.md +++ b/core-java-modules/core-java-io-4/README.md @@ -8,4 +8,5 @@ This module contains articles about core Java input and output (IO) - [Simulate touch Command in Java](https://www.baeldung.com/java-simulate-touch-command) - [SequenceInputStream Class in Java](https://www.baeldung.com/java-sequenceinputstream) - [Read a File Into a Map in Java](https://www.baeldung.com/java-read-file-into-map) +- [Read User Input Until a Condition is Met](https://www.baeldung.com/java-read-input-until-condition) - [[<-- Prev]](/core-java-modules/core-java-io-3) From 871d806242cf1a6b5e153fb1dcb55d0a605331f9 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:51:11 +0800 Subject: [PATCH 203/249] Update README.md --- persistence-modules/spring-boot-persistence-mongodb/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/spring-boot-persistence-mongodb/README.md b/persistence-modules/spring-boot-persistence-mongodb/README.md index 485ff92905..91dd8718e1 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/README.md +++ b/persistence-modules/spring-boot-persistence-mongodb/README.md @@ -7,4 +7,4 @@ - [ZonedDateTime with Spring Data MongoDB](https://www.baeldung.com/spring-data-mongodb-zoneddatetime) - [A Guide to @DBRef in MongoDB](https://www.baeldung.com/spring-mongodb-dbref-annotation) - [Import Data to MongoDB From JSON File Using Java](https://www.baeldung.com/java-import-json-mongodb) - +- [Logging MongoDB Queries with Spring Boot](https://www.baeldung.com/spring-boot-mongodb-logging) From fd2b2c41a57ab3bb0c281c576a042f3d9a8424b2 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:52:47 +0800 Subject: [PATCH 204/249] Update README.md --- core-java-modules/core-java-collections-set/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-set/README.md b/core-java-modules/core-java-collections-set/README.md index b97cd3216f..bec98538ec 100644 --- a/core-java-modules/core-java-collections-set/README.md +++ b/core-java-modules/core-java-collections-set/README.md @@ -12,3 +12,4 @@ This module contains articles about the Java Set collection - [Set Operations in Java](https://www.baeldung.com/java-set-operations) - [Copying Sets in Java](https://www.baeldung.com/java-copy-sets) - [Immutable Set in Java](https://www.baeldung.com/java-immutable-set) +- [Find the Difference Between Two Sets](https://www.baeldung.com/java-difference-between-sets) From 614002bebf9b5ef9581a35329238db43f00275e9 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:54:28 +0800 Subject: [PATCH 205/249] Update README.md --- persistence-modules/java-mongodb-2/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/java-mongodb-2/README.md b/persistence-modules/java-mongodb-2/README.md index 1b49e11499..7b08569d9d 100644 --- a/persistence-modules/java-mongodb-2/README.md +++ b/persistence-modules/java-mongodb-2/README.md @@ -2,4 +2,4 @@ This module contains articles about MongoDB in Java. - +- [Guide to Upsert in MongoDB](https://www.baeldung.com/mongodb-upsert) From 202c6e3fad9ef88daf8e277576ee74a8c00e1f9b Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:55:31 +0800 Subject: [PATCH 206/249] Update README.md --- persistence-modules/java-mongodb-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-mongodb-2/README.md b/persistence-modules/java-mongodb-2/README.md index 7b08569d9d..6e39bddfbe 100644 --- a/persistence-modules/java-mongodb-2/README.md +++ b/persistence-modules/java-mongodb-2/README.md @@ -3,3 +3,4 @@ This module contains articles about MongoDB in Java. - [Guide to Upsert in MongoDB](https://www.baeldung.com/mongodb-upsert) +- [Bulk Update of Documents in MongoDB](https://www.baeldung.com/mongodb-bulk-update-documents) From 0a2f8431b33e7289b4a142721ecf84a8b782d885 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:58:12 +0800 Subject: [PATCH 207/249] Update README.md --- spring-boot-modules/spring-boot-libraries-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-libraries-2/README.md b/spring-boot-modules/spring-boot-libraries-2/README.md index cf07279258..1cf21d8b1c 100644 --- a/spring-boot-modules/spring-boot-libraries-2/README.md +++ b/spring-boot-modules/spring-boot-libraries-2/README.md @@ -7,4 +7,5 @@ This module contains articles about various Spring Boot libraries - [Background Jobs in Spring with JobRunr](https://www.baeldung.com/java-jobrunr-spring) - [Open API Server Implementation Using OpenAPI Generator](https://www.baeldung.com/java-openapi-generator-server) - [An Introduction to Kong](https://www.baeldung.com/kong) +- [Getting Started With GraphQL SPQR and Spring Boot](https://www.baeldung.com/spring-boot-graphql-spqr) More articles: [[prev -->]](/spring-boot-modules/spring-boot-libraries) From b558c9fca48933305d88bc53bf2a96def53f7300 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:59:04 +0800 Subject: [PATCH 208/249] Update README.md --- spring-boot-modules/spring-boot-libraries-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-libraries-2/README.md b/spring-boot-modules/spring-boot-libraries-2/README.md index 1cf21d8b1c..712558119c 100644 --- a/spring-boot-modules/spring-boot-libraries-2/README.md +++ b/spring-boot-modules/spring-boot-libraries-2/README.md @@ -8,4 +8,5 @@ This module contains articles about various Spring Boot libraries - [Open API Server Implementation Using OpenAPI Generator](https://www.baeldung.com/java-openapi-generator-server) - [An Introduction to Kong](https://www.baeldung.com/kong) - [Getting Started With GraphQL SPQR and Spring Boot](https://www.baeldung.com/spring-boot-graphql-spqr) + More articles: [[prev -->]](/spring-boot-modules/spring-boot-libraries) From 5550a58a43b62b25bafb7060464a80e9b0351514 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:59:24 +0800 Subject: [PATCH 209/249] Update README.md --- spring-boot-modules/spring-boot-libraries-2/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-modules/spring-boot-libraries-2/README.md b/spring-boot-modules/spring-boot-libraries-2/README.md index 712558119c..96f82cdf59 100644 --- a/spring-boot-modules/spring-boot-libraries-2/README.md +++ b/spring-boot-modules/spring-boot-libraries-2/README.md @@ -9,4 +9,4 @@ This module contains articles about various Spring Boot libraries - [An Introduction to Kong](https://www.baeldung.com/kong) - [Getting Started With GraphQL SPQR and Spring Boot](https://www.baeldung.com/spring-boot-graphql-spqr) - More articles: [[prev -->]](/spring-boot-modules/spring-boot-libraries) +More articles: [[prev -->]](/spring-boot-modules/spring-boot-libraries) From 5ec7677a21c816c99969f5679f093fe0fa3548a6 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 14:01:49 +0800 Subject: [PATCH 210/249] Create README.md --- graphql/graphql-spqr/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 graphql/graphql-spqr/README.md diff --git a/graphql/graphql-spqr/README.md b/graphql/graphql-spqr/README.md new file mode 100644 index 0000000000..7089a7a9f1 --- /dev/null +++ b/graphql/graphql-spqr/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Getting Started With GraphQL SPQR and Spring Boot](https://www.baeldung.com/spring-boot-graphql-spqr) From 90448ef4adff205c4a460edca571a3a431216b80 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 31 Mar 2022 14:04:45 +0800 Subject: [PATCH 211/249] Create README.md --- .../src/main/java/com/baeldung/controllerprefix/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/controllerprefix/README.md diff --git a/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/controllerprefix/README.md b/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/controllerprefix/README.md new file mode 100644 index 0000000000..9faac4362a --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/controllerprefix/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Add Prefix to All Spring Boot Controllers](https://www.baeldung.com/spring-boot-controllers-add-prefix) From 6b89f0d2f298ba3cfcea1429893687fc7771fde0 Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Thu, 31 Mar 2022 11:17:24 +0200 Subject: [PATCH 212/249] JAVA-10238-2: Run jobrunr dashboard on random port --- .../src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/resources/application.properties b/spring-boot-modules/spring-boot-libraries-2/src/main/resources/application.properties index bb2a31f1d9..0fea0163f1 100644 --- a/spring-boot-modules/spring-boot-libraries-2/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/resources/application.properties @@ -1,2 +1,3 @@ org.jobrunr.background-job-server.enabled=true org.jobrunr.dashboard.enabled=true +org.jobrunr.dashboard.port=0 From b1c60e90936ec70dee3d2d85cf2e66873dfce4fa Mon Sep 17 00:00:00 2001 From: Azhwani <13301425+azhwani@users.noreply.github.com> Date: Fri, 1 Apr 2022 03:04:10 +0200 Subject: [PATCH 213/249] BAEL-5386: Format Instant to String in Java (#11970) * first commit * remove extra spaces * add the requested changes --- .../formatinstant/FormatInstantUnitTest.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/formatinstant/FormatInstantUnitTest.java diff --git a/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/formatinstant/FormatInstantUnitTest.java b/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/formatinstant/FormatInstantUnitTest.java new file mode 100644 index 0000000000..ef273e4b81 --- /dev/null +++ b/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/formatinstant/FormatInstantUnitTest.java @@ -0,0 +1,54 @@ +package com.baeldung.formatinstant; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.time.temporal.UnsupportedTemporalTypeException; + +import org.joda.time.format.DateTimeFormat; +import org.junit.Test; + +public class FormatInstantUnitTest { + + private static final String PATTERN_FORMAT = "dd.MM.yyyy"; + + @Test + public void givenInstant_whenUsingDateTimeFormatter_thenFormat() { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN_FORMAT) + .withZone(ZoneId.systemDefault()); + + Instant instant = Instant.parse("2022-02-15T18:35:24.00Z"); + String formattedInstant = formatter.format(instant); + + assertThat(formattedInstant).isEqualTo("15.02.2022"); + } + + @Test(expected = UnsupportedTemporalTypeException.class) + public void givenInstant_whenNotSpecifyingTimeZone_thenThrowException() { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN_FORMAT); + + Instant instant = Instant.now(); + formatter.format(instant); + } + + @Test + public void givenInstant_whenUsingToString_thenFormat() { + Instant instant = Instant.ofEpochMilli(1641828224000L); + String formattedInstant = instant.toString(); + + assertThat(formattedInstant).isEqualTo("2022-01-10T15:23:44Z"); + } + + @Test + public void givenInstant_whenUsingJodaTime_thenFormat() { + org.joda.time.Instant instant = new org.joda.time.Instant("2022-03-20T10:11:12"); + + String formattedInstant = DateTimeFormat.forPattern(PATTERN_FORMAT) + .print(instant); + + assertThat(formattedInstant).isEqualTo("20.03.2022"); + } + +} From b33baa051263de3944a2dedaeca337cb1cff8d40 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Fri, 1 Apr 2022 13:17:58 +0100 Subject: [PATCH 214/249] [JAVA-8147] Update and cleanup code for debugging reactive streams --- .../ChronJobs.java => cronjobs/CronJobs.java} | 130 +++++++-------- .../debugging/consumer/model/Foo.java | 20 ++- .../debugging/consumer/model/FooDto.java | 7 +- .../consumer/service/FooNameHelper.java | 50 +++--- .../consumer/service/FooQuantityHelper.java | 28 ++-- .../consumer/service/FooReporter.java | 20 +-- .../consumer/service/FooService.java | 151 +++++++++--------- .../server/handlers/ServerHandler.java | 29 ++-- .../ConsumerFooServiceIntegrationTest.java | 20 +-- .../consumer/ConsumerFooServiceLiveTest.java | 3 - .../consumer/utils/ListAppender.java | 8 +- 11 files changed, 227 insertions(+), 239 deletions(-) rename spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/{chronjobs/ChronJobs.java => cronjobs/CronJobs.java} (52%) diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/chronjobs/ChronJobs.java b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/cronjobs/CronJobs.java similarity index 52% rename from spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/chronjobs/ChronJobs.java rename to spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/cronjobs/CronJobs.java index b58648ff9d..e71892d4e7 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/chronjobs/ChronJobs.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/cronjobs/CronJobs.java @@ -1,4 +1,4 @@ -package com.baeldung.reactive.debugging.consumer.chronjobs; +package com.baeldung.reactive.debugging.consumer.cronjobs; import com.baeldung.reactive.debugging.consumer.model.Foo; import com.baeldung.reactive.debugging.consumer.model.FooDto; @@ -16,10 +16,10 @@ import java.time.Duration; import java.util.concurrent.ThreadLocalRandom; @Component -public class ChronJobs { +public class CronJobs { - private static Logger logger = LoggerFactory.getLogger(ChronJobs.class); - private WebClient client = WebClient.create("http://localhost:8081"); + final Logger logger = LoggerFactory.getLogger(CronJobs.class); + final WebClient client = WebClient.create("http://localhost:8081"); @Autowired private FooService service; @@ -27,17 +27,19 @@ public class ChronJobs { @Scheduled(fixedRate = 10000) public void consumeInfiniteFlux() { Flux fluxFoo = client.get() - .uri("/functional-reactive/periodic-foo") - .accept(MediaType.TEXT_EVENT_STREAM) - .retrieve() - .bodyToFlux(FooDto.class) - .delayElements(Duration.ofMillis(100)) - .map(dto -> { - logger.debug("process 1 with dto id {} name{}", dto.getId(), dto.getName()); - return new Foo(dto); - }); - Integer random = ThreadLocalRandom.current() - .nextInt(0, 3); + .uri("/functional-reactive/periodic-foo") + .accept(MediaType.TEXT_EVENT_STREAM) + .retrieve() + .bodyToFlux(FooDto.class) + .delayElements(Duration.ofMillis(100)) + .map(dto -> { + logger.debug("process 1 with dto id {} name{}", dto.getId(), dto.getName()); + return new Foo(dto); + }); + + int random = ThreadLocalRandom.current() + .nextInt(0, 3); + switch (random) { case 0: logger.info("process 1 with approach 1"); @@ -51,24 +53,25 @@ public class ChronJobs { logger.info("process 1 with approach 2"); service.processFooInAnotherScenario(fluxFoo); break; - } } @Scheduled(fixedRate = 20000) public void consumeFiniteFlux2() { Flux fluxFoo = client.get() - .uri("/functional-reactive/periodic-foo-2") - .accept(MediaType.TEXT_EVENT_STREAM) - .retrieve() - .bodyToFlux(FooDto.class) - .delayElements(Duration.ofMillis(100)) - .map(dto -> { - logger.debug("process 2 with dto id {} name{}", dto.getId(), dto.getName()); - return new Foo(dto); - }); - Integer random = ThreadLocalRandom.current() - .nextInt(0, 3); + .uri("/functional-reactive/periodic-foo-2") + .accept(MediaType.TEXT_EVENT_STREAM) + .retrieve() + .bodyToFlux(FooDto.class) + .delayElements(Duration.ofMillis(100)) + .map(dto -> { + logger.debug("process 2 with dto id {} name{}", dto.getId(), dto.getName()); + return new Foo(dto); + }); + + int random = ThreadLocalRandom.current() + .nextInt(0, 3); + switch (random) { case 0: logger.info("process 2 with approach 1"); @@ -82,22 +85,21 @@ public class ChronJobs { logger.info("process 2 with approach 2"); service.processFooInAnotherScenario(fluxFoo); break; - } } @Scheduled(fixedRate = 20000) public void consumeFiniteFlux3() { Flux fluxFoo = client.get() - .uri("/functional-reactive/periodic-foo-2") - .accept(MediaType.TEXT_EVENT_STREAM) - .retrieve() - .bodyToFlux(FooDto.class) - .delayElements(Duration.ofMillis(100)) - .map(dto -> { - logger.debug("process 3 with dto id {} name{}", dto.getId(), dto.getName()); - return new Foo(dto); - }); + .uri("/functional-reactive/periodic-foo-2") + .accept(MediaType.TEXT_EVENT_STREAM) + .retrieve() + .bodyToFlux(FooDto.class) + .delayElements(Duration.ofMillis(100)) + .map(dto -> { + logger.debug("process 3 with dto id {} name{}", dto.getId(), dto.getName()); + return new Foo(dto); + }); logger.info("process 3 with approach 3"); service.processUsingApproachThree(fluxFoo); } @@ -105,15 +107,15 @@ public class ChronJobs { @Scheduled(fixedRate = 20000) public void consumeFiniteFluxWithCheckpoint4() { Flux fluxFoo = client.get() - .uri("/functional-reactive/periodic-foo-2") - .accept(MediaType.TEXT_EVENT_STREAM) - .retrieve() - .bodyToFlux(FooDto.class) - .delayElements(Duration.ofMillis(100)) - .map(dto -> { - logger.debug("process 4 with dto id {} name{}", dto.getId(), dto.getName()); - return new Foo(dto); - }); + .uri("/functional-reactive/periodic-foo-2") + .accept(MediaType.TEXT_EVENT_STREAM) + .retrieve() + .bodyToFlux(FooDto.class) + .delayElements(Duration.ofMillis(100)) + .map(dto -> { + logger.debug("process 4 with dto id {} name{}", dto.getId(), dto.getName()); + return new Foo(dto); + }); logger.info("process 4 with approach 4"); service.processUsingApproachFourWithCheckpoint(fluxFoo); } @@ -121,15 +123,15 @@ public class ChronJobs { @Scheduled(fixedRate = 20000) public void consumeFiniteFluxWitParallelScheduler() { Flux fluxFoo = client.get() - .uri("/functional-reactive/periodic-foo-2") - .accept(MediaType.TEXT_EVENT_STREAM) - .retrieve() - .bodyToFlux(FooDto.class) - .delayElements(Duration.ofMillis(100)) - .map(dto -> { - logger.debug("process 5-parallel with dto id {} name{}", dto.getId(), dto.getName()); - return new Foo(dto); - }); + .uri("/functional-reactive/periodic-foo-2") + .accept(MediaType.TEXT_EVENT_STREAM) + .retrieve() + .bodyToFlux(FooDto.class) + .delayElements(Duration.ofMillis(100)) + .map(dto -> { + logger.debug("process 5-parallel with dto id {} name{}", dto.getId(), dto.getName()); + return new Foo(dto); + }); logger.info("process 5-parallel with approach 5-parallel"); service.processUsingApproachFivePublishingToDifferentParallelThreads(fluxFoo); } @@ -137,15 +139,15 @@ public class ChronJobs { @Scheduled(fixedRate = 20000) public void consumeFiniteFluxWithSingleSchedulers() { Flux fluxFoo = client.get() - .uri("/functional-reactive/periodic-foo-2") - .accept(MediaType.TEXT_EVENT_STREAM) - .retrieve() - .bodyToFlux(FooDto.class) - .delayElements(Duration.ofMillis(100)) - .map(dto -> { - logger.debug("process 5-single with dto id {} name{}", dto.getId(), dto.getName()); - return new Foo(dto); - }); + .uri("/functional-reactive/periodic-foo-2") + .accept(MediaType.TEXT_EVENT_STREAM) + .retrieve() + .bodyToFlux(FooDto.class) + .delayElements(Duration.ofMillis(100)) + .map(dto -> { + logger.debug("process 5-single with dto id {} name{}", dto.getId(), dto.getName()); + return new Foo(dto); + }); logger.info("process 5-single with approach 5-single"); service.processUsingApproachFivePublishingToDifferentSingleThreads(fluxFoo); } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/model/Foo.java b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/model/Foo.java index d20e2c9ba0..b77b8e497a 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/model/Foo.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/model/Foo.java @@ -1,14 +1,12 @@ package com.baeldung.reactive.debugging.consumer.model; import lombok.AllArgsConstructor; -import lombok.Getter; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Setter; import java.util.concurrent.ThreadLocalRandom; -@Getter -@Setter +@Data @NoArgsConstructor @AllArgsConstructor public class Foo { @@ -18,10 +16,16 @@ public class Foo { private Integer quantity; public Foo(FooDto dto) { - this.id = (ThreadLocalRandom.current() - .nextInt(0, 100) == 0) ? null : dto.getId(); + this.id = randomId() == 0 ? null : dto.getId(); this.formattedName = dto.getName(); - this.quantity = ThreadLocalRandom.current() - .nextInt(0, 10); + this.quantity = randomQuantity(); + } + + private static int randomId() { + return ThreadLocalRandom.current().nextInt(0, 100); + } + + private static int randomQuantity() { + return ThreadLocalRandom.current().nextInt(0, 10); } } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/model/FooDto.java b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/model/FooDto.java index bf6f614e18..67c916baec 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/model/FooDto.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/model/FooDto.java @@ -1,16 +1,15 @@ package com.baeldung.reactive.debugging.consumer.model; import lombok.AllArgsConstructor; -import lombok.Getter; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Setter; -@Getter -@Setter +@Data @NoArgsConstructor @AllArgsConstructor public class FooDto { private Integer id; private String name; + } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooNameHelper.java b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooNameHelper.java index cdd9ca31a6..9a85f2015a 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooNameHelper.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooNameHelper.java @@ -1,44 +1,40 @@ package com.baeldung.reactive.debugging.consumer.service; import com.baeldung.reactive.debugging.consumer.model.Foo; -import reactor.core.publisher.Flux; import java.util.concurrent.ThreadLocalRandom; public class FooNameHelper { - public static Flux concatAndSubstringFooName(Flux flux) { - flux = concatFooName(flux); - flux = substringFooName(flux); - return flux; + public static Foo concatAndSubstringFooName(Foo foo) { + Foo concat = concatFooName(foo); + return substringFooName(concat); } - public static Flux concatFooName(Flux flux) { - flux = flux.map(foo -> { - String processedName = null; - Integer random = ThreadLocalRandom.current() - .nextInt(0, 80); - processedName = (random != 0) ? foo.getFormattedName() : foo.getFormattedName() + "-bael"; - foo.setFormattedName(processedName); - return foo; - }); - return flux; + public static Foo concatFooName(Foo foo) { + + int random = ThreadLocalRandom.current() + .nextInt(0, 80); + + String processedName = (random != 0) + ? foo.getFormattedName() + : foo.getFormattedName() + "-bael"; + + foo.setFormattedName(processedName); + return foo; } - public static Flux substringFooName(Flux flux) { - return flux.map(foo -> { - String processedName; - Integer random = ThreadLocalRandom.current() - .nextInt(0, 100); + public static Foo substringFooName(Foo foo) { + int random = ThreadLocalRandom.current() + .nextInt(0, 100); - processedName = (random == 0) ? foo.getFormattedName() - .substring(10, 15) - : foo.getFormattedName() - .substring(0, 5); + String processedName = (random == 0) + ? foo.getFormattedName().substring(10, 15) + : foo.getFormattedName().substring(0, 5); - foo.setFormattedName(processedName); - return foo; - }); + foo.setFormattedName(processedName); + + return foo; } } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooQuantityHelper.java b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooQuantityHelper.java index f4600b41b9..038f26dd8c 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooQuantityHelper.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooQuantityHelper.java @@ -1,30 +1,24 @@ package com.baeldung.reactive.debugging.consumer.service; import com.baeldung.reactive.debugging.consumer.model.Foo; -import reactor.core.publisher.Flux; import java.util.concurrent.ThreadLocalRandom; public class FooQuantityHelper { - public static Flux processFooReducingQuantity(Flux flux) { - flux = flux.map(foo -> { - Integer result; - Integer random = ThreadLocalRandom.current() - .nextInt(0, 90); - result = (random == 0) ? result = 0 : foo.getQuantity() + 2; - foo.setQuantity(result); - return foo; - }); - return divideFooQuantity(flux); + public static Foo processFooReducingQuantity(Foo foo) { + int random = ThreadLocalRandom.current().nextInt(0, 90); + int result = (random == 0) ? 0 : foo.getQuantity() + 2; + foo.setQuantity(result); + + return divideFooQuantity(foo); } - public static Flux divideFooQuantity(Flux flux) { - return flux.map(foo -> { - Integer result = Math.round(5 / foo.getQuantity()); - foo.setQuantity(result); - return foo; - }); + public static Foo divideFooQuantity(Foo foo) { + + Integer result = (int) Math.round(5.0 / foo.getQuantity()); + foo.setQuantity(result); + return foo; } } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooReporter.java b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooReporter.java index 1a8f9bc783..740c646e8d 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooReporter.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooReporter.java @@ -3,22 +3,22 @@ package com.baeldung.reactive.debugging.consumer.service; import com.baeldung.reactive.debugging.consumer.model.Foo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import reactor.core.publisher.Flux; public class FooReporter { - private static Logger logger = LoggerFactory.getLogger(FooReporter.class); + private static final Logger LOGGER = LoggerFactory.getLogger(FooReporter.class); - public static Flux reportResult(Flux input, String approach) { - return input.map(foo -> { - if (foo.getId() == null) - throw new IllegalArgumentException("Null id is not valid!"); - logger.info("Reporting for approach {}: Foo with id '{}' name '{}' and quantity '{}'", approach, foo.getId(), foo.getFormattedName(), foo.getQuantity()); - return foo; - }); + public static Foo reportResult(Foo foo, String approach) { + if (foo.getId() == null) { + throw new IllegalArgumentException("Null id is not valid!"); + } + LOGGER.info("Reporting for approach {}: Foo with id '{}' name '{}' and quantity '{}'", + approach, foo.getId(), foo.getFormattedName(), foo.getQuantity()); + + return foo; } - public static Flux reportResult(Flux input) { + public static Foo reportResult(Foo input) { return reportResult(input, "default"); } } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooService.java b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooService.java index bafaa3cfa0..bf630aacb5 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooService.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/service/FooService.java @@ -7,112 +7,107 @@ import org.springframework.stereotype.Component; import reactor.core.publisher.Flux; import reactor.core.scheduler.Schedulers; -import static com.baeldung.reactive.debugging.consumer.service.FooNameHelper.concatAndSubstringFooName; -import static com.baeldung.reactive.debugging.consumer.service.FooNameHelper.substringFooName; -import static com.baeldung.reactive.debugging.consumer.service.FooQuantityHelper.divideFooQuantity; -import static com.baeldung.reactive.debugging.consumer.service.FooQuantityHelper.processFooReducingQuantity; import static com.baeldung.reactive.debugging.consumer.service.FooReporter.reportResult; @Component public class FooService { - private static Logger logger = LoggerFactory.getLogger(FooService.class); + private static final Logger LOGGER = LoggerFactory.getLogger(FooService.class); public void processFoo(Flux flux) { - flux = FooNameHelper.concatFooName(flux); - flux = FooNameHelper.substringFooName(flux); - flux = flux.log(); - flux = FooReporter.reportResult(flux); - flux = flux.doOnError(error -> { - logger.error("The following error happened on processFoo method!", error); - }); - flux.subscribe(); + flux.map(FooNameHelper::concatFooName) + .map(FooNameHelper::substringFooName) + .log() + .map(FooReporter::reportResult) + .doOnError(error -> LOGGER.error("The following error happened on processFoo method!", error)) + .subscribe(); } public void processFooInAnotherScenario(Flux flux) { - flux = FooNameHelper.substringFooName(flux); - flux = FooQuantityHelper.divideFooQuantity(flux); - flux.subscribe(); + flux.map(FooNameHelper::substringFooName) + .map(FooQuantityHelper::divideFooQuantity) + .subscribe(); } public void processUsingApproachOneWithErrorHandling(Flux flux) { - logger.info("starting approach one w error handling!"); - flux = concatAndSubstringFooName(flux); - flux = concatAndSubstringFooName(flux); - flux = substringFooName(flux); - flux = processFooReducingQuantity(flux); - flux = processFooReducingQuantity(flux); - flux = processFooReducingQuantity(flux); - flux = reportResult(flux, "ONE w/ EH"); - flux = flux.doOnError(error -> { - logger.error("Approach 1 with Error Handling failed!", error); - }); - flux.subscribe(); + LOGGER.info("starting approach one w error handling!"); + + flux.map(FooNameHelper::concatAndSubstringFooName) + .map(FooNameHelper::concatAndSubstringFooName) + .map(FooNameHelper::substringFooName) + .map(FooQuantityHelper::processFooReducingQuantity) + .map(FooQuantityHelper::processFooReducingQuantity) + .map(FooQuantityHelper::processFooReducingQuantity) + .map(FooReporter::reportResult) + .doOnError(error -> LOGGER.error("Approach 1 with Error Handling failed!", error)) + .subscribe(); } public void processUsingApproachThree(Flux flux) { - logger.info("starting approach three!"); - flux = concatAndSubstringFooName(flux); - flux = reportResult(flux, "THREE"); - flux = flux.doOnError(error -> { - logger.error("Approach 3 failed!", error); - }); - flux.subscribe(); + LOGGER.info("starting approach three!"); + + flux.map(FooNameHelper::concatAndSubstringFooName) + .map(foo -> reportResult(foo, "THREE")) + .doOnError(error -> LOGGER.error("Approach 3 failed!", error)) + .subscribe(); } public void processUsingApproachFourWithCheckpoint(Flux flux) { - logger.info("starting approach four!"); - flux = concatAndSubstringFooName(flux); - flux = flux.checkpoint("CHECKPOINT 1"); - flux = concatAndSubstringFooName(flux); - flux = divideFooQuantity(flux); - flux = flux.checkpoint("CHECKPOINT 2", true); - flux = reportResult(flux, "FOUR"); - flux = concatAndSubstringFooName(flux).doOnError(error -> { - logger.error("Approach 4 failed!", error); - }); - flux.subscribe(); + LOGGER.info("starting approach four!"); + + flux.map(FooNameHelper::concatAndSubstringFooName) + .checkpoint("CHECKPOINT 1") + .map(FooNameHelper::concatAndSubstringFooName) + .map(FooQuantityHelper::divideFooQuantity) + .checkpoint("CHECKPOINT 2", true) + .map(foo -> reportResult(foo, "FOUR")) + .map(FooNameHelper::concatAndSubstringFooName) + .doOnError(error -> LOGGER.error("Approach 4 failed!", error)) + .subscribe(); } public void processUsingApproachFourWithInitialCheckpoint(Flux flux) { - logger.info("starting approach four!"); - flux = concatAndSubstringFooName(flux); - flux = flux.checkpoint("CHECKPOINT 1", true); - flux = concatAndSubstringFooName(flux); - flux = divideFooQuantity(flux); - flux = reportResult(flux, "FOUR"); - flux = flux.doOnError(error -> { - logger.error("Approach 4-2 failed!", error); - }); - flux.subscribe(); + LOGGER.info("starting approach four!"); + + flux.map(FooNameHelper::concatAndSubstringFooName) + .checkpoint("CHECKPOINT 1", true) + .map(FooNameHelper::concatAndSubstringFooName) + .map(FooQuantityHelper::divideFooQuantity) + .map(foo -> reportResult(foo, "FOUR")) + .map(FooNameHelper::concatAndSubstringFooName) + .doOnError(error -> LOGGER.error("Approach 4-2 failed!", error)) + .subscribe(); } public void processUsingApproachFivePublishingToDifferentParallelThreads(Flux flux) { - logger.info("starting approach five-parallel!"); - flux = concatAndSubstringFooName(flux).publishOn(Schedulers.newParallel("five-parallel-foo")) - .log(); - flux = concatAndSubstringFooName(flux); - flux = divideFooQuantity(flux); - flux = reportResult(flux, "FIVE-PARALLEL").publishOn(Schedulers.newSingle("five-parallel-bar")); - flux = concatAndSubstringFooName(flux).doOnError(error -> { - logger.error("Approach 5-parallel failed!", error); - }); - flux.subscribeOn(Schedulers.newParallel("five-parallel-starter")) - .subscribe(); + LOGGER.info("starting approach five-parallel!"); + + flux.map(FooNameHelper::concatAndSubstringFooName) + .publishOn(Schedulers.newParallel("five-parallel-foo")) + .log() + .map(FooNameHelper::concatAndSubstringFooName) + .map(foo -> reportResult(foo, "FIVE-PARALLEL")) + .publishOn(Schedulers.newSingle("five-parallel-bar")) + .map(FooNameHelper::concatAndSubstringFooName) + .doOnError(error -> LOGGER.error("Approach 5-parallel failed!", error)) + .subscribeOn(Schedulers.newParallel("five-parallel-starter")) + .subscribe(); } public void processUsingApproachFivePublishingToDifferentSingleThreads(Flux flux) { - logger.info("starting approach five-single!"); - flux = flux.log() - .subscribeOn(Schedulers.newSingle("five-single-starter")); - flux = concatAndSubstringFooName(flux).publishOn(Schedulers.newSingle("five-single-foo")); - flux = concatAndSubstringFooName(flux); - flux = divideFooQuantity(flux); - flux = reportResult(flux, "FIVE-SINGLE").publishOn(Schedulers.newSingle("five-single-bar")); - flux = concatAndSubstringFooName(flux).doOnError(error -> { - logger.error("Approach 5-single failed!", error); - }); - flux.subscribe(); + LOGGER.info("starting approach five-single!"); + + flux.log() + .subscribeOn(Schedulers.newSingle("five-single-starter")) + .map(FooNameHelper::concatAndSubstringFooName) + .publishOn(Schedulers.newSingle("five-single-foo")) + .map(FooNameHelper::concatAndSubstringFooName) + .map(FooQuantityHelper::divideFooQuantity) + .map(foo -> reportResult(foo, "FIVE-SINGLE")) + .publishOn(Schedulers.newSingle("five-single-bar")) + .map(FooNameHelper::concatAndSubstringFooName) + .doOnError(error -> LOGGER.error("Approach 5-single failed!", error)) + .subscribe(); } } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/server/handlers/ServerHandler.java b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/server/handlers/ServerHandler.java index 15f9a4b786..a86932c6f9 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/debugging/server/handlers/ServerHandler.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/debugging/server/handlers/ServerHandler.java @@ -16,30 +16,31 @@ import java.util.concurrent.ThreadLocalRandom; @Component public class ServerHandler { - private static Logger logger = LoggerFactory.getLogger(ServerHandler.class); + private static final Logger LOGGER = LoggerFactory.getLogger(ServerHandler.class); public Mono useHandler(final ServerRequest request) { // there are chances that something goes wrong here... return ServerResponse.ok() .contentType(MediaType.TEXT_EVENT_STREAM) - .body(Flux.interval(Duration.ofSeconds(1)) - .map(sequence -> { - logger.info("retrieving Foo. Sequence: {}", sequence); - if (ThreadLocalRandom.current() - .nextInt(0, 50) == 1) { - throw new RuntimeException("There was an error retrieving the Foo!"); - } - return new Foo(sequence, "name" + sequence); - - }), Foo.class); + .body(getFlux(), Foo.class); } public Mono useHandlerFinite(final ServerRequest request) { return ServerResponse.ok() .contentType(MediaType.TEXT_EVENT_STREAM) .body(Flux.range(0, 50) - .map(sequence -> { - return new Foo(new Long(sequence), "theFooNameNumber" + sequence); - }), Foo.class); + .map(sequence -> new Foo(new Long(sequence), "theFooNameNumber" + sequence) + ), Foo.class); + } + + private static Flux getFlux() { + return Flux.interval(Duration.ofSeconds(1)) + .map(sequence -> { + LOGGER.info("retrieving Foo. Sequence: {}", sequence); + if (ThreadLocalRandom.current().nextInt(0, 50) == 1) { + throw new RuntimeException("There was an error retrieving the Foo!"); + } + return new Foo(sequence, "name" + sequence); + }); } } diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/debugging/consumer/ConsumerFooServiceIntegrationTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/debugging/consumer/ConsumerFooServiceIntegrationTest.java index 37e2ebe0ac..3635844056 100644 --- a/spring-reactive/src/test/java/com/baeldung/reactive/debugging/consumer/ConsumerFooServiceIntegrationTest.java +++ b/spring-reactive/src/test/java/com/baeldung/reactive/debugging/consumer/ConsumerFooServiceIntegrationTest.java @@ -45,19 +45,19 @@ public class ConsumerFooServiceIntegrationTest { Collection allSuppressedEntries = ListAppender.getEvents() .stream() .map(ILoggingEvent::getThrowableProxy) - .flatMap(t -> { - return Optional.ofNullable(t) - .map(IThrowableProxy::getSuppressed) - .map(Arrays::stream) - .orElse(Stream.empty()); - }) + .flatMap(t -> Optional.ofNullable(t) + .map(IThrowableProxy::getSuppressed) + .map(Arrays::stream) + .orElse(Stream.empty())) .map(IThrowableProxy::getClassName) .collect(Collectors.toList()); - assertThat(allLoggedEntries).anyMatch(entry -> entry.contains("The following error happened on processFoo method!")) - .anyMatch(entry -> entry.contains("| onSubscribe")) - .anyMatch(entry -> entry.contains("| cancel()")); + + assertThat(allLoggedEntries) + .anyMatch(entry -> entry.contains("The following error happened on processFoo method!")) + .anyMatch(entry -> entry.contains("| onSubscribe")) + .anyMatch(entry -> entry.contains("| cancel()")); assertThat(allSuppressedEntries) - .anyMatch(entry -> entry.contains("reactor.core.publisher.FluxOnAssembly$OnAssemblyException")); + .anyMatch(entry -> entry.contains("reactor.core.publisher.FluxOnAssembly$OnAssemblyException")); } } diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/debugging/consumer/ConsumerFooServiceLiveTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/debugging/consumer/ConsumerFooServiceLiveTest.java index ff6e4b2bd2..89e92f2818 100644 --- a/spring-reactive/src/test/java/com/baeldung/reactive/debugging/consumer/ConsumerFooServiceLiveTest.java +++ b/spring-reactive/src/test/java/com/baeldung/reactive/debugging/consumer/ConsumerFooServiceLiveTest.java @@ -1,6 +1,5 @@ package com.baeldung.reactive.debugging.consumer; -import com.baeldung.reactive.debugging.consumer.service.FooService; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.test.web.reactive.server.WebTestClient; @@ -13,8 +12,6 @@ import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; */ public class ConsumerFooServiceLiveTest { - FooService service = new FooService(); - private static final String BASE_URL = "http://localhost:8082"; private static final String DEBUG_HOOK_ON = BASE_URL + "/debug-hook-on"; private static final String DEBUG_HOOK_OFF = BASE_URL + "/debug-hook-off"; diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/debugging/consumer/utils/ListAppender.java b/spring-reactive/src/test/java/com/baeldung/reactive/debugging/consumer/utils/ListAppender.java index fe8b04e824..9e1fae9135 100644 --- a/spring-reactive/src/test/java/com/baeldung/reactive/debugging/consumer/utils/ListAppender.java +++ b/spring-reactive/src/test/java/com/baeldung/reactive/debugging/consumer/utils/ListAppender.java @@ -8,18 +8,18 @@ import java.util.List; public class ListAppender extends AppenderBase { - static private List events = new ArrayList<>(); + private static final List EVENTS = new ArrayList<>(); @Override protected void append(ILoggingEvent eventObject) { - events.add(eventObject); + EVENTS.add(eventObject); } public static List getEvents() { - return events; + return EVENTS; } public static void clearEventList() { - events.clear(); + EVENTS.clear(); } } From 42a804e715c0eadf349d4667dd22de1c19e64995 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Fri, 1 Apr 2022 15:50:07 +0100 Subject: [PATCH 215/249] [JAVA-11196] Split httpclient module --- httpclient-2/README.md | 1 + httpclient-2/pom.xml | 5 +++++ .../httpclient/rare/HttpClientUnshortenLiveTest.java | 0 httpclient/README.md | 1 - httpclient/pom.xml | 6 ------ 5 files changed, 6 insertions(+), 7 deletions(-) rename {httpclient => httpclient-2}/src/test/java/com/baeldung/httpclient/rare/HttpClientUnshortenLiveTest.java (100%) diff --git a/httpclient-2/README.md b/httpclient-2/README.md index 4f9805063c..49adf470e9 100644 --- a/httpclient-2/README.md +++ b/httpclient-2/README.md @@ -12,4 +12,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Reading an HTTP Response Body as a String in Java](https://www.baeldung.com/java-http-response-body-as-string) - [How To Get Cookies From the Apache HttpClient Response](https://www.baeldung.com/java-apache-httpclient-cookies) - [Enabling Logging for Apache HttpClient](https://www.baeldung.com/apache-httpclient-enable-logging) +- [Unshorten URLs with HttpClient](https://www.baeldung.com/unshorten-url-httpclient) - More articles: [[<-- prev]](../httpclient) diff --git a/httpclient-2/pom.xml b/httpclient-2/pom.xml index 287ff27e35..32f2e80b18 100644 --- a/httpclient-2/pom.xml +++ b/httpclient-2/pom.xml @@ -15,6 +15,11 @@
+ + org.apache.commons + commons-lang3 + ${commons-lang3.version} + org.apache.httpcomponents diff --git a/httpclient/src/test/java/com/baeldung/httpclient/rare/HttpClientUnshortenLiveTest.java b/httpclient-2/src/test/java/com/baeldung/httpclient/rare/HttpClientUnshortenLiveTest.java similarity index 100% rename from httpclient/src/test/java/com/baeldung/httpclient/rare/HttpClientUnshortenLiveTest.java rename to httpclient-2/src/test/java/com/baeldung/httpclient/rare/HttpClientUnshortenLiveTest.java diff --git a/httpclient/README.md b/httpclient/README.md index 3c5b0b3376..8cc61386e1 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -10,7 +10,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [HttpClient 4 – Cancel Request](https://www.baeldung.com/httpclient-cancel-request) - [HttpClient 4 Cookbook](https://www.baeldung.com/httpclient4) -- [Unshorten URLs with HttpClient](https://www.baeldung.com/unshorten-url-httpclient) - [HttpClient 4 – Follow Redirects for POST](https://www.baeldung.com/httpclient-redirect-on-http-post) - [Multipart Upload with HttpClient 4](https://www.baeldung.com/httpclient-multipart-upload) - [HttpAsyncClient Tutorial](https://www.baeldung.com/httpasyncclient-tutorial) diff --git a/httpclient/pom.xml b/httpclient/pom.xml index a1627cb6fa..b69981fb13 100644 --- a/httpclient/pom.xml +++ b/httpclient/pom.xml @@ -15,12 +15,6 @@ - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - org.apache.httpcomponents From 113d4f182473091c5dc6d50ae18e65ceb58da506 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Fri, 1 Apr 2022 22:26:34 +0100 Subject: [PATCH 216/249] [JAVA-11186] Split java-mongodb module --- persistence-modules/java-mongodb-2/README.md | 6 + .../com/baeldung/mongo/PushOperations.java | 6 +- .../baeldung/mongo/PushOperationLiveTest.java | 15 +- .../aggregation/AggregationLiveTest.java | 43 +- .../field/FieldExistenceLiveTest.java | 6 +- .../mongo}/geo/MongoGeospatialLiveTest.java | 25 +- .../CaseInsensitiveOrderingLiveTest.java | 8 +- .../src/test/resources/countrydata.json | 498 +++++++++--------- persistence-modules/java-mongodb/README.md | 6 +- 9 files changed, 307 insertions(+), 306 deletions(-) rename persistence-modules/{java-mongodb => java-mongodb-2}/src/main/java/com/baeldung/mongo/PushOperations.java (97%) rename persistence-modules/{java-mongodb => java-mongodb-2}/src/test/java/com/baeldung/mongo/PushOperationLiveTest.java (99%) rename persistence-modules/{java-mongodb/src/test/java/com/baeldung => java-mongodb-2/src/test/java/com/baeldung/mongo}/aggregation/AggregationLiveTest.java (99%) rename persistence-modules/{java-mongodb/src/test/java/com/baeldung => java-mongodb-2/src/test/java/com/baeldung/mongo}/existence/field/FieldExistenceLiveTest.java (90%) rename persistence-modules/{java-mongodb/src/test/java/com/baeldung => java-mongodb-2/src/test/java/com/baeldung/mongo}/geo/MongoGeospatialLiveTest.java (99%) rename persistence-modules/{java-mongodb/src/test/java/com/baeldung => java-mongodb-2/src/test/java/com/baeldung/mongo}/ordering/caseinsensitive/CaseInsensitiveOrderingLiveTest.java (94%) rename persistence-modules/{java-mongodb => java-mongodb-2}/src/test/resources/countrydata.json (99%) diff --git a/persistence-modules/java-mongodb-2/README.md b/persistence-modules/java-mongodb-2/README.md index 6e39bddfbe..c9554413f9 100644 --- a/persistence-modules/java-mongodb-2/README.md +++ b/persistence-modules/java-mongodb-2/README.md @@ -4,3 +4,9 @@ This module contains articles about MongoDB in Java. - [Guide to Upsert in MongoDB](https://www.baeldung.com/mongodb-upsert) - [Bulk Update of Documents in MongoDB](https://www.baeldung.com/mongodb-bulk-update-documents) +- [Case Insensitive Sorting in MongoDB](https://www.baeldung.com/java-mongodb-case-insensitive-sorting) +- [How to Check Field Existence in MongoDB?](https://www.baeldung.com/mongodb-check-field-exists) +- [Push Operations in MongoDB](https://www.baeldung.com/mongodb-push-operations) +- [Geospatial Support in MongoDB](https://www.baeldung.com/mongodb-geospatial-support) +- [MongoDB Aggregations Using Java](https://www.baeldung.com/java-mongodb-aggregations) +- More articles: [[<-- prev]](../java-mongodb) \ No newline at end of file diff --git a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/PushOperations.java b/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/PushOperations.java similarity index 97% rename from persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/PushOperations.java rename to persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/PushOperations.java index fa1f9ddc96..5cfbe5f309 100644 --- a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/PushOperations.java +++ b/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/PushOperations.java @@ -1,10 +1,5 @@ package com.baeldung.mongo; -import java.io.FileNotFoundException; -import java.io.IOException; - -import org.bson.Document; - import com.mongodb.BasicDBObject; import com.mongodb.DBObject; import com.mongodb.MongoClient; @@ -13,6 +8,7 @@ import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Updates; import com.mongodb.client.result.UpdateResult; +import org.bson.Document; public class PushOperations { diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/mongo/PushOperationLiveTest.java b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/PushOperationLiveTest.java similarity index 99% rename from persistence-modules/java-mongodb/src/test/java/com/baeldung/mongo/PushOperationLiveTest.java rename to persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/PushOperationLiveTest.java index bd8523b301..9427b174ff 100644 --- a/persistence-modules/java-mongodb/src/test/java/com/baeldung/mongo/PushOperationLiveTest.java +++ b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/PushOperationLiveTest.java @@ -1,13 +1,5 @@ package com.baeldung.mongo; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; - -import org.bson.Document; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - import com.mongodb.BasicDBObject; import com.mongodb.DBObject; import com.mongodb.MongoClient; @@ -16,6 +8,13 @@ import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Updates; import com.mongodb.client.result.UpdateResult; +import org.bson.Document; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; public class PushOperationLiveTest { diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/aggregation/AggregationLiveTest.java b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/aggregation/AggregationLiveTest.java similarity index 99% rename from persistence-modules/java-mongodb/src/test/java/com/baeldung/aggregation/AggregationLiveTest.java rename to persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/aggregation/AggregationLiveTest.java index 62ab13563a..fdba2586e7 100644 --- a/persistence-modules/java-mongodb/src/test/java/com/baeldung/aggregation/AggregationLiveTest.java +++ b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/aggregation/AggregationLiveTest.java @@ -1,4 +1,24 @@ -package com.baeldung.aggregation; +package com.baeldung.mongo.aggregation; + +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Accumulators; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Projections; +import com.mongodb.client.model.Sorts; +import org.bson.Document; +import org.bson.conversions.Bson; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Arrays; import static com.mongodb.client.model.Aggregates.count; import static com.mongodb.client.model.Aggregates.group; @@ -11,27 +31,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.Arrays; - -import org.bson.Document; -import org.bson.conversions.Bson; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoClients; -import com.mongodb.client.MongoCollection; -import com.mongodb.client.MongoDatabase; -import com.mongodb.client.model.Accumulators; -import com.mongodb.client.model.Filters; -import com.mongodb.client.model.Projections; -import com.mongodb.client.model.Sorts; - public class AggregationLiveTest { private static final String DATABASE = "world"; diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/existence/field/FieldExistenceLiveTest.java b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/existence/field/FieldExistenceLiveTest.java similarity index 90% rename from persistence-modules/java-mongodb/src/test/java/com/baeldung/existence/field/FieldExistenceLiveTest.java rename to persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/existence/field/FieldExistenceLiveTest.java index ca37ac6664..94acb314b6 100644 --- a/persistence-modules/java-mongodb/src/test/java/com/baeldung/existence/field/FieldExistenceLiveTest.java +++ b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/existence/field/FieldExistenceLiveTest.java @@ -1,4 +1,4 @@ -package com.baeldung.existence.field; +package com.baeldung.mongo.existence.field; import com.mongodb.BasicDBObject; import com.mongodb.MongoClient; @@ -9,7 +9,9 @@ import org.bson.Document; import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; public class FieldExistenceLiveTest { private MongoClient mongoClient; diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/MongoGeospatialLiveTest.java b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/geo/MongoGeospatialLiveTest.java similarity index 99% rename from persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/MongoGeospatialLiveTest.java rename to persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/geo/MongoGeospatialLiveTest.java index 6e5a56491b..27d4766578 100644 --- a/persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/MongoGeospatialLiveTest.java +++ b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/geo/MongoGeospatialLiveTest.java @@ -1,16 +1,4 @@ -package com.baeldung.geo; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.bson.Document; -import org.junit.Before; -import org.junit.Test; +package com.baeldung.mongo.geo; import com.mongodb.MongoClient; import com.mongodb.client.FindIterable; @@ -21,6 +9,17 @@ import com.mongodb.client.model.Indexes; import com.mongodb.client.model.geojson.Point; import com.mongodb.client.model.geojson.Polygon; import com.mongodb.client.model.geojson.Position; +import org.bson.Document; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; public class MongoGeospatialLiveTest { diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/ordering/caseinsensitive/CaseInsensitiveOrderingLiveTest.java b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/ordering/caseinsensitive/CaseInsensitiveOrderingLiveTest.java similarity index 94% rename from persistence-modules/java-mongodb/src/test/java/com/baeldung/ordering/caseinsensitive/CaseInsensitiveOrderingLiveTest.java rename to persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/ordering/caseinsensitive/CaseInsensitiveOrderingLiveTest.java index ec2c332018..3705e68893 100644 --- a/persistence-modules/java-mongodb/src/test/java/com/baeldung/ordering/caseinsensitive/CaseInsensitiveOrderingLiveTest.java +++ b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/ordering/caseinsensitive/CaseInsensitiveOrderingLiveTest.java @@ -1,7 +1,11 @@ -package com.baeldung.ordering.caseinsensitive; +package com.baeldung.mongo.ordering.caseinsensitive; import com.mongodb.MongoClient; -import com.mongodb.client.*; +import com.mongodb.client.AggregateIterable; +import com.mongodb.client.FindIterable; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoCursor; +import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.Collation; import com.mongodb.client.model.Projections; import com.mongodb.client.model.Sorts; diff --git a/persistence-modules/java-mongodb/src/test/resources/countrydata.json b/persistence-modules/java-mongodb-2/src/test/resources/countrydata.json similarity index 99% rename from persistence-modules/java-mongodb/src/test/resources/countrydata.json rename to persistence-modules/java-mongodb-2/src/test/resources/countrydata.json index 81213c31e7..dd6df954d4 100644 --- a/persistence-modules/java-mongodb/src/test/resources/countrydata.json +++ b/persistence-modules/java-mongodb-2/src/test/resources/countrydata.json @@ -1,250 +1,250 @@ -{"name":"Afghanistan","topLevelDomain":[".af"],"alpha2Code":"AF","alpha3Code":"AFG","callingCodes":["93"],"capital":"Kabul","altSpellings":["AF","Afġānistān"],"region":"Asia","subregion":"Southern Asia","population":27657145,"latlng":[33.0,65.0],"demonym":"Afghan","area":652230.0,"gini":27.8,"timezones":["UTC+04:30"],"borders":["IRN","PAK","TKM","UZB","TJK","CHN"],"nativeName":"افغانستان","numericCode":"004","currencies":[{"code":"AFN","name":"Afghan afghani","symbol":"؋"}],"languages":[{"iso639_1":"ps","iso639_2":"pus","name":"Pashto","nativeName":"پښتو"},{"iso639_1":"uz","iso639_2":"uzb","name":"Uzbek","nativeName":"Oʻzbek"},{"iso639_1":"tk","iso639_2":"tuk","name":"Turkmen","nativeName":"Türkmen"}],"translations":{"de":"Afghanistan","es":"Afganistán","fr":"Afghanistan","ja":"アフガニスタン","it":"Afghanistan","br":"Afeganistão","pt":"Afeganistão","nl":"Afghanistan","hr":"Afganistan","fa":"افغانستان"},"flag":"https://restcountries.eu/data/afg.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"AFG"} -{"name":"Åland Islands","topLevelDomain":[".ax"],"alpha2Code":"AX","alpha3Code":"ALA","callingCodes":["358"],"capital":"Mariehamn","altSpellings":["AX","Aaland","Aland","Ahvenanmaa"],"region":"Europe","subregion":"Northern Europe","population":28875,"latlng":[60.116667,19.9],"demonym":"Ålandish","area":1580.0,"gini":null,"timezones":["UTC+02:00"],"borders":[],"nativeName":"Åland","numericCode":"248","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"sv","iso639_2":"swe","name":"Swedish","nativeName":"svenska"}],"translations":{"de":"Åland","es":"Alandia","fr":"Åland","ja":"オーランド諸島","it":"Isole Aland","br":"Ilhas de Aland","pt":"Ilhas de Aland","nl":"Ålandeilanden","hr":"Ålandski otoci","fa":"جزایر الند"},"flag":"https://restcountries.eu/data/ala.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":""} -{"name":"Albania","topLevelDomain":[".al"],"alpha2Code":"AL","alpha3Code":"ALB","callingCodes":["355"],"capital":"Tirana","altSpellings":["AL","Shqipëri","Shqipëria","Shqipnia"],"region":"Europe","subregion":"Southern Europe","population":2886026,"latlng":[41.0,20.0],"demonym":"Albanian","area":28748.0,"gini":34.5,"timezones":["UTC+01:00"],"borders":["MNE","GRC","MKD","KOS"],"nativeName":"Shqipëria","numericCode":"008","currencies":[{"code":"ALL","name":"Albanian lek","symbol":"L"}],"languages":[{"iso639_1":"sq","iso639_2":"sqi","name":"Albanian","nativeName":"Shqip"}],"translations":{"de":"Albanien","es":"Albania","fr":"Albanie","ja":"アルバニア","it":"Albania","br":"Albânia","pt":"Albânia","nl":"Albanië","hr":"Albanija","fa":"آلبانی"},"flag":"https://restcountries.eu/data/alb.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":"ALB"} -{"name":"Algeria","topLevelDomain":[".dz"],"alpha2Code":"DZ","alpha3Code":"DZA","callingCodes":["213"],"capital":"Algiers","altSpellings":["DZ","Dzayer","Algérie"],"region":"Africa","subregion":"Northern Africa","population":40400000,"latlng":[28.0,3.0],"demonym":"Algerian","area":2381741.0,"gini":35.3,"timezones":["UTC+01:00"],"borders":["TUN","LBY","NER","ESH","MRT","MLI","MAR"],"nativeName":"الجزائر","numericCode":"012","currencies":[{"code":"DZD","name":"Algerian dinar","symbol":"د.ج"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Algerien","es":"Argelia","fr":"Algérie","ja":"アルジェリア","it":"Algeria","br":"Argélia","pt":"Argélia","nl":"Algerije","hr":"Alžir","fa":"الجزایر"},"flag":"https://restcountries.eu/data/dza.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"ALG"} -{"name":"American Samoa","topLevelDomain":[".as"],"alpha2Code":"AS","alpha3Code":"ASM","callingCodes":["1684"],"capital":"Pago Pago","altSpellings":["AS","Amerika Sāmoa","Amelika Sāmoa","Sāmoa Amelika"],"region":"Oceania","subregion":"Polynesia","population":57100,"latlng":[-14.33333333,-170.0],"demonym":"American Samoan","area":199.0,"gini":null,"timezones":["UTC-11:00"],"borders":[],"nativeName":"American Samoa","numericCode":"016","currencies":[{"code":"USD","name":"United State Dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"sm","iso639_2":"smo","name":"Samoan","nativeName":"gagana fa'a Samoa"}],"translations":{"de":"Amerikanisch-Samoa","es":"Samoa Americana","fr":"Samoa américaines","ja":"アメリカ領サモア","it":"Samoa Americane","br":"Samoa Americana","pt":"Samoa Americana","nl":"Amerikaans Samoa","hr":"Američka Samoa","fa":"ساموآی آمریکا"},"flag":"https://restcountries.eu/data/asm.svg","regionalBlocs":[],"cioc":"ASA"} -{"name":"Andorra","topLevelDomain":[".ad"],"alpha2Code":"AD","alpha3Code":"AND","callingCodes":["376"],"capital":"Andorra la Vella","altSpellings":["AD","Principality of Andorra","Principat d'Andorra"],"region":"Europe","subregion":"Southern Europe","population":78014,"latlng":[42.5,1.5],"demonym":"Andorran","area":468.0,"gini":null,"timezones":["UTC+01:00"],"borders":["FRA","ESP"],"nativeName":"Andorra","numericCode":"020","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"ca","iso639_2":"cat","name":"Catalan","nativeName":"català"}],"translations":{"de":"Andorra","es":"Andorra","fr":"Andorre","ja":"アンドラ","it":"Andorra","br":"Andorra","pt":"Andorra","nl":"Andorra","hr":"Andora","fa":"آندورا"},"flag":"https://restcountries.eu/data/and.svg","regionalBlocs":[],"cioc":"AND"} -{"name":"Angola","topLevelDomain":[".ao"],"alpha2Code":"AO","alpha3Code":"AGO","callingCodes":["244"],"capital":"Luanda","altSpellings":["AO","República de Angola","ʁɛpublika de an'ɡɔla"],"region":"Africa","subregion":"Middle Africa","population":25868000,"latlng":[-12.5,18.5],"demonym":"Angolan","area":1246700.0,"gini":58.6,"timezones":["UTC+01:00"],"borders":["COG","COD","ZMB","NAM"],"nativeName":"Angola","numericCode":"024","currencies":[{"code":"AOA","name":"Angolan kwanza","symbol":"Kz"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Angola","es":"Angola","fr":"Angola","ja":"アンゴラ","it":"Angola","br":"Angola","pt":"Angola","nl":"Angola","hr":"Angola","fa":"آنگولا"},"flag":"https://restcountries.eu/data/ago.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"ANG"} -{"name":"Anguilla","topLevelDomain":[".ai"],"alpha2Code":"AI","alpha3Code":"AIA","callingCodes":["1264"],"capital":"The Valley","altSpellings":["AI"],"region":"Americas","subregion":"Caribbean","population":13452,"latlng":[18.25,-63.16666666],"demonym":"Anguillian","area":91.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Anguilla","numericCode":"660","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Anguilla","es":"Anguilla","fr":"Anguilla","ja":"アンギラ","it":"Anguilla","br":"Anguila","pt":"Anguila","nl":"Anguilla","hr":"Angvila","fa":"آنگویلا"},"flag":"https://restcountries.eu/data/aia.svg","regionalBlocs":[],"cioc":""} -{"name":"Antarctica","topLevelDomain":[".aq"],"alpha2Code":"AQ","alpha3Code":"ATA","callingCodes":["672"],"capital":"","altSpellings":[],"region":"Polar","subregion":"","population":1000,"latlng":[-74.65,4.48],"demonym":"","area":1.4E7,"gini":null,"timezones":["UTC-03:00","UTC+03:00","UTC+05:00","UTC+06:00","UTC+07:00","UTC+08:00","UTC+10:00","UTC+12:00"],"borders":[],"nativeName":"Antarctica","numericCode":"010","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"},{"code":"GBP","name":"British pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Antarktika","es":"Antártida","fr":"Antarctique","ja":"南極大陸","it":"Antartide","br":"Antártida","pt":"Antárctida","nl":"Antarctica","hr":"Antarktika","fa":"جنوبگان"},"flag":"https://restcountries.eu/data/ata.svg","regionalBlocs":[],"cioc":""} -{"name":"Antigua and Barbuda","topLevelDomain":[".ag"],"alpha2Code":"AG","alpha3Code":"ATG","callingCodes":["1268"],"capital":"Saint John's","altSpellings":["AG"],"region":"Americas","subregion":"Caribbean","population":86295,"latlng":[17.05,-61.8],"demonym":"Antiguan, Barbudan","area":442.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Antigua and Barbuda","numericCode":"028","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Antigua und Barbuda","es":"Antigua y Barbuda","fr":"Antigua-et-Barbuda","ja":"アンティグア・バーブーダ","it":"Antigua e Barbuda","br":"Antígua e Barbuda","pt":"Antígua e Barbuda","nl":"Antigua en Barbuda","hr":"Antigva i Barbuda","fa":"آنتیگوا و باربودا"},"flag":"https://restcountries.eu/data/atg.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"ANT"} -{"name":"Argentina","topLevelDomain":[".ar"],"alpha2Code":"AR","alpha3Code":"ARG","callingCodes":["54"],"capital":"Buenos Aires","altSpellings":["AR","Argentine Republic","República Argentina"],"region":"Americas","subregion":"South America","population":43590400,"latlng":[-34.0,-64.0],"demonym":"Argentinean","area":2780400.0,"gini":44.5,"timezones":["UTC-03:00"],"borders":["BOL","BRA","CHL","PRY","URY"],"nativeName":"Argentina","numericCode":"032","currencies":[{"code":"ARS","name":"Argentine peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"},{"iso639_1":"gn","iso639_2":"grn","name":"Guaraní","nativeName":"Avañe'ẽ"}],"translations":{"de":"Argentinien","es":"Argentina","fr":"Argentine","ja":"アルゼンチン","it":"Argentina","br":"Argentina","pt":"Argentina","nl":"Argentinië","hr":"Argentina","fa":"آرژانتین"},"flag":"https://restcountries.eu/data/arg.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"ARG"} -{"name":"Armenia","topLevelDomain":[".am"],"alpha2Code":"AM","alpha3Code":"ARM","callingCodes":["374"],"capital":"Yerevan","altSpellings":["AM","Hayastan","Republic of Armenia","Հայաստանի Հանրապետություն"],"region":"Asia","subregion":"Western Asia","population":2994400,"latlng":[40.0,45.0],"demonym":"Armenian","area":29743.0,"gini":30.9,"timezones":["UTC+04:00"],"borders":["AZE","GEO","IRN","TUR"],"nativeName":"Հայաստան","numericCode":"051","currencies":[{"code":"AMD","name":"Armenian dram","symbol":null}],"languages":[{"iso639_1":"hy","iso639_2":"hye","name":"Armenian","nativeName":"Հայերեն"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Armenien","es":"Armenia","fr":"Arménie","ja":"アルメニア","it":"Armenia","br":"Armênia","pt":"Arménia","nl":"Armenië","hr":"Armenija","fa":"ارمنستان"},"flag":"https://restcountries.eu/data/arm.svg","regionalBlocs":[{"acronym":"EEU","name":"Eurasian Economic Union","otherAcronyms":["EAEU"],"otherNames":[]}],"cioc":"ARM"} -{"name":"Aruba","topLevelDomain":[".aw"],"alpha2Code":"AW","alpha3Code":"ABW","callingCodes":["297"],"capital":"Oranjestad","altSpellings":["AW"],"region":"Americas","subregion":"Caribbean","population":107394,"latlng":[12.5,-69.96666666],"demonym":"Aruban","area":180.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Aruba","numericCode":"533","currencies":[{"code":"AWG","name":"Aruban florin","symbol":"ƒ"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"},{"iso639_1":"pa","iso639_2":"pan","name":"(Eastern) Punjabi","nativeName":"ਪੰਜਾਬੀ"}],"translations":{"de":"Aruba","es":"Aruba","fr":"Aruba","ja":"アルバ","it":"Aruba","br":"Aruba","pt":"Aruba","nl":"Aruba","hr":"Aruba","fa":"آروبا"},"flag":"https://restcountries.eu/data/abw.svg","regionalBlocs":[],"cioc":"ARU"} -{"name":"Australia","topLevelDomain":[".au"],"alpha2Code":"AU","alpha3Code":"AUS","callingCodes":["61"],"capital":"Canberra","altSpellings":["AU"],"region":"Oceania","subregion":"Australia and New Zealand","population":24117360,"latlng":[-27.0,133.0],"demonym":"Australian","area":7692024.0,"gini":30.5,"timezones":["UTC+05:00","UTC+06:30","UTC+07:00","UTC+08:00","UTC+09:30","UTC+10:00","UTC+10:30","UTC+11:30"],"borders":[],"nativeName":"Australia","numericCode":"036","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Australien","es":"Australia","fr":"Australie","ja":"オーストラリア","it":"Australia","br":"Austrália","pt":"Austrália","nl":"Australië","hr":"Australija","fa":"استرالیا"},"flag":"https://restcountries.eu/data/aus.svg","regionalBlocs":[],"cioc":"AUS"} -{"name":"Austria","topLevelDomain":[".at"],"alpha2Code":"AT","alpha3Code":"AUT","callingCodes":["43"],"capital":"Vienna","altSpellings":["AT","Österreich","Osterreich","Oesterreich"],"region":"Europe","subregion":"Western Europe","population":8725931,"latlng":[47.33333333,13.33333333],"demonym":"Austrian","area":83871.0,"gini":26.0,"timezones":["UTC+01:00"],"borders":["CZE","DEU","HUN","ITA","LIE","SVK","SVN","CHE"],"nativeName":"Österreich","numericCode":"040","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"}],"translations":{"de":"Österreich","es":"Austria","fr":"Autriche","ja":"オーストリア","it":"Austria","br":"áustria","pt":"áustria","nl":"Oostenrijk","hr":"Austrija","fa":"اتریش"},"flag":"https://restcountries.eu/data/aut.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"AUT"} -{"name":"Azerbaijan","topLevelDomain":[".az"],"alpha2Code":"AZ","alpha3Code":"AZE","callingCodes":["994"],"capital":"Baku","altSpellings":["AZ","Republic of Azerbaijan","Azərbaycan Respublikası"],"region":"Asia","subregion":"Western Asia","population":9730500,"latlng":[40.5,47.5],"demonym":"Azerbaijani","area":86600.0,"gini":33.7,"timezones":["UTC+04:00"],"borders":["ARM","GEO","IRN","RUS","TUR"],"nativeName":"Azərbaycan","numericCode":"031","currencies":[{"code":"AZN","name":"Azerbaijani manat","symbol":null}],"languages":[{"iso639_1":"az","iso639_2":"aze","name":"Azerbaijani","nativeName":"azərbaycan dili"}],"translations":{"de":"Aserbaidschan","es":"Azerbaiyán","fr":"Azerbaïdjan","ja":"アゼルバイジャン","it":"Azerbaijan","br":"Azerbaijão","pt":"Azerbaijão","nl":"Azerbeidzjan","hr":"Azerbajdžan","fa":"آذربایجان"},"flag":"https://restcountries.eu/data/aze.svg","regionalBlocs":[],"cioc":"AZE"} -{"name":"Bahamas","topLevelDomain":[".bs"],"alpha2Code":"BS","alpha3Code":"BHS","callingCodes":["1242"],"capital":"Nassau","altSpellings":["BS","Commonwealth of the Bahamas"],"region":"Americas","subregion":"Caribbean","population":378040,"latlng":[24.25,-76.0],"demonym":"Bahamian","area":13943.0,"gini":null,"timezones":["UTC-05:00"],"borders":[],"nativeName":"Bahamas","numericCode":"044","currencies":[{"code":"BSD","name":"Bahamian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Bahamas","es":"Bahamas","fr":"Bahamas","ja":"バハマ","it":"Bahamas","br":"Bahamas","pt":"Baamas","nl":"Bahama’s","hr":"Bahami","fa":"باهاما"},"flag":"https://restcountries.eu/data/bhs.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"BAH"} -{"name":"Bahrain","topLevelDomain":[".bh"],"alpha2Code":"BH","alpha3Code":"BHR","callingCodes":["973"],"capital":"Manama","altSpellings":["BH","Kingdom of Bahrain","Mamlakat al-Baḥrayn"],"region":"Asia","subregion":"Western Asia","population":1404900,"latlng":[26.0,50.55],"demonym":"Bahraini","area":765.0,"gini":null,"timezones":["UTC+03:00"],"borders":[],"nativeName":"‏البحرين","numericCode":"048","currencies":[{"code":"BHD","name":"Bahraini dinar","symbol":".د.ب"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Bahrain","es":"Bahrein","fr":"Bahreïn","ja":"バーレーン","it":"Bahrein","br":"Bahrein","pt":"Barém","nl":"Bahrein","hr":"Bahrein","fa":"بحرین"},"flag":"https://restcountries.eu/data/bhr.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"BRN"} -{"name":"Bangladesh","topLevelDomain":[".bd"],"alpha2Code":"BD","alpha3Code":"BGD","callingCodes":["880"],"capital":"Dhaka","altSpellings":["BD","People's Republic of Bangladesh","Gônôprôjatôntri Bangladesh"],"region":"Asia","subregion":"Southern Asia","population":161006790,"latlng":[24.0,90.0],"demonym":"Bangladeshi","area":147570.0,"gini":32.1,"timezones":["UTC+06:00"],"borders":["MMR","IND"],"nativeName":"Bangladesh","numericCode":"050","currencies":[{"code":"BDT","name":"Bangladeshi taka","symbol":"৳"}],"languages":[{"iso639_1":"bn","iso639_2":"ben","name":"Bengali","nativeName":"বাংলা"}],"translations":{"de":"Bangladesch","es":"Bangladesh","fr":"Bangladesh","ja":"バングラデシュ","it":"Bangladesh","br":"Bangladesh","pt":"Bangladeche","nl":"Bangladesh","hr":"Bangladeš","fa":"بنگلادش"},"flag":"https://restcountries.eu/data/bgd.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"BAN"} -{"name":"Barbados","topLevelDomain":[".bb"],"alpha2Code":"BB","alpha3Code":"BRB","callingCodes":["1246"],"capital":"Bridgetown","altSpellings":["BB"],"region":"Americas","subregion":"Caribbean","population":285000,"latlng":[13.16666666,-59.53333333],"demonym":"Barbadian","area":430.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Barbados","numericCode":"052","currencies":[{"code":"BBD","name":"Barbadian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Barbados","es":"Barbados","fr":"Barbade","ja":"バルバドス","it":"Barbados","br":"Barbados","pt":"Barbados","nl":"Barbados","hr":"Barbados","fa":"باربادوس"},"flag":"https://restcountries.eu/data/brb.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"BAR"} -{"name":"Belarus","topLevelDomain":[".by"],"alpha2Code":"BY","alpha3Code":"BLR","callingCodes":["375"],"capital":"Minsk","altSpellings":["BY","Bielaruś","Republic of Belarus","Белоруссия","Республика Беларусь","Belorussiya","Respublika Belarus’"],"region":"Europe","subregion":"Eastern Europe","population":9498700,"latlng":[53.0,28.0],"demonym":"Belarusian","area":207600.0,"gini":26.5,"timezones":["UTC+03:00"],"borders":["LVA","LTU","POL","RUS","UKR"],"nativeName":"Белару́сь","numericCode":"112","currencies":[{"code":"BYN","name":"New Belarusian ruble","symbol":"Br"},{"code":"BYR","name":"Old Belarusian ruble","symbol":"Br"}],"languages":[{"iso639_1":"be","iso639_2":"bel","name":"Belarusian","nativeName":"беларуская мова"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Weißrussland","es":"Bielorrusia","fr":"Biélorussie","ja":"ベラルーシ","it":"Bielorussia","br":"Bielorrússia","pt":"Bielorrússia","nl":"Wit-Rusland","hr":"Bjelorusija","fa":"بلاروس"},"flag":"https://restcountries.eu/data/blr.svg","regionalBlocs":[{"acronym":"EEU","name":"Eurasian Economic Union","otherAcronyms":["EAEU"],"otherNames":[]}],"cioc":"BLR"} -{"name":"Belgium","topLevelDomain":[".be"],"alpha2Code":"BE","alpha3Code":"BEL","callingCodes":["32"],"capital":"Brussels","altSpellings":["BE","België","Belgie","Belgien","Belgique","Kingdom of Belgium","Koninkrijk België","Royaume de Belgique","Königreich Belgien"],"region":"Europe","subregion":"Western Europe","population":11319511,"latlng":[50.83333333,4.0],"demonym":"Belgian","area":30528.0,"gini":33.0,"timezones":["UTC+01:00"],"borders":["FRA","DEU","LUX","NLD"],"nativeName":"België","numericCode":"056","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"}],"translations":{"de":"Belgien","es":"Bélgica","fr":"Belgique","ja":"ベルギー","it":"Belgio","br":"Bélgica","pt":"Bélgica","nl":"België","hr":"Belgija","fa":"بلژیک"},"flag":"https://restcountries.eu/data/bel.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"BEL"} -{"name":"Belize","topLevelDomain":[".bz"],"alpha2Code":"BZ","alpha3Code":"BLZ","callingCodes":["501"],"capital":"Belmopan","altSpellings":["BZ"],"region":"Americas","subregion":"Central America","population":370300,"latlng":[17.25,-88.75],"demonym":"Belizean","area":22966.0,"gini":53.1,"timezones":["UTC-06:00"],"borders":["GTM","MEX"],"nativeName":"Belize","numericCode":"084","currencies":[{"code":"BZD","name":"Belize dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Belize","es":"Belice","fr":"Belize","ja":"ベリーズ","it":"Belize","br":"Belize","pt":"Belize","nl":"Belize","hr":"Belize","fa":"بلیز"},"flag":"https://restcountries.eu/data/blz.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]},{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"BIZ"} -{"name":"Benin","topLevelDomain":[".bj"],"alpha2Code":"BJ","alpha3Code":"BEN","callingCodes":["229"],"capital":"Porto-Novo","altSpellings":["BJ","Republic of Benin","République du Bénin"],"region":"Africa","subregion":"Western Africa","population":10653654,"latlng":[9.5,2.25],"demonym":"Beninese","area":112622.0,"gini":38.6,"timezones":["UTC+01:00"],"borders":["BFA","NER","NGA","TGO"],"nativeName":"Bénin","numericCode":"204","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Benin","es":"Benín","fr":"Bénin","ja":"ベナン","it":"Benin","br":"Benin","pt":"Benim","nl":"Benin","hr":"Benin","fa":"بنین"},"flag":"https://restcountries.eu/data/ben.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"BEN"} -{"name":"Bermuda","topLevelDomain":[".bm"],"alpha2Code":"BM","alpha3Code":"BMU","callingCodes":["1441"],"capital":"Hamilton","altSpellings":["BM","The Islands of Bermuda","The Bermudas","Somers Isles"],"region":"Americas","subregion":"Northern America","population":61954,"latlng":[32.33333333,-64.75],"demonym":"Bermudian","area":54.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Bermuda","numericCode":"060","currencies":[{"code":"BMD","name":"Bermudian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Bermuda","es":"Bermudas","fr":"Bermudes","ja":"バミューダ","it":"Bermuda","br":"Bermudas","pt":"Bermudas","nl":"Bermuda","hr":"Bermudi","fa":"برمودا"},"flag":"https://restcountries.eu/data/bmu.svg","regionalBlocs":[],"cioc":"BER"} -{"name":"Bhutan","topLevelDomain":[".bt"],"alpha2Code":"BT","alpha3Code":"BTN","callingCodes":["975"],"capital":"Thimphu","altSpellings":["BT","Kingdom of Bhutan"],"region":"Asia","subregion":"Southern Asia","population":775620,"latlng":[27.5,90.5],"demonym":"Bhutanese","area":38394.0,"gini":38.1,"timezones":["UTC+06:00"],"borders":["CHN","IND"],"nativeName":"ʼbrug-yul","numericCode":"064","currencies":[{"code":"BTN","name":"Bhutanese ngultrum","symbol":"Nu."},{"code":"INR","name":"Indian rupee","symbol":"₹"}],"languages":[{"iso639_1":"dz","iso639_2":"dzo","name":"Dzongkha","nativeName":"རྫོང་ཁ"}],"translations":{"de":"Bhutan","es":"Bután","fr":"Bhoutan","ja":"ブータン","it":"Bhutan","br":"Butão","pt":"Butão","nl":"Bhutan","hr":"Butan","fa":"بوتان"},"flag":"https://restcountries.eu/data/btn.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"BHU"} -{"name":"Bolivia (Plurinational State of)","topLevelDomain":[".bo"],"alpha2Code":"BO","alpha3Code":"BOL","callingCodes":["591"],"capital":"Sucre","altSpellings":["BO","Buliwya","Wuliwya","Plurinational State of Bolivia","Estado Plurinacional de Bolivia","Buliwya Mamallaqta","Wuliwya Suyu","Tetã Volívia"],"region":"Americas","subregion":"South America","population":10985059,"latlng":[-17.0,-65.0],"demonym":"Bolivian","area":1098581.0,"gini":56.3,"timezones":["UTC-04:00"],"borders":["ARG","BRA","CHL","PRY","PER"],"nativeName":"Bolivia","numericCode":"068","currencies":[{"code":"BOB","name":"Bolivian boliviano","symbol":"Bs."}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"},{"iso639_1":"ay","iso639_2":"aym","name":"Aymara","nativeName":"aymar aru"},{"iso639_1":"qu","iso639_2":"que","name":"Quechua","nativeName":"Runa Simi"}],"translations":{"de":"Bolivien","es":"Bolivia","fr":"Bolivie","ja":"ボリビア多民族国","it":"Bolivia","br":"Bolívia","pt":"Bolívia","nl":"Bolivia","hr":"Bolivija","fa":"بولیوی"},"flag":"https://restcountries.eu/data/bol.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"BOL"} -{"name":"Bonaire, Sint Eustatius and Saba","topLevelDomain":[".an",".nl"],"alpha2Code":"BQ","alpha3Code":"BES","callingCodes":["5997"],"capital":"Kralendijk","altSpellings":["BQ","Boneiru"],"region":"Americas","subregion":"Caribbean","population":17408,"latlng":[12.15,-68.266667],"demonym":"Dutch","area":294.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Bonaire","numericCode":"535","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"}],"translations":{"de":"Bonaire, Sint Eustatius und Saba","es":null,"fr":"Bonaire, Saint-Eustache et Saba","ja":null,"it":"Bonaire, Saint-Eustache e Saba","br":"Bonaire","pt":"Bonaire","nl":null,"hr":null,"fa":"بونیر"},"flag":"https://restcountries.eu/data/bes.svg","regionalBlocs":[],"cioc":null} -{"name":"Bosnia and Herzegovina","topLevelDomain":[".ba"],"alpha2Code":"BA","alpha3Code":"BIH","callingCodes":["387"],"capital":"Sarajevo","altSpellings":["BA","Bosnia-Herzegovina","Босна и Херцеговина"],"region":"Europe","subregion":"Southern Europe","population":3531159,"latlng":[44.0,18.0],"demonym":"Bosnian, Herzegovinian","area":51209.0,"gini":36.2,"timezones":["UTC+01:00"],"borders":["HRV","MNE","SRB"],"nativeName":"Bosna i Hercegovina","numericCode":"070","currencies":[{"code":"BAM","name":"Bosnia and Herzegovina convertible mark","symbol":null}],"languages":[{"iso639_1":"bs","iso639_2":"bos","name":"Bosnian","nativeName":"bosanski jezik"},{"iso639_1":"hr","iso639_2":"hrv","name":"Croatian","nativeName":"hrvatski jezik"},{"iso639_1":"sr","iso639_2":"srp","name":"Serbian","nativeName":"српски језик"}],"translations":{"de":"Bosnien und Herzegowina","es":"Bosnia y Herzegovina","fr":"Bosnie-Herzégovine","ja":"ボスニア・ヘルツェゴビナ","it":"Bosnia ed Erzegovina","br":"Bósnia e Herzegovina","pt":"Bósnia e Herzegovina","nl":"Bosnië en Herzegovina","hr":"Bosna i Hercegovina","fa":"بوسنی و هرزگوین"},"flag":"https://restcountries.eu/data/bih.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":"BIH"} -{"name":"Botswana","topLevelDomain":[".bw"],"alpha2Code":"BW","alpha3Code":"BWA","callingCodes":["267"],"capital":"Gaborone","altSpellings":["BW","Republic of Botswana","Lefatshe la Botswana"],"region":"Africa","subregion":"Southern Africa","population":2141206,"latlng":[-22.0,24.0],"demonym":"Motswana","area":582000.0,"gini":61.0,"timezones":["UTC+02:00"],"borders":["NAM","ZAF","ZMB","ZWE"],"nativeName":"Botswana","numericCode":"072","currencies":[{"code":"BWP","name":"Botswana pula","symbol":"P"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"tn","iso639_2":"tsn","name":"Tswana","nativeName":"Setswana"}],"translations":{"de":"Botswana","es":"Botswana","fr":"Botswana","ja":"ボツワナ","it":"Botswana","br":"Botsuana","pt":"Botsuana","nl":"Botswana","hr":"Bocvana","fa":"بوتسوانا"},"flag":"https://restcountries.eu/data/bwa.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"BOT"} -{"name":"Bouvet Island","topLevelDomain":[".bv"],"alpha2Code":"BV","alpha3Code":"BVT","callingCodes":[""],"capital":"","altSpellings":["BV","Bouvetøya","Bouvet-øya"],"region":"","subregion":"","population":0,"latlng":[-54.43333333,3.4],"demonym":"","area":49.0,"gini":null,"timezones":["UTC+01:00"],"borders":[],"nativeName":"Bouvetøya","numericCode":"074","currencies":[{"code":"NOK","name":"Norwegian krone","symbol":"kr"}],"languages":[{"iso639_1":"no","iso639_2":"nor","name":"Norwegian","nativeName":"Norsk"},{"iso639_1":"nb","iso639_2":"nob","name":"Norwegian Bokmål","nativeName":"Norsk bokmål"},{"iso639_1":"nn","iso639_2":"nno","name":"Norwegian Nynorsk","nativeName":"Norsk nynorsk"}],"translations":{"de":"Bouvetinsel","es":"Isla Bouvet","fr":"Île Bouvet","ja":"ブーベ島","it":"Isola Bouvet","br":"Ilha Bouvet","pt":"Ilha Bouvet","nl":"Bouveteiland","hr":"Otok Bouvet","fa":"جزیره بووه"},"flag":"https://restcountries.eu/data/bvt.svg","regionalBlocs":[],"cioc":""} -{"name":"Brazil","topLevelDomain":[".br"],"alpha2Code":"BR","alpha3Code":"BRA","callingCodes":["55"],"capital":"Brasília","altSpellings":["BR","Brasil","Federative Republic of Brazil","República Federativa do Brasil"],"region":"Americas","subregion":"South America","population":206135893,"latlng":[-10.0,-55.0],"demonym":"Brazilian","area":8515767.0,"gini":54.7,"timezones":["UTC-05:00","UTC-04:00","UTC-03:00","UTC-02:00"],"borders":["ARG","BOL","COL","GUF","GUY","PRY","PER","SUR","URY","VEN"],"nativeName":"Brasil","numericCode":"076","currencies":[{"code":"BRL","name":"Brazilian real","symbol":"R$"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Brasilien","es":"Brasil","fr":"Brésil","ja":"ブラジル","it":"Brasile","br":"Brasil","pt":"Brasil","nl":"Brazilië","hr":"Brazil","fa":"برزیل"},"flag":"https://restcountries.eu/data/bra.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"BRA"} -{"name":"British Indian Ocean Territory","topLevelDomain":[".io"],"alpha2Code":"IO","alpha3Code":"IOT","callingCodes":["246"],"capital":"Diego Garcia","altSpellings":["IO"],"region":"Africa","subregion":"Eastern Africa","population":3000,"latlng":[-6.0,71.5],"demonym":"Indian","area":60.0,"gini":null,"timezones":["UTC+06:00"],"borders":[],"nativeName":"British Indian Ocean Territory","numericCode":"086","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Britisches Territorium im Indischen Ozean","es":"Territorio Británico del Océano Índico","fr":"Territoire britannique de l'océan Indien","ja":"イギリス領インド洋地域","it":"Territorio britannico dell'oceano indiano","br":"Território Britânico do Oceano íÍdico","pt":"Território Britânico do Oceano Índico","nl":"Britse Gebieden in de Indische Oceaan","hr":"Britanski Indijskooceanski teritorij","fa":"قلمرو بریتانیا در اقیانوس هند"},"flag":"https://restcountries.eu/data/iot.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":""} -{"name":"United States Minor Outlying Islands","topLevelDomain":[".us"],"alpha2Code":"UM","alpha3Code":"UMI","callingCodes":[""],"capital":"","altSpellings":["UM"],"region":"Americas","subregion":"Northern America","population":300,"latlng":[],"demonym":"American","area":null,"gini":null,"timezones":["UTC-11:00","UTC-10:00","UTC+12:00"],"borders":[],"nativeName":"United States Minor Outlying Islands","numericCode":"581","currencies":[{"code":"USD","name":"United States Dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Kleinere Inselbesitzungen der Vereinigten Staaten","es":"Islas Ultramarinas Menores de Estados Unidos","fr":"Îles mineures éloignées des États-Unis","ja":"合衆国領有小離島","it":"Isole minori esterne degli Stati Uniti d'America","br":"Ilhas Menores Distantes dos Estados Unidos","pt":"Ilhas Menores Distantes dos Estados Unidos","nl":"Kleine afgelegen eilanden van de Verenigde Staten","hr":"Mali udaljeni otoci SAD-a","fa":"جزایر کوچک حاشیه‌ای ایالات متحده آمریکا"},"flag":"https://restcountries.eu/data/umi.svg","regionalBlocs":[],"cioc":""} -{"name":"Virgin Islands (British)","topLevelDomain":[".vg"],"alpha2Code":"VG","alpha3Code":"VGB","callingCodes":["1284"],"capital":"Road Town","altSpellings":["VG"],"region":"Americas","subregion":"Caribbean","population":28514,"latlng":[18.431383,-64.62305],"demonym":"Virgin Islander","area":151.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"British Virgin Islands","numericCode":"092","currencies":[{"code":null,"name":"[D]","symbol":"$"},{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Britische Jungferninseln","es":"Islas Vírgenes del Reino Unido","fr":"Îles Vierges britanniques","ja":"イギリス領ヴァージン諸島","it":"Isole Vergini Britanniche","br":"Ilhas Virgens Britânicas","pt":"Ilhas Virgens Britânicas","nl":"Britse Maagdeneilanden","hr":"Britanski Djevičanski Otoci","fa":"جزایر ویرجین بریتانیا"},"flag":"https://restcountries.eu/data/vgb.svg","regionalBlocs":[],"cioc":"IVB"} -{"name":"Virgin Islands (U.S.)","topLevelDomain":[".vi"],"alpha2Code":"VI","alpha3Code":"VIR","callingCodes":["1 340"],"capital":"Charlotte Amalie","altSpellings":["VI","USVI","American Virgin Islands","U.S. Virgin Islands"],"region":"Americas","subregion":"Caribbean","population":114743,"latlng":[18.34,-64.93],"demonym":"Virgin Islander","area":346.36,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Virgin Islands of the United States","numericCode":"850","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Amerikanische Jungferninseln","es":"Islas Vírgenes de los Estados Unidos","fr":"Îles Vierges des États-Unis","ja":"アメリカ領ヴァージン諸島","it":"Isole Vergini americane","br":"Ilhas Virgens Americanas","pt":"Ilhas Virgens Americanas","nl":"Verenigde Staten Maagdeneilanden","hr":null,"fa":"جزایر ویرجین آمریکا"},"flag":"https://restcountries.eu/data/vir.svg","regionalBlocs":[],"cioc":"ISV"} -{"name":"Brunei Darussalam","topLevelDomain":[".bn"],"alpha2Code":"BN","alpha3Code":"BRN","callingCodes":["673"],"capital":"Bandar Seri Begawan","altSpellings":["BN","Nation of Brunei"," the Abode of Peace"],"region":"Asia","subregion":"South-Eastern Asia","population":411900,"latlng":[4.5,114.66666666],"demonym":"Bruneian","area":5765.0,"gini":null,"timezones":["UTC+08:00"],"borders":["MYS"],"nativeName":"Negara Brunei Darussalam","numericCode":"096","currencies":[{"code":"BND","name":"Brunei dollar","symbol":"$"},{"code":"SGD","name":"Singapore dollar","symbol":"$"}],"languages":[{"iso639_1":"ms","iso639_2":"msa","name":"Malay","nativeName":"bahasa Melayu"}],"translations":{"de":"Brunei","es":"Brunei","fr":"Brunei","ja":"ブルネイ・ダルサラーム","it":"Brunei","br":"Brunei","pt":"Brunei","nl":"Brunei","hr":"Brunej","fa":"برونئی"},"flag":"https://restcountries.eu/data/brn.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"BRU"} -{"name":"Bulgaria","topLevelDomain":[".bg"],"alpha2Code":"BG","alpha3Code":"BGR","callingCodes":["359"],"capital":"Sofia","altSpellings":["BG","Republic of Bulgaria","Република България"],"region":"Europe","subregion":"Eastern Europe","population":7153784,"latlng":[43.0,25.0],"demonym":"Bulgarian","area":110879.0,"gini":28.2,"timezones":["UTC+02:00"],"borders":["GRC","MKD","ROU","SRB","TUR"],"nativeName":"България","numericCode":"100","currencies":[{"code":"BGN","name":"Bulgarian lev","symbol":"лв"}],"languages":[{"iso639_1":"bg","iso639_2":"bul","name":"Bulgarian","nativeName":"български език"}],"translations":{"de":"Bulgarien","es":"Bulgaria","fr":"Bulgarie","ja":"ブルガリア","it":"Bulgaria","br":"Bulgária","pt":"Bulgária","nl":"Bulgarije","hr":"Bugarska","fa":"بلغارستان"},"flag":"https://restcountries.eu/data/bgr.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"BUL"} -{"name":"Burkina Faso","topLevelDomain":[".bf"],"alpha2Code":"BF","alpha3Code":"BFA","callingCodes":["226"],"capital":"Ouagadougou","altSpellings":["BF"],"region":"Africa","subregion":"Western Africa","population":19034397,"latlng":[13.0,-2.0],"demonym":"Burkinabe","area":272967.0,"gini":39.8,"timezones":["UTC"],"borders":["BEN","CIV","GHA","MLI","NER","TGO"],"nativeName":"Burkina Faso","numericCode":"854","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ff","iso639_2":"ful","name":"Fula","nativeName":"Fulfulde"}],"translations":{"de":"Burkina Faso","es":"Burkina Faso","fr":"Burkina Faso","ja":"ブルキナファソ","it":"Burkina Faso","br":"Burkina Faso","pt":"Burquina Faso","nl":"Burkina Faso","hr":"Burkina Faso","fa":"بورکینافاسو"},"flag":"https://restcountries.eu/data/bfa.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"BUR"} -{"name":"Burundi","topLevelDomain":[".bi"],"alpha2Code":"BI","alpha3Code":"BDI","callingCodes":["257"],"capital":"Bujumbura","altSpellings":["BI","Republic of Burundi","Republika y'Uburundi","République du Burundi"],"region":"Africa","subregion":"Eastern Africa","population":10114505,"latlng":[-3.5,30.0],"demonym":"Burundian","area":27834.0,"gini":33.3,"timezones":["UTC+02:00"],"borders":["COD","RWA","TZA"],"nativeName":"Burundi","numericCode":"108","currencies":[{"code":"BIF","name":"Burundian franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"rn","iso639_2":"run","name":"Kirundi","nativeName":"Ikirundi"}],"translations":{"de":"Burundi","es":"Burundi","fr":"Burundi","ja":"ブルンジ","it":"Burundi","br":"Burundi","pt":"Burúndi","nl":"Burundi","hr":"Burundi","fa":"بوروندی"},"flag":"https://restcountries.eu/data/bdi.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"BDI"} -{"name":"Cambodia","topLevelDomain":[".kh"],"alpha2Code":"KH","alpha3Code":"KHM","callingCodes":["855"],"capital":"Phnom Penh","altSpellings":["KH","Kingdom of Cambodia"],"region":"Asia","subregion":"South-Eastern Asia","population":15626444,"latlng":[13.0,105.0],"demonym":"Cambodian","area":181035.0,"gini":37.9,"timezones":["UTC+07:00"],"borders":["LAO","THA","VNM"],"nativeName":"Kâmpŭchéa","numericCode":"116","currencies":[{"code":"KHR","name":"Cambodian riel","symbol":"៛"},{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"km","iso639_2":"khm","name":"Khmer","nativeName":"ខ្មែរ"}],"translations":{"de":"Kambodscha","es":"Camboya","fr":"Cambodge","ja":"カンボジア","it":"Cambogia","br":"Camboja","pt":"Camboja","nl":"Cambodja","hr":"Kambodža","fa":"کامبوج"},"flag":"https://restcountries.eu/data/khm.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"CAM"} -{"name":"Cameroon","topLevelDomain":[".cm"],"alpha2Code":"CM","alpha3Code":"CMR","callingCodes":["237"],"capital":"Yaoundé","altSpellings":["CM","Republic of Cameroon","République du Cameroun"],"region":"Africa","subregion":"Middle Africa","population":22709892,"latlng":[6.0,12.0],"demonym":"Cameroonian","area":475442.0,"gini":38.9,"timezones":["UTC+01:00"],"borders":["CAF","TCD","COG","GNQ","GAB","NGA"],"nativeName":"Cameroon","numericCode":"120","currencies":[{"code":"XAF","name":"Central African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Kamerun","es":"Camerún","fr":"Cameroun","ja":"カメルーン","it":"Camerun","br":"Camarões","pt":"Camarões","nl":"Kameroen","hr":"Kamerun","fa":"کامرون"},"flag":"https://restcountries.eu/data/cmr.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"CMR"} -{"name":"Canada","topLevelDomain":[".ca"],"alpha2Code":"CA","alpha3Code":"CAN","callingCodes":["1"],"capital":"Ottawa","altSpellings":["CA"],"region":"Americas","subregion":"Northern America","population":36155487,"latlng":[60.0,-95.0],"demonym":"Canadian","area":9984670.0,"gini":32.6,"timezones":["UTC-08:00","UTC-07:00","UTC-06:00","UTC-05:00","UTC-04:00","UTC-03:30"],"borders":["USA"],"nativeName":"Canada","numericCode":"124","currencies":[{"code":"CAD","name":"Canadian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Kanada","es":"Canadá","fr":"Canada","ja":"カナダ","it":"Canada","br":"Canadá","pt":"Canadá","nl":"Canada","hr":"Kanada","fa":"کانادا"},"flag":"https://restcountries.eu/data/can.svg","regionalBlocs":[{"acronym":"NAFTA","name":"North American Free Trade Agreement","otherAcronyms":[],"otherNames":["Tratado de Libre Comercio de América del Norte","Accord de Libre-échange Nord-Américain"]}],"cioc":"CAN"} -{"name":"Cabo Verde","topLevelDomain":[".cv"],"alpha2Code":"CV","alpha3Code":"CPV","callingCodes":["238"],"capital":"Praia","altSpellings":["CV","Republic of Cabo Verde","República de Cabo Verde"],"region":"Africa","subregion":"Western Africa","population":531239,"latlng":[16.0,-24.0],"demonym":"Cape Verdian","area":4033.0,"gini":50.5,"timezones":["UTC-01:00"],"borders":[],"nativeName":"Cabo Verde","numericCode":"132","currencies":[{"code":"CVE","name":"Cape Verdean escudo","symbol":"Esc"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Kap Verde","es":"Cabo Verde","fr":"Cap Vert","ja":"カーボベルデ","it":"Capo Verde","br":"Cabo Verde","pt":"Cabo Verde","nl":"Kaapverdië","hr":"Zelenortska Republika","fa":"کیپ ورد"},"flag":"https://restcountries.eu/data/cpv.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"CPV"} -{"name":"Cayman Islands","topLevelDomain":[".ky"],"alpha2Code":"KY","alpha3Code":"CYM","callingCodes":["1345"],"capital":"George Town","altSpellings":["KY"],"region":"Americas","subregion":"Caribbean","population":58238,"latlng":[19.5,-80.5],"demonym":"Caymanian","area":264.0,"gini":null,"timezones":["UTC-05:00"],"borders":[],"nativeName":"Cayman Islands","numericCode":"136","currencies":[{"code":"KYD","name":"Cayman Islands dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Kaimaninseln","es":"Islas Caimán","fr":"Îles Caïmans","ja":"ケイマン諸島","it":"Isole Cayman","br":"Ilhas Cayman","pt":"Ilhas Caimão","nl":"Caymaneilanden","hr":"Kajmanski otoci","fa":"جزایر کیمن"},"flag":"https://restcountries.eu/data/cym.svg","regionalBlocs":[],"cioc":"CAY"} -{"name":"Central African Republic","topLevelDomain":[".cf"],"alpha2Code":"CF","alpha3Code":"CAF","callingCodes":["236"],"capital":"Bangui","altSpellings":["CF","Central African Republic","République centrafricaine"],"region":"Africa","subregion":"Middle Africa","population":4998000,"latlng":[7.0,21.0],"demonym":"Central African","area":622984.0,"gini":56.3,"timezones":["UTC+01:00"],"borders":["CMR","TCD","COD","COG","SSD","SDN"],"nativeName":"Ködörösêse tî Bêafrîka","numericCode":"140","currencies":[{"code":"XAF","name":"Central African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"sg","iso639_2":"sag","name":"Sango","nativeName":"yângâ tî sängö"}],"translations":{"de":"Zentralafrikanische Republik","es":"República Centroafricana","fr":"République centrafricaine","ja":"中央アフリカ共和国","it":"Repubblica Centrafricana","br":"República Centro-Africana","pt":"República Centro-Africana","nl":"Centraal-Afrikaanse Republiek","hr":"Srednjoafrička Republika","fa":"جمهوری آفریقای مرکزی"},"flag":"https://restcountries.eu/data/caf.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"CAF"} -{"name":"Chad","topLevelDomain":[".td"],"alpha2Code":"TD","alpha3Code":"TCD","callingCodes":["235"],"capital":"N'Djamena","altSpellings":["TD","Tchad","Republic of Chad","République du Tchad"],"region":"Africa","subregion":"Middle Africa","population":14497000,"latlng":[15.0,19.0],"demonym":"Chadian","area":1284000.0,"gini":39.8,"timezones":["UTC+01:00"],"borders":["CMR","CAF","LBY","NER","NGA","SSD"],"nativeName":"Tchad","numericCode":"148","currencies":[{"code":"XAF","name":"Central African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Tschad","es":"Chad","fr":"Tchad","ja":"チャド","it":"Ciad","br":"Chade","pt":"Chade","nl":"Tsjaad","hr":"Čad","fa":"چاد"},"flag":"https://restcountries.eu/data/tcd.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"CHA"} -{"name":"Chile","topLevelDomain":[".cl"],"alpha2Code":"CL","alpha3Code":"CHL","callingCodes":["56"],"capital":"Santiago","altSpellings":["CL","Republic of Chile","República de Chile"],"region":"Americas","subregion":"South America","population":18191900,"latlng":[-30.0,-71.0],"demonym":"Chilean","area":756102.0,"gini":52.1,"timezones":["UTC-06:00","UTC-04:00"],"borders":["ARG","BOL","PER"],"nativeName":"Chile","numericCode":"152","currencies":[{"code":"CLP","name":"Chilean peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Chile","es":"Chile","fr":"Chili","ja":"チリ","it":"Cile","br":"Chile","pt":"Chile","nl":"Chili","hr":"Čile","fa":"شیلی"},"flag":"https://restcountries.eu/data/chl.svg","regionalBlocs":[{"acronym":"PA","name":"Pacific Alliance","otherAcronyms":[],"otherNames":["Alianza del Pacífico"]},{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"CHI"} -{"name":"China","topLevelDomain":[".cn"],"alpha2Code":"CN","alpha3Code":"CHN","callingCodes":["86"],"capital":"Beijing","altSpellings":["CN","Zhōngguó","Zhongguo","Zhonghua","People's Republic of China","中华人民共和国","Zhōnghuá Rénmín Gònghéguó"],"region":"Asia","subregion":"Eastern Asia","population":1377422166,"latlng":[35.0,105.0],"demonym":"Chinese","area":9640011.0,"gini":47.0,"timezones":["UTC+08:00"],"borders":["AFG","BTN","MMR","HKG","IND","KAZ","PRK","KGZ","LAO","MAC","MNG","PAK","RUS","TJK","VNM"],"nativeName":"中国","numericCode":"156","currencies":[{"code":"CNY","name":"Chinese yuan","symbol":"¥"}],"languages":[{"iso639_1":"zh","iso639_2":"zho","name":"Chinese","nativeName":"中文 (Zhōngwén)"}],"translations":{"de":"China","es":"China","fr":"Chine","ja":"中国","it":"Cina","br":"China","pt":"China","nl":"China","hr":"Kina","fa":"چین"},"flag":"https://restcountries.eu/data/chn.svg","regionalBlocs":[],"cioc":"CHN"} -{"name":"Christmas Island","topLevelDomain":[".cx"],"alpha2Code":"CX","alpha3Code":"CXR","callingCodes":["61"],"capital":"Flying Fish Cove","altSpellings":["CX","Territory of Christmas Island"],"region":"Oceania","subregion":"Australia and New Zealand","population":2072,"latlng":[-10.5,105.66666666],"demonym":"Christmas Island","area":135.0,"gini":null,"timezones":["UTC+07:00"],"borders":[],"nativeName":"Christmas Island","numericCode":"162","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Weihnachtsinsel","es":"Isla de Navidad","fr":"Île Christmas","ja":"クリスマス島","it":"Isola di Natale","br":"Ilha Christmas","pt":"Ilha do Natal","nl":"Christmaseiland","hr":"Božićni otok","fa":"جزیره کریسمس"},"flag":"https://restcountries.eu/data/cxr.svg","regionalBlocs":[],"cioc":""} -{"name":"Cocos (Keeling) Islands","topLevelDomain":[".cc"],"alpha2Code":"CC","alpha3Code":"CCK","callingCodes":["61"],"capital":"West Island","altSpellings":["CC","Territory of the Cocos (Keeling) Islands","Keeling Islands"],"region":"Oceania","subregion":"Australia and New Zealand","population":550,"latlng":[-12.5,96.83333333],"demonym":"Cocos Islander","area":14.0,"gini":null,"timezones":["UTC+06:30"],"borders":[],"nativeName":"Cocos (Keeling) Islands","numericCode":"166","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Kokosinseln","es":"Islas Cocos o Islas Keeling","fr":"Îles Cocos","ja":"ココス(キーリング)諸島","it":"Isole Cocos e Keeling","br":"Ilhas Cocos","pt":"Ilhas dos Cocos","nl":"Cocoseilanden","hr":"Kokosovi Otoci","fa":"جزایر کوکوس"},"flag":"https://restcountries.eu/data/cck.svg","regionalBlocs":[],"cioc":""} -{"name":"Colombia","topLevelDomain":[".co"],"alpha2Code":"CO","alpha3Code":"COL","callingCodes":["57"],"capital":"Bogotá","altSpellings":["CO","Republic of Colombia","República de Colombia"],"region":"Americas","subregion":"South America","population":48759958,"latlng":[4.0,-72.0],"demonym":"Colombian","area":1141748.0,"gini":55.9,"timezones":["UTC-05:00"],"borders":["BRA","ECU","PAN","PER","VEN"],"nativeName":"Colombia","numericCode":"170","currencies":[{"code":"COP","name":"Colombian peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Kolumbien","es":"Colombia","fr":"Colombie","ja":"コロンビア","it":"Colombia","br":"Colômbia","pt":"Colômbia","nl":"Colombia","hr":"Kolumbija","fa":"کلمبیا"},"flag":"https://restcountries.eu/data/col.svg","regionalBlocs":[{"acronym":"PA","name":"Pacific Alliance","otherAcronyms":[],"otherNames":["Alianza del Pacífico"]},{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"COL"} -{"name":"Comoros","topLevelDomain":[".km"],"alpha2Code":"KM","alpha3Code":"COM","callingCodes":["269"],"capital":"Moroni","altSpellings":["KM","Union of the Comoros","Union des Comores","Udzima wa Komori","al-Ittiḥād al-Qumurī"],"region":"Africa","subregion":"Eastern Africa","population":806153,"latlng":[-12.16666666,44.25],"demonym":"Comoran","area":1862.0,"gini":64.3,"timezones":["UTC+03:00"],"borders":[],"nativeName":"Komori","numericCode":"174","currencies":[{"code":"KMF","name":"Comorian franc","symbol":"Fr"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Union der Komoren","es":"Comoras","fr":"Comores","ja":"コモロ","it":"Comore","br":"Comores","pt":"Comores","nl":"Comoren","hr":"Komori","fa":"کومور"},"flag":"https://restcountries.eu/data/com.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"COM"} -{"name":"Congo","topLevelDomain":[".cg"],"alpha2Code":"CG","alpha3Code":"COG","callingCodes":["242"],"capital":"Brazzaville","altSpellings":["CG","Congo-Brazzaville"],"region":"Africa","subregion":"Middle Africa","population":4741000,"latlng":[-1.0,15.0],"demonym":"Congolese","area":342000.0,"gini":47.3,"timezones":["UTC+01:00"],"borders":["AGO","CMR","CAF","COD","GAB"],"nativeName":"République du Congo","numericCode":"178","currencies":[{"code":"XAF","name":"Central African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ln","iso639_2":"lin","name":"Lingala","nativeName":"Lingála"}],"translations":{"de":"Kongo","es":"Congo","fr":"Congo","ja":"コンゴ共和国","it":"Congo","br":"Congo","pt":"Congo","nl":"Congo [Republiek]","hr":"Kongo","fa":"کنگو"},"flag":"https://restcountries.eu/data/cog.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"CGO"} -{"name":"Congo (Democratic Republic of the)","topLevelDomain":[".cd"],"alpha2Code":"CD","alpha3Code":"COD","callingCodes":["243"],"capital":"Kinshasa","altSpellings":["CD","DR Congo","Congo-Kinshasa","DRC"],"region":"Africa","subregion":"Middle Africa","population":85026000,"latlng":[0.0,25.0],"demonym":"Congolese","area":2344858.0,"gini":null,"timezones":["UTC+01:00","UTC+02:00"],"borders":["AGO","BDI","CAF","COG","RWA","SSD","TZA","UGA","ZMB"],"nativeName":"République démocratique du Congo","numericCode":"180","currencies":[{"code":"CDF","name":"Congolese franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ln","iso639_2":"lin","name":"Lingala","nativeName":"Lingála"},{"iso639_1":"kg","iso639_2":"kon","name":"Kongo","nativeName":"Kikongo"},{"iso639_1":"sw","iso639_2":"swa","name":"Swahili","nativeName":"Kiswahili"},{"iso639_1":"lu","iso639_2":"lub","name":"Luba-Katanga","nativeName":"Tshiluba"}],"translations":{"de":"Kongo (Dem. Rep.)","es":"Congo (Rep. Dem.)","fr":"Congo (Rép. dém.)","ja":"コンゴ民主共和国","it":"Congo (Rep. Dem.)","br":"RD Congo","pt":"RD Congo","nl":"Congo [DRC]","hr":"Kongo, Demokratska Republika","fa":"جمهوری کنگو"},"flag":"https://restcountries.eu/data/cod.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"COD"} -{"name":"Cook Islands","topLevelDomain":[".ck"],"alpha2Code":"CK","alpha3Code":"COK","callingCodes":["682"],"capital":"Avarua","altSpellings":["CK","Kūki 'Āirani"],"region":"Oceania","subregion":"Polynesia","population":18100,"latlng":[-21.23333333,-159.76666666],"demonym":"Cook Islander","area":236.0,"gini":null,"timezones":["UTC-10:00"],"borders":[],"nativeName":"Cook Islands","numericCode":"184","currencies":[{"code":"NZD","name":"New Zealand dollar","symbol":"$"},{"code":"CKD","name":"Cook Islands dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Cookinseln","es":"Islas Cook","fr":"Îles Cook","ja":"クック諸島","it":"Isole Cook","br":"Ilhas Cook","pt":"Ilhas Cook","nl":"Cookeilanden","hr":"Cookovo Otočje","fa":"جزایر کوک"},"flag":"https://restcountries.eu/data/cok.svg","regionalBlocs":[],"cioc":"COK"} -{"name":"Costa Rica","topLevelDomain":[".cr"],"alpha2Code":"CR","alpha3Code":"CRI","callingCodes":["506"],"capital":"San José","altSpellings":["CR","Republic of Costa Rica","República de Costa Rica"],"region":"Americas","subregion":"Central America","population":4890379,"latlng":[10.0,-84.0],"demonym":"Costa Rican","area":51100.0,"gini":50.7,"timezones":["UTC-06:00"],"borders":["NIC","PAN"],"nativeName":"Costa Rica","numericCode":"188","currencies":[{"code":"CRC","name":"Costa Rican colón","symbol":"₡"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Costa Rica","es":"Costa Rica","fr":"Costa Rica","ja":"コスタリカ","it":"Costa Rica","br":"Costa Rica","pt":"Costa Rica","nl":"Costa Rica","hr":"Kostarika","fa":"کاستاریکا"},"flag":"https://restcountries.eu/data/cri.svg","regionalBlocs":[{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"CRC"} -{"name":"Croatia","topLevelDomain":[".hr"],"alpha2Code":"HR","alpha3Code":"HRV","callingCodes":["385"],"capital":"Zagreb","altSpellings":["HR","Hrvatska","Republic of Croatia","Republika Hrvatska"],"region":"Europe","subregion":"Southern Europe","population":4190669,"latlng":[45.16666666,15.5],"demonym":"Croatian","area":56594.0,"gini":33.7,"timezones":["UTC+01:00"],"borders":["BIH","HUN","MNE","SRB","SVN"],"nativeName":"Hrvatska","numericCode":"191","currencies":[{"code":"HRK","name":"Croatian kuna","symbol":"kn"}],"languages":[{"iso639_1":"hr","iso639_2":"hrv","name":"Croatian","nativeName":"hrvatski jezik"}],"translations":{"de":"Kroatien","es":"Croacia","fr":"Croatie","ja":"クロアチア","it":"Croazia","br":"Croácia","pt":"Croácia","nl":"Kroatië","hr":"Hrvatska","fa":"کرواسی"},"flag":"https://restcountries.eu/data/hrv.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"CRO"} -{"name":"Cuba","topLevelDomain":[".cu"],"alpha2Code":"CU","alpha3Code":"CUB","callingCodes":["53"],"capital":"Havana","altSpellings":["CU","Republic of Cuba","República de Cuba"],"region":"Americas","subregion":"Caribbean","population":11239004,"latlng":[21.5,-80.0],"demonym":"Cuban","area":109884.0,"gini":null,"timezones":["UTC-05:00"],"borders":[],"nativeName":"Cuba","numericCode":"192","currencies":[{"code":"CUC","name":"Cuban convertible peso","symbol":"$"},{"code":"CUP","name":"Cuban peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Kuba","es":"Cuba","fr":"Cuba","ja":"キューバ","it":"Cuba","br":"Cuba","pt":"Cuba","nl":"Cuba","hr":"Kuba","fa":"کوبا"},"flag":"https://restcountries.eu/data/cub.svg","regionalBlocs":[],"cioc":"CUB"} -{"name":"Curaçao","topLevelDomain":[".cw"],"alpha2Code":"CW","alpha3Code":"CUW","callingCodes":["599"],"capital":"Willemstad","altSpellings":["CW","Curacao","Kòrsou","Country of Curaçao","Land Curaçao","Pais Kòrsou"],"region":"Americas","subregion":"Caribbean","population":154843,"latlng":[12.116667,-68.933333],"demonym":"Dutch","area":444.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Curaçao","numericCode":"531","currencies":[{"code":"ANG","name":"Netherlands Antillean guilder","symbol":"ƒ"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"},{"iso639_1":"pa","iso639_2":"pan","name":"(Eastern) Punjabi","nativeName":"ਪੰਜਾਬੀ"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Curaçao","es":null,"fr":"Curaçao","ja":null,"it":"Curaçao","br":"Curaçao","pt":"Curaçao","nl":"Curaçao","hr":null,"fa":"کوراسائو"},"flag":"https://restcountries.eu/data/cuw.svg","regionalBlocs":[],"cioc":""} -{"name":"Cyprus","topLevelDomain":[".cy"],"alpha2Code":"CY","alpha3Code":"CYP","callingCodes":["357"],"capital":"Nicosia","altSpellings":["CY","Kýpros","Kıbrıs","Republic of Cyprus","Κυπριακή Δημοκρατία","Kıbrıs Cumhuriyeti"],"region":"Europe","subregion":"Southern Europe","population":847000,"latlng":[35.0,33.0],"demonym":"Cypriot","area":9251.0,"gini":null,"timezones":["UTC+02:00"],"borders":["GBR"],"nativeName":"Κύπρος","numericCode":"196","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"el","iso639_2":"ell","name":"Greek (modern)","nativeName":"ελληνικά"},{"iso639_1":"tr","iso639_2":"tur","name":"Turkish","nativeName":"Türkçe"},{"iso639_1":"hy","iso639_2":"hye","name":"Armenian","nativeName":"Հայերեն"}],"translations":{"de":"Zypern","es":"Chipre","fr":"Chypre","ja":"キプロス","it":"Cipro","br":"Chipre","pt":"Chipre","nl":"Cyprus","hr":"Cipar","fa":"قبرس"},"flag":"https://restcountries.eu/data/cyp.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"CYP"} -{"name":"Czech Republic","topLevelDomain":[".cz"],"alpha2Code":"CZ","alpha3Code":"CZE","callingCodes":["420"],"capital":"Prague","altSpellings":["CZ","Česká republika","Česko"],"region":"Europe","subregion":"Eastern Europe","population":10558524,"latlng":[49.75,15.5],"demonym":"Czech","area":78865.0,"gini":26.0,"timezones":["UTC+01:00"],"borders":["AUT","DEU","POL","SVK"],"nativeName":"Česká republika","numericCode":"203","currencies":[{"code":"CZK","name":"Czech koruna","symbol":"Kč"}],"languages":[{"iso639_1":"cs","iso639_2":"ces","name":"Czech","nativeName":"čeština"},{"iso639_1":"sk","iso639_2":"slk","name":"Slovak","nativeName":"slovenčina"}],"translations":{"de":"Tschechische Republik","es":"República Checa","fr":"République tchèque","ja":"チェコ","it":"Repubblica Ceca","br":"República Tcheca","pt":"República Checa","nl":"Tsjechië","hr":"Češka","fa":"جمهوری چک"},"flag":"https://restcountries.eu/data/cze.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"CZE"} -{"name":"Denmark","topLevelDomain":[".dk"],"alpha2Code":"DK","alpha3Code":"DNK","callingCodes":["45"],"capital":"Copenhagen","altSpellings":["DK","Danmark","Kingdom of Denmark","Kongeriget Danmark"],"region":"Europe","subregion":"Northern Europe","population":5717014,"latlng":[56.0,10.0],"demonym":"Danish","area":43094.0,"gini":24.0,"timezones":["UTC-04:00","UTC-03:00","UTC-01:00","UTC","UTC+01:00"],"borders":["DEU"],"nativeName":"Danmark","numericCode":"208","currencies":[{"code":"DKK","name":"Danish krone","symbol":"kr"}],"languages":[{"iso639_1":"da","iso639_2":"dan","name":"Danish","nativeName":"dansk"}],"translations":{"de":"Dänemark","es":"Dinamarca","fr":"Danemark","ja":"デンマーク","it":"Danimarca","br":"Dinamarca","pt":"Dinamarca","nl":"Denemarken","hr":"Danska","fa":"دانمارک"},"flag":"https://restcountries.eu/data/dnk.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"DEN"} -{"name":"Djibouti","topLevelDomain":[".dj"],"alpha2Code":"DJ","alpha3Code":"DJI","callingCodes":["253"],"capital":"Djibouti","altSpellings":["DJ","Jabuuti","Gabuuti","Republic of Djibouti","République de Djibouti","Gabuutih Ummuuno","Jamhuuriyadda Jabuuti"],"region":"Africa","subregion":"Eastern Africa","population":900000,"latlng":[11.5,43.0],"demonym":"Djibouti","area":23200.0,"gini":40.0,"timezones":["UTC+03:00"],"borders":["ERI","ETH","SOM"],"nativeName":"Djibouti","numericCode":"262","currencies":[{"code":"DJF","name":"Djiboutian franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Dschibuti","es":"Yibuti","fr":"Djibouti","ja":"ジブチ","it":"Gibuti","br":"Djibuti","pt":"Djibuti","nl":"Djibouti","hr":"Džibuti","fa":"جیبوتی"},"flag":"https://restcountries.eu/data/dji.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"DJI"} -{"name":"Dominica","topLevelDomain":[".dm"],"alpha2Code":"DM","alpha3Code":"DMA","callingCodes":["1767"],"capital":"Roseau","altSpellings":["DM","Dominique","Wai‘tu kubuli","Commonwealth of Dominica"],"region":"Americas","subregion":"Caribbean","population":71293,"latlng":[15.41666666,-61.33333333],"demonym":"Dominican","area":751.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Dominica","numericCode":"212","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Dominica","es":"Dominica","fr":"Dominique","ja":"ドミニカ国","it":"Dominica","br":"Dominica","pt":"Dominica","nl":"Dominica","hr":"Dominika","fa":"دومینیکا"},"flag":"https://restcountries.eu/data/dma.svg","regionalBlocs":[],"cioc":"DMA"} -{"name":"Dominican Republic","topLevelDomain":[".do"],"alpha2Code":"DO","alpha3Code":"DOM","callingCodes":["1809","1829","1849"],"capital":"Santo Domingo","altSpellings":["DO"],"region":"Americas","subregion":"Caribbean","population":10075045,"latlng":[19.0,-70.66666666],"demonym":"Dominican","area":48671.0,"gini":47.2,"timezones":["UTC-04:00"],"borders":["HTI"],"nativeName":"República Dominicana","numericCode":"214","currencies":[{"code":"DOP","name":"Dominican peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Dominikanische Republik","es":"República Dominicana","fr":"République dominicaine","ja":"ドミニカ共和国","it":"Repubblica Dominicana","br":"República Dominicana","pt":"República Dominicana","nl":"Dominicaanse Republiek","hr":"Dominikanska Republika","fa":"جمهوری دومینیکن"},"flag":"https://restcountries.eu/data/dom.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]},{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"DOM"} -{"name":"Ecuador","topLevelDomain":[".ec"],"alpha2Code":"EC","alpha3Code":"ECU","callingCodes":["593"],"capital":"Quito","altSpellings":["EC","Republic of Ecuador","República del Ecuador"],"region":"Americas","subregion":"South America","population":16545799,"latlng":[-2.0,-77.5],"demonym":"Ecuadorean","area":276841.0,"gini":49.3,"timezones":["UTC-06:00","UTC-05:00"],"borders":["COL","PER"],"nativeName":"Ecuador","numericCode":"218","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Ecuador","es":"Ecuador","fr":"Équateur","ja":"エクアドル","it":"Ecuador","br":"Equador","pt":"Equador","nl":"Ecuador","hr":"Ekvador","fa":"اکوادور"},"flag":"https://restcountries.eu/data/ecu.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"ECU"} -{"name":"Egypt","topLevelDomain":[".eg"],"alpha2Code":"EG","alpha3Code":"EGY","callingCodes":["20"],"capital":"Cairo","altSpellings":["EG","Arab Republic of Egypt"],"region":"Africa","subregion":"Northern Africa","population":91290000,"latlng":[27.0,30.0],"demonym":"Egyptian","area":1002450.0,"gini":30.8,"timezones":["UTC+02:00"],"borders":["ISR","LBY","SDN"],"nativeName":"مصر‎","numericCode":"818","currencies":[{"code":"EGP","name":"Egyptian pound","symbol":"£"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Ägypten","es":"Egipto","fr":"Égypte","ja":"エジプト","it":"Egitto","br":"Egito","pt":"Egipto","nl":"Egypte","hr":"Egipat","fa":"مصر"},"flag":"https://restcountries.eu/data/egy.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"EGY"} -{"name":"El Salvador","topLevelDomain":[".sv"],"alpha2Code":"SV","alpha3Code":"SLV","callingCodes":["503"],"capital":"San Salvador","altSpellings":["SV","Republic of El Salvador","República de El Salvador"],"region":"Americas","subregion":"Central America","population":6520675,"latlng":[13.83333333,-88.91666666],"demonym":"Salvadoran","area":21041.0,"gini":48.3,"timezones":["UTC-06:00"],"borders":["GTM","HND"],"nativeName":"El Salvador","numericCode":"222","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"El Salvador","es":"El Salvador","fr":"Salvador","ja":"エルサルバドル","it":"El Salvador","br":"El Salvador","pt":"El Salvador","nl":"El Salvador","hr":"Salvador","fa":"السالوادور"},"flag":"https://restcountries.eu/data/slv.svg","regionalBlocs":[{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"ESA"} -{"name":"Equatorial Guinea","topLevelDomain":[".gq"],"alpha2Code":"GQ","alpha3Code":"GNQ","callingCodes":["240"],"capital":"Malabo","altSpellings":["GQ","Republic of Equatorial Guinea","República de Guinea Ecuatorial","République de Guinée équatoriale","República da Guiné Equatorial"],"region":"Africa","subregion":"Middle Africa","population":1222442,"latlng":[2.0,10.0],"demonym":"Equatorial Guinean","area":28051.0,"gini":null,"timezones":["UTC+01:00"],"borders":["CMR","GAB"],"nativeName":"Guinea Ecuatorial","numericCode":"226","currencies":[{"code":"XAF","name":"Central African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Äquatorial-Guinea","es":"Guinea Ecuatorial","fr":"Guinée-Équatoriale","ja":"赤道ギニア","it":"Guinea Equatoriale","br":"Guiné Equatorial","pt":"Guiné Equatorial","nl":"Equatoriaal-Guinea","hr":"Ekvatorijalna Gvineja","fa":"گینه استوایی"},"flag":"https://restcountries.eu/data/gnq.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"GEQ"} -{"name":"Eritrea","topLevelDomain":[".er"],"alpha2Code":"ER","alpha3Code":"ERI","callingCodes":["291"],"capital":"Asmara","altSpellings":["ER","State of Eritrea","ሃገረ ኤርትራ","Dawlat Iritriyá","ʾErtrā","Iritriyā",""],"region":"Africa","subregion":"Eastern Africa","population":5352000,"latlng":[15.0,39.0],"demonym":"Eritrean","area":117600.0,"gini":null,"timezones":["UTC+03:00"],"borders":["DJI","ETH","SDN"],"nativeName":"ኤርትራ","numericCode":"232","currencies":[{"code":"ERN","name":"Eritrean nakfa","symbol":"Nfk"}],"languages":[{"iso639_1":"ti","iso639_2":"tir","name":"Tigrinya","nativeName":"ትግርኛ"},{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Eritrea","es":"Eritrea","fr":"Érythrée","ja":"エリトリア","it":"Eritrea","br":"Eritreia","pt":"Eritreia","nl":"Eritrea","hr":"Eritreja","fa":"اریتره"},"flag":"https://restcountries.eu/data/eri.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"ERI"} -{"name":"Estonia","topLevelDomain":[".ee"],"alpha2Code":"EE","alpha3Code":"EST","callingCodes":["372"],"capital":"Tallinn","altSpellings":["EE","Eesti","Republic of Estonia","Eesti Vabariik"],"region":"Europe","subregion":"Northern Europe","population":1315944,"latlng":[59.0,26.0],"demonym":"Estonian","area":45227.0,"gini":36.0,"timezones":["UTC+02:00"],"borders":["LVA","RUS"],"nativeName":"Eesti","numericCode":"233","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"et","iso639_2":"est","name":"Estonian","nativeName":"eesti"}],"translations":{"de":"Estland","es":"Estonia","fr":"Estonie","ja":"エストニア","it":"Estonia","br":"Estônia","pt":"Estónia","nl":"Estland","hr":"Estonija","fa":"استونی"},"flag":"https://restcountries.eu/data/est.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"EST"} -{"name":"Ethiopia","topLevelDomain":[".et"],"alpha2Code":"ET","alpha3Code":"ETH","callingCodes":["251"],"capital":"Addis Ababa","altSpellings":["ET","ʾĪtyōṗṗyā","Federal Democratic Republic of Ethiopia","የኢትዮጵያ ፌዴራላዊ ዲሞክራሲያዊ ሪፐብሊክ"],"region":"Africa","subregion":"Eastern Africa","population":92206005,"latlng":[8.0,38.0],"demonym":"Ethiopian","area":1104300.0,"gini":29.8,"timezones":["UTC+03:00"],"borders":["DJI","ERI","KEN","SOM","SSD","SDN"],"nativeName":"ኢትዮጵያ","numericCode":"231","currencies":[{"code":"ETB","name":"Ethiopian birr","symbol":"Br"}],"languages":[{"iso639_1":"am","iso639_2":"amh","name":"Amharic","nativeName":"አማርኛ"}],"translations":{"de":"Äthiopien","es":"Etiopía","fr":"Éthiopie","ja":"エチオピア","it":"Etiopia","br":"Etiópia","pt":"Etiópia","nl":"Ethiopië","hr":"Etiopija","fa":"اتیوپی"},"flag":"https://restcountries.eu/data/eth.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"ETH"} -{"name":"Falkland Islands (Malvinas)","topLevelDomain":[".fk"],"alpha2Code":"FK","alpha3Code":"FLK","callingCodes":["500"],"capital":"Stanley","altSpellings":["FK","Islas Malvinas"],"region":"Americas","subregion":"South America","population":2563,"latlng":[-51.75,-59.0],"demonym":"Falkland Islander","area":12173.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Falkland Islands","numericCode":"238","currencies":[{"code":"FKP","name":"Falkland Islands pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Falklandinseln","es":"Islas Malvinas","fr":"Îles Malouines","ja":"フォークランド(マルビナス)諸島","it":"Isole Falkland o Isole Malvine","br":"Ilhas Malvinas","pt":"Ilhas Falkland","nl":"Falklandeilanden [Islas Malvinas]","hr":"Falklandski Otoci","fa":"جزایر فالکلند"},"flag":"https://restcountries.eu/data/flk.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":""} -{"name":"Faroe Islands","topLevelDomain":[".fo"],"alpha2Code":"FO","alpha3Code":"FRO","callingCodes":["298"],"capital":"Tórshavn","altSpellings":["FO","Føroyar","Færøerne"],"region":"Europe","subregion":"Northern Europe","population":49376,"latlng":[62.0,-7.0],"demonym":"Faroese","area":1393.0,"gini":null,"timezones":["UTC+00:00"],"borders":[],"nativeName":"Føroyar","numericCode":"234","currencies":[{"code":"DKK","name":"Danish krone","symbol":"kr"},{"code":"(none)","name":"Faroese króna","symbol":"kr"}],"languages":[{"iso639_1":"fo","iso639_2":"fao","name":"Faroese","nativeName":"føroyskt"}],"translations":{"de":"Färöer-Inseln","es":"Islas Faroe","fr":"Îles Féroé","ja":"フェロー諸島","it":"Isole Far Oer","br":"Ilhas Faroé","pt":"Ilhas Faroé","nl":"Faeröer","hr":"Farski Otoci","fa":"جزایر فارو"},"flag":"https://restcountries.eu/data/fro.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":""} -{"name":"Fiji","topLevelDomain":[".fj"],"alpha2Code":"FJ","alpha3Code":"FJI","callingCodes":["679"],"capital":"Suva","altSpellings":["FJ","Viti","Republic of Fiji","Matanitu ko Viti","Fijī Gaṇarājya"],"region":"Oceania","subregion":"Melanesia","population":867000,"latlng":[-18.0,175.0],"demonym":"Fijian","area":18272.0,"gini":42.8,"timezones":["UTC+12:00"],"borders":[],"nativeName":"Fiji","numericCode":"242","currencies":[{"code":"FJD","name":"Fijian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fj","iso639_2":"fij","name":"Fijian","nativeName":"vosa Vakaviti"},{"iso639_1":"hi","iso639_2":"hin","name":"Hindi","nativeName":"हिन्दी"},{"iso639_1":"ur","iso639_2":"urd","name":"Urdu","nativeName":"اردو"}],"translations":{"de":"Fidschi","es":"Fiyi","fr":"Fidji","ja":"フィジー","it":"Figi","br":"Fiji","pt":"Fiji","nl":"Fiji","hr":"Fiđi","fa":"فیجی"},"flag":"https://restcountries.eu/data/fji.svg","regionalBlocs":[],"cioc":"FIJ"} -{"name":"Finland","topLevelDomain":[".fi"],"alpha2Code":"FI","alpha3Code":"FIN","callingCodes":["358"],"capital":"Helsinki","altSpellings":["FI","Suomi","Republic of Finland","Suomen tasavalta","Republiken Finland"],"region":"Europe","subregion":"Northern Europe","population":5491817,"latlng":[64.0,26.0],"demonym":"Finnish","area":338424.0,"gini":26.9,"timezones":["UTC+02:00"],"borders":["NOR","SWE","RUS"],"nativeName":"Suomi","numericCode":"246","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fi","iso639_2":"fin","name":"Finnish","nativeName":"suomi"},{"iso639_1":"sv","iso639_2":"swe","name":"Swedish","nativeName":"svenska"}],"translations":{"de":"Finnland","es":"Finlandia","fr":"Finlande","ja":"フィンランド","it":"Finlandia","br":"Finlândia","pt":"Finlândia","nl":"Finland","hr":"Finska","fa":"فنلاند"},"flag":"https://restcountries.eu/data/fin.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"FIN"} -{"name":"France","topLevelDomain":[".fr"],"alpha2Code":"FR","alpha3Code":"FRA","callingCodes":["33"],"capital":"Paris","altSpellings":["FR","French Republic","République française"],"region":"Europe","subregion":"Western Europe","population":66710000,"latlng":[46.0,2.0],"demonym":"French","area":640679.0,"gini":32.7,"timezones":["UTC-10:00","UTC-09:30","UTC-09:00","UTC-08:00","UTC-04:00","UTC-03:00","UTC+01:00","UTC+03:00","UTC+04:00","UTC+05:00","UTC+11:00","UTC+12:00"],"borders":["AND","BEL","DEU","ITA","LUX","MCO","ESP","CHE"],"nativeName":"France","numericCode":"250","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Frankreich","es":"Francia","fr":"France","ja":"フランス","it":"Francia","br":"França","pt":"França","nl":"Frankrijk","hr":"Francuska","fa":"فرانسه"},"flag":"https://restcountries.eu/data/fra.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"FRA"} -{"name":"French Guiana","topLevelDomain":[".gf"],"alpha2Code":"GF","alpha3Code":"GUF","callingCodes":["594"],"capital":"Cayenne","altSpellings":["GF","Guiana","Guyane"],"region":"Americas","subregion":"South America","population":254541,"latlng":[4.0,-53.0],"demonym":"","area":null,"gini":null,"timezones":["UTC-03:00"],"borders":["BRA","SUR"],"nativeName":"Guyane française","numericCode":"254","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Französisch Guyana","es":"Guayana Francesa","fr":"Guayane","ja":"フランス領ギアナ","it":"Guyana francese","br":"Guiana Francesa","pt":"Guiana Francesa","nl":"Frans-Guyana","hr":"Francuska Gvajana","fa":"گویان فرانسه"},"flag":"https://restcountries.eu/data/guf.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]},{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":""} -{"name":"French Polynesia","topLevelDomain":[".pf"],"alpha2Code":"PF","alpha3Code":"PYF","callingCodes":["689"],"capital":"Papeetē","altSpellings":["PF","Polynésie française","French Polynesia","Pōrīnetia Farāni"],"region":"Oceania","subregion":"Polynesia","population":271800,"latlng":[-15.0,-140.0],"demonym":"French Polynesian","area":4167.0,"gini":null,"timezones":["UTC-10:00","UTC-09:30","UTC-09:00"],"borders":[],"nativeName":"Polynésie française","numericCode":"258","currencies":[{"code":"XPF","name":"CFP franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Französisch-Polynesien","es":"Polinesia Francesa","fr":"Polynésie française","ja":"フランス領ポリネシア","it":"Polinesia Francese","br":"Polinésia Francesa","pt":"Polinésia Francesa","nl":"Frans-Polynesië","hr":"Francuska Polinezija","fa":"پلی‌نزی فرانسه"},"flag":"https://restcountries.eu/data/pyf.svg","regionalBlocs":[],"cioc":""} -{"name":"French Southern Territories","topLevelDomain":[".tf"],"alpha2Code":"TF","alpha3Code":"ATF","callingCodes":[""],"capital":"Port-aux-Français","altSpellings":["TF"],"region":"Africa","subregion":"Southern Africa","population":140,"latlng":[-49.25,69.167],"demonym":"French","area":7747.0,"gini":null,"timezones":["UTC+05:00"],"borders":[],"nativeName":"Territoire des Terres australes et antarctiques françaises","numericCode":"260","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Französische Süd- und Antarktisgebiete","es":"Tierras Australes y Antárticas Francesas","fr":"Terres australes et antarctiques françaises","ja":"フランス領南方・南極地域","it":"Territori Francesi del Sud","br":"Terras Austrais e Antárticas Francesas","pt":"Terras Austrais e Antárticas Francesas","nl":"Franse Gebieden in de zuidelijke Indische Oceaan","hr":"Francuski južni i antarktički teritoriji","fa":"سرزمین‌های جنوبی و جنوبگانی فرانسه"},"flag":"https://restcountries.eu/data/atf.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":""} -{"name":"Gabon","topLevelDomain":[".ga"],"alpha2Code":"GA","alpha3Code":"GAB","callingCodes":["241"],"capital":"Libreville","altSpellings":["GA","Gabonese Republic","République Gabonaise"],"region":"Africa","subregion":"Middle Africa","population":1802278,"latlng":[-1.0,11.75],"demonym":"Gabonese","area":267668.0,"gini":41.5,"timezones":["UTC+01:00"],"borders":["CMR","COG","GNQ"],"nativeName":"Gabon","numericCode":"266","currencies":[{"code":"XAF","name":"Central African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Gabun","es":"Gabón","fr":"Gabon","ja":"ガボン","it":"Gabon","br":"Gabão","pt":"Gabão","nl":"Gabon","hr":"Gabon","fa":"گابن"},"flag":"https://restcountries.eu/data/gab.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"GAB"} -{"name":"Gambia","topLevelDomain":[".gm"],"alpha2Code":"GM","alpha3Code":"GMB","callingCodes":["220"],"capital":"Banjul","altSpellings":["GM","Republic of the Gambia"],"region":"Africa","subregion":"Western Africa","population":1882450,"latlng":[13.46666666,-16.56666666],"demonym":"Gambian","area":11295.0,"gini":null,"timezones":["UTC+00:00"],"borders":["SEN"],"nativeName":"Gambia","numericCode":"270","currencies":[{"code":"GMD","name":"Gambian dalasi","symbol":"D"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Gambia","es":"Gambia","fr":"Gambie","ja":"ガンビア","it":"Gambia","br":"Gâmbia","pt":"Gâmbia","nl":"Gambia","hr":"Gambija","fa":"گامبیا"},"flag":"https://restcountries.eu/data/gmb.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"GAM"} -{"name":"Georgia","topLevelDomain":[".ge"],"alpha2Code":"GE","alpha3Code":"GEO","callingCodes":["995"],"capital":"Tbilisi","altSpellings":["GE","Sakartvelo"],"region":"Asia","subregion":"Western Asia","population":3720400,"latlng":[42.0,43.5],"demonym":"Georgian","area":69700.0,"gini":41.3,"timezones":["UTC-05:00"],"borders":["ARM","AZE","RUS","TUR"],"nativeName":"საქართველო","numericCode":"268","currencies":[{"code":"GEL","name":"Georgian Lari","symbol":"ლ"}],"languages":[{"iso639_1":"ka","iso639_2":"kat","name":"Georgian","nativeName":"ქართული"}],"translations":{"de":"Georgien","es":"Georgia","fr":"Géorgie","ja":"グルジア","it":"Georgia","br":"Geórgia","pt":"Geórgia","nl":"Georgië","hr":"Gruzija","fa":"گرجستان"},"flag":"https://restcountries.eu/data/geo.svg","regionalBlocs":[],"cioc":"GEO"} -{"name":"Germany","topLevelDomain":[".de"],"alpha2Code":"DE","alpha3Code":"DEU","callingCodes":["49"],"capital":"Berlin","altSpellings":["DE","Federal Republic of Germany","Bundesrepublik Deutschland"],"region":"Europe","subregion":"Western Europe","population":81770900,"latlng":[51.0,9.0],"demonym":"German","area":357114.0,"gini":28.3,"timezones":["UTC+01:00"],"borders":["AUT","BEL","CZE","DNK","FRA","LUX","NLD","POL","CHE"],"nativeName":"Deutschland","numericCode":"276","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"}],"translations":{"de":"Deutschland","es":"Alemania","fr":"Allemagne","ja":"ドイツ","it":"Germania","br":"Alemanha","pt":"Alemanha","nl":"Duitsland","hr":"Njemačka","fa":"آلمان"},"flag":"https://restcountries.eu/data/deu.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"GER"} -{"name":"Ghana","topLevelDomain":[".gh"],"alpha2Code":"GH","alpha3Code":"GHA","callingCodes":["233"],"capital":"Accra","altSpellings":["GH"],"region":"Africa","subregion":"Western Africa","population":27670174,"latlng":[8.0,-2.0],"demonym":"Ghanaian","area":238533.0,"gini":42.8,"timezones":["UTC"],"borders":["BFA","CIV","TGO"],"nativeName":"Ghana","numericCode":"288","currencies":[{"code":"GHS","name":"Ghanaian cedi","symbol":"₵"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Ghana","es":"Ghana","fr":"Ghana","ja":"ガーナ","it":"Ghana","br":"Gana","pt":"Gana","nl":"Ghana","hr":"Gana","fa":"غنا"},"flag":"https://restcountries.eu/data/gha.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"GHA"} -{"name":"Gibraltar","topLevelDomain":[".gi"],"alpha2Code":"GI","alpha3Code":"GIB","callingCodes":["350"],"capital":"Gibraltar","altSpellings":["GI"],"region":"Europe","subregion":"Southern Europe","population":33140,"latlng":[36.13333333,-5.35],"demonym":"Gibraltar","area":6.0,"gini":null,"timezones":["UTC+01:00"],"borders":["ESP"],"nativeName":"Gibraltar","numericCode":"292","currencies":[{"code":"GIP","name":"Gibraltar pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Gibraltar","es":"Gibraltar","fr":"Gibraltar","ja":"ジブラルタル","it":"Gibilterra","br":"Gibraltar","pt":"Gibraltar","nl":"Gibraltar","hr":"Gibraltar","fa":"جبل‌طارق"},"flag":"https://restcountries.eu/data/gib.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":""} -{"name":"Greece","topLevelDomain":[".gr"],"alpha2Code":"GR","alpha3Code":"GRC","callingCodes":["30"],"capital":"Athens","altSpellings":["GR","Elláda","Hellenic Republic","Ελληνική Δημοκρατία"],"region":"Europe","subregion":"Southern Europe","population":10858018,"latlng":[39.0,22.0],"demonym":"Greek","area":131990.0,"gini":34.3,"timezones":["UTC+02:00"],"borders":["ALB","BGR","TUR","MKD"],"nativeName":"Ελλάδα","numericCode":"300","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"el","iso639_2":"ell","name":"Greek (modern)","nativeName":"ελληνικά"}],"translations":{"de":"Griechenland","es":"Grecia","fr":"Grèce","ja":"ギリシャ","it":"Grecia","br":"Grécia","pt":"Grécia","nl":"Griekenland","hr":"Grčka","fa":"یونان"},"flag":"https://restcountries.eu/data/grc.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"GRE"} -{"name":"Greenland","topLevelDomain":[".gl"],"alpha2Code":"GL","alpha3Code":"GRL","callingCodes":["299"],"capital":"Nuuk","altSpellings":["GL","Grønland"],"region":"Americas","subregion":"Northern America","population":55847,"latlng":[72.0,-40.0],"demonym":"Greenlandic","area":2166086.0,"gini":null,"timezones":["UTC-04:00","UTC-03:00","UTC-01:00","UTC+00:00"],"borders":[],"nativeName":"Kalaallit Nunaat","numericCode":"304","currencies":[{"code":"DKK","name":"Danish krone","symbol":"kr"}],"languages":[{"iso639_1":"kl","iso639_2":"kal","name":"Kalaallisut","nativeName":"kalaallisut"}],"translations":{"de":"Grönland","es":"Groenlandia","fr":"Groenland","ja":"グリーンランド","it":"Groenlandia","br":"Groelândia","pt":"Gronelândia","nl":"Groenland","hr":"Grenland","fa":"گرینلند"},"flag":"https://restcountries.eu/data/grl.svg","regionalBlocs":[],"cioc":""} -{"name":"Grenada","topLevelDomain":[".gd"],"alpha2Code":"GD","alpha3Code":"GRD","callingCodes":["1473"],"capital":"St. George's","altSpellings":["GD"],"region":"Americas","subregion":"Caribbean","population":103328,"latlng":[12.11666666,-61.66666666],"demonym":"Grenadian","area":344.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Grenada","numericCode":"308","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Grenada","es":"Grenada","fr":"Grenade","ja":"グレナダ","it":"Grenada","br":"Granada","pt":"Granada","nl":"Grenada","hr":"Grenada","fa":"گرنادا"},"flag":"https://restcountries.eu/data/grd.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"GRN"} -{"name":"Guadeloupe","topLevelDomain":[".gp"],"alpha2Code":"GP","alpha3Code":"GLP","callingCodes":["590"],"capital":"Basse-Terre","altSpellings":["GP","Gwadloup"],"region":"Americas","subregion":"Caribbean","population":400132,"latlng":[16.25,-61.583333],"demonym":"Guadeloupian","area":null,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Guadeloupe","numericCode":"312","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Guadeloupe","es":"Guadalupe","fr":"Guadeloupe","ja":"グアドループ","it":"Guadeloupa","br":"Guadalupe","pt":"Guadalupe","nl":"Guadeloupe","hr":"Gvadalupa","fa":"جزیره گوادلوپ"},"flag":"https://restcountries.eu/data/glp.svg","regionalBlocs":[],"cioc":""} -{"name":"Guam","topLevelDomain":[".gu"],"alpha2Code":"GU","alpha3Code":"GUM","callingCodes":["1671"],"capital":"Hagåtña","altSpellings":["GU","Guåhån"],"region":"Oceania","subregion":"Micronesia","population":184200,"latlng":[13.46666666,144.78333333],"demonym":"Guamanian","area":549.0,"gini":null,"timezones":["UTC+10:00"],"borders":[],"nativeName":"Guam","numericCode":"316","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ch","iso639_2":"cha","name":"Chamorro","nativeName":"Chamoru"},{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Guam","es":"Guam","fr":"Guam","ja":"グアム","it":"Guam","br":"Guam","pt":"Guame","nl":"Guam","hr":"Guam","fa":"گوام"},"flag":"https://restcountries.eu/data/gum.svg","regionalBlocs":[],"cioc":"GUM"} -{"name":"Guatemala","topLevelDomain":[".gt"],"alpha2Code":"GT","alpha3Code":"GTM","callingCodes":["502"],"capital":"Guatemala City","altSpellings":["GT"],"region":"Americas","subregion":"Central America","population":16176133,"latlng":[15.5,-90.25],"demonym":"Guatemalan","area":108889.0,"gini":55.9,"timezones":["UTC-06:00"],"borders":["BLZ","SLV","HND","MEX"],"nativeName":"Guatemala","numericCode":"320","currencies":[{"code":"GTQ","name":"Guatemalan quetzal","symbol":"Q"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Guatemala","es":"Guatemala","fr":"Guatemala","ja":"グアテマラ","it":"Guatemala","br":"Guatemala","pt":"Guatemala","nl":"Guatemala","hr":"Gvatemala","fa":"گواتمالا"},"flag":"https://restcountries.eu/data/gtm.svg","regionalBlocs":[{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"GUA"} -{"name":"Guernsey","topLevelDomain":[".gg"],"alpha2Code":"GG","alpha3Code":"GGY","callingCodes":["44"],"capital":"St. Peter Port","altSpellings":["GG","Bailiwick of Guernsey","Bailliage de Guernesey"],"region":"Europe","subregion":"Northern Europe","population":62999,"latlng":[49.46666666,-2.58333333],"demonym":"Channel Islander","area":78.0,"gini":null,"timezones":["UTC+00:00"],"borders":[],"nativeName":"Guernsey","numericCode":"831","currencies":[{"code":"GBP","name":"British pound","symbol":"£"},{"code":"(none)","name":"Guernsey pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Guernsey","es":"Guernsey","fr":"Guernesey","ja":"ガーンジー","it":"Guernsey","br":"Guernsey","pt":"Guernsey","nl":"Guernsey","hr":"Guernsey","fa":"گرنزی"},"flag":"https://restcountries.eu/data/ggy.svg","regionalBlocs":[],"cioc":""} -{"name":"Guinea","topLevelDomain":[".gn"],"alpha2Code":"GN","alpha3Code":"GIN","callingCodes":["224"],"capital":"Conakry","altSpellings":["GN","Republic of Guinea","République de Guinée"],"region":"Africa","subregion":"Western Africa","population":12947000,"latlng":[11.0,-10.0],"demonym":"Guinean","area":245857.0,"gini":39.4,"timezones":["UTC"],"borders":["CIV","GNB","LBR","MLI","SEN","SLE"],"nativeName":"Guinée","numericCode":"324","currencies":[{"code":"GNF","name":"Guinean franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ff","iso639_2":"ful","name":"Fula","nativeName":"Fulfulde"}],"translations":{"de":"Guinea","es":"Guinea","fr":"Guinée","ja":"ギニア","it":"Guinea","br":"Guiné","pt":"Guiné","nl":"Guinee","hr":"Gvineja","fa":"گینه"},"flag":"https://restcountries.eu/data/gin.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"GUI"} -{"name":"Guinea-Bissau","topLevelDomain":[".gw"],"alpha2Code":"GW","alpha3Code":"GNB","callingCodes":["245"],"capital":"Bissau","altSpellings":["GW","Republic of Guinea-Bissau","República da Guiné-Bissau"],"region":"Africa","subregion":"Western Africa","population":1547777,"latlng":[12.0,-15.0],"demonym":"Guinea-Bissauan","area":36125.0,"gini":35.5,"timezones":["UTC"],"borders":["GIN","SEN"],"nativeName":"Guiné-Bissau","numericCode":"624","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Guinea-Bissau","es":"Guinea-Bisáu","fr":"Guinée-Bissau","ja":"ギニアビサウ","it":"Guinea-Bissau","br":"Guiné-Bissau","pt":"Guiné-Bissau","nl":"Guinee-Bissau","hr":"Gvineja Bisau","fa":"گینه بیسائو"},"flag":"https://restcountries.eu/data/gnb.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"GBS"} -{"name":"Guyana","topLevelDomain":[".gy"],"alpha2Code":"GY","alpha3Code":"GUY","callingCodes":["592"],"capital":"Georgetown","altSpellings":["GY","Co-operative Republic of Guyana"],"region":"Americas","subregion":"South America","population":746900,"latlng":[5.0,-59.0],"demonym":"Guyanese","area":214969.0,"gini":44.5,"timezones":["UTC-04:00"],"borders":["BRA","SUR","VEN"],"nativeName":"Guyana","numericCode":"328","currencies":[{"code":"GYD","name":"Guyanese dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Guyana","es":"Guyana","fr":"Guyane","ja":"ガイアナ","it":"Guyana","br":"Guiana","pt":"Guiana","nl":"Guyana","hr":"Gvajana","fa":"گویان"},"flag":"https://restcountries.eu/data/guy.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]},{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"GUY"} -{"name":"Haiti","topLevelDomain":[".ht"],"alpha2Code":"HT","alpha3Code":"HTI","callingCodes":["509"],"capital":"Port-au-Prince","altSpellings":["HT","Republic of Haiti","République d'Haïti","Repiblik Ayiti"],"region":"Americas","subregion":"Caribbean","population":11078033,"latlng":[19.0,-72.41666666],"demonym":"Haitian","area":27750.0,"gini":59.2,"timezones":["UTC-05:00"],"borders":["DOM"],"nativeName":"Haïti","numericCode":"332","currencies":[{"code":"HTG","name":"Haitian gourde","symbol":"G"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ht","iso639_2":"hat","name":"Haitian","nativeName":"Kreyòl ayisyen"}],"translations":{"de":"Haiti","es":"Haiti","fr":"Haïti","ja":"ハイチ","it":"Haiti","br":"Haiti","pt":"Haiti","nl":"Haïti","hr":"Haiti","fa":"هائیتی"},"flag":"https://restcountries.eu/data/hti.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"HAI"} -{"name":"Heard Island and McDonald Islands","topLevelDomain":[".hm",".aq"],"alpha2Code":"HM","alpha3Code":"HMD","callingCodes":[""],"capital":"","altSpellings":["HM"],"region":"","subregion":"","population":0,"latlng":[-53.1,72.51666666],"demonym":"Heard and McDonald Islander","area":412.0,"gini":null,"timezones":["UTC+05:00"],"borders":[],"nativeName":"Heard Island and McDonald Islands","numericCode":"334","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Heard und die McDonaldinseln","es":"Islas Heard y McDonald","fr":"Îles Heard-et-MacDonald","ja":"ハード島とマクドナルド諸島","it":"Isole Heard e McDonald","br":"Ilha Heard e Ilhas McDonald","pt":"Ilha Heard e Ilhas McDonald","nl":"Heard- en McDonaldeilanden","hr":"Otok Heard i otočje McDonald","fa":"جزیره هرد و جزایر مک‌دونالد"},"flag":"https://restcountries.eu/data/hmd.svg","regionalBlocs":[],"cioc":""} -{"name":"Holy See","topLevelDomain":[".va"],"alpha2Code":"VA","alpha3Code":"VAT","callingCodes":["379"],"capital":"Rome","altSpellings":["Sancta Sedes","Vatican","The Vatican"],"region":"Europe","subregion":"Southern Europe","population":451,"latlng":[41.9,12.45],"demonym":"","area":0.44,"gini":null,"timezones":["UTC+01:00"],"borders":["ITA"],"nativeName":"Sancta Sedes","numericCode":"336","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"la","iso639_2":"lat","name":"Latin","nativeName":"latine"},{"iso639_1":"it","iso639_2":"ita","name":"Italian","nativeName":"Italiano"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"}],"translations":{"de":"Heiliger Stuhl","es":"Santa Sede","fr":"voir Saint","ja":"聖座","it":"Santa Sede","br":"Vaticano","pt":"Vaticano","nl":"Heilige Stoel","hr":"Sveta Stolica","fa":"سریر مقدس"},"flag":"https://restcountries.eu/data/vat.svg","regionalBlocs":[],"cioc":""} -{"name":"Honduras","topLevelDomain":[".hn"],"alpha2Code":"HN","alpha3Code":"HND","callingCodes":["504"],"capital":"Tegucigalpa","altSpellings":["HN","Republic of Honduras","República de Honduras"],"region":"Americas","subregion":"Central America","population":8576532,"latlng":[15.0,-86.5],"demonym":"Honduran","area":112492.0,"gini":57.0,"timezones":["UTC-06:00"],"borders":["GTM","SLV","NIC"],"nativeName":"Honduras","numericCode":"340","currencies":[{"code":"HNL","name":"Honduran lempira","symbol":"L"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Honduras","es":"Honduras","fr":"Honduras","ja":"ホンジュラス","it":"Honduras","br":"Honduras","pt":"Honduras","nl":"Honduras","hr":"Honduras","fa":"هندوراس"},"flag":"https://restcountries.eu/data/hnd.svg","regionalBlocs":[{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"HON"} -{"name":"Hong Kong","topLevelDomain":[".hk"],"alpha2Code":"HK","alpha3Code":"HKG","callingCodes":["852"],"capital":"City of Victoria","altSpellings":["HK","香港"],"region":"Asia","subregion":"Eastern Asia","population":7324300,"latlng":[22.25,114.16666666],"demonym":"Chinese","area":1104.0,"gini":53.3,"timezones":["UTC+08:00"],"borders":["CHN"],"nativeName":"香港","numericCode":"344","currencies":[{"code":"HKD","name":"Hong Kong dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"zh","iso639_2":"zho","name":"Chinese","nativeName":"中文 (Zhōngwén)"}],"translations":{"de":"Hong Kong","es":"Hong Kong","fr":"Hong Kong","ja":"香港","it":"Hong Kong","br":"Hong Kong","pt":"Hong Kong","nl":"Hongkong","hr":"Hong Kong","fa":"هنگ‌کنگ"},"flag":"https://restcountries.eu/data/hkg.svg","regionalBlocs":[],"cioc":"HKG"} -{"name":"Hungary","topLevelDomain":[".hu"],"alpha2Code":"HU","alpha3Code":"HUN","callingCodes":["36"],"capital":"Budapest","altSpellings":["HU"],"region":"Europe","subregion":"Eastern Europe","population":9823000,"latlng":[47.0,20.0],"demonym":"Hungarian","area":93028.0,"gini":31.2,"timezones":["UTC+01:00"],"borders":["AUT","HRV","ROU","SRB","SVK","SVN","UKR"],"nativeName":"Magyarország","numericCode":"348","currencies":[{"code":"HUF","name":"Hungarian forint","symbol":"Ft"}],"languages":[{"iso639_1":"hu","iso639_2":"hun","name":"Hungarian","nativeName":"magyar"}],"translations":{"de":"Ungarn","es":"Hungría","fr":"Hongrie","ja":"ハンガリー","it":"Ungheria","br":"Hungria","pt":"Hungria","nl":"Hongarije","hr":"Mađarska","fa":"مجارستان"},"flag":"https://restcountries.eu/data/hun.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"HUN"} -{"name":"Iceland","topLevelDomain":[".is"],"alpha2Code":"IS","alpha3Code":"ISL","callingCodes":["354"],"capital":"Reykjavík","altSpellings":["IS","Island","Republic of Iceland","Lýðveldið Ísland"],"region":"Europe","subregion":"Northern Europe","population":334300,"latlng":[65.0,-18.0],"demonym":"Icelander","area":103000.0,"gini":null,"timezones":["UTC"],"borders":[],"nativeName":"Ísland","numericCode":"352","currencies":[{"code":"ISK","name":"Icelandic króna","symbol":"kr"}],"languages":[{"iso639_1":"is","iso639_2":"isl","name":"Icelandic","nativeName":"Íslenska"}],"translations":{"de":"Island","es":"Islandia","fr":"Islande","ja":"アイスランド","it":"Islanda","br":"Islândia","pt":"Islândia","nl":"IJsland","hr":"Island","fa":"ایسلند"},"flag":"https://restcountries.eu/data/isl.svg","regionalBlocs":[{"acronym":"EFTA","name":"European Free Trade Association","otherAcronyms":[],"otherNames":[]}],"cioc":"ISL"} -{"name":"India","topLevelDomain":[".in"],"alpha2Code":"IN","alpha3Code":"IND","callingCodes":["91"],"capital":"New Delhi","altSpellings":["IN","Bhārat","Republic of India","Bharat Ganrajya"],"region":"Asia","subregion":"Southern Asia","population":1295210000,"latlng":[20.0,77.0],"demonym":"Indian","area":3287590.0,"gini":33.4,"timezones":["UTC+05:30"],"borders":["AFG","BGD","BTN","MMR","CHN","NPL","PAK","LKA"],"nativeName":"भारत","numericCode":"356","currencies":[{"code":"INR","name":"Indian rupee","symbol":"₹"}],"languages":[{"iso639_1":"hi","iso639_2":"hin","name":"Hindi","nativeName":"हिन्दी"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Indien","es":"India","fr":"Inde","ja":"インド","it":"India","br":"Índia","pt":"Índia","nl":"India","hr":"Indija","fa":"هند"},"flag":"https://restcountries.eu/data/ind.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"IND"} -{"name":"Indonesia","topLevelDomain":[".id"],"alpha2Code":"ID","alpha3Code":"IDN","callingCodes":["62"],"capital":"Jakarta","altSpellings":["ID","Republic of Indonesia","Republik Indonesia"],"region":"Asia","subregion":"South-Eastern Asia","population":258705000,"latlng":[-5.0,120.0],"demonym":"Indonesian","area":1904569.0,"gini":34.0,"timezones":["UTC+07:00","UTC+08:00","UTC+09:00"],"borders":["TLS","MYS","PNG"],"nativeName":"Indonesia","numericCode":"360","currencies":[{"code":"IDR","name":"Indonesian rupiah","symbol":"Rp"}],"languages":[{"iso639_1":"id","iso639_2":"ind","name":"Indonesian","nativeName":"Bahasa Indonesia"}],"translations":{"de":"Indonesien","es":"Indonesia","fr":"Indonésie","ja":"インドネシア","it":"Indonesia","br":"Indonésia","pt":"Indonésia","nl":"Indonesië","hr":"Indonezija","fa":"اندونزی"},"flag":"https://restcountries.eu/data/idn.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"INA"} -{"name":"Côte d'Ivoire","topLevelDomain":[".ci"],"alpha2Code":"CI","alpha3Code":"CIV","callingCodes":["225"],"capital":"Yamoussoukro","altSpellings":["CI","Ivory Coast","Republic of Côte d'Ivoire","République de Côte d'Ivoire"],"region":"Africa","subregion":"Western Africa","population":22671331,"latlng":[8.0,-5.0],"demonym":"Ivorian","area":322463.0,"gini":41.5,"timezones":["UTC"],"borders":["BFA","GHA","GIN","LBR","MLI"],"nativeName":"Côte d'Ivoire","numericCode":"384","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Elfenbeinküste","es":"Costa de Marfil","fr":"Côte d'Ivoire","ja":"コートジボワール","it":"Costa D'Avorio","br":"Costa do Marfim","pt":"Costa do Marfim","nl":"Ivoorkust","hr":"Obala Bjelokosti","fa":"ساحل عاج"},"flag":"https://restcountries.eu/data/civ.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"CIV"} -{"name":"Iran (Islamic Republic of)","topLevelDomain":[".ir"],"alpha2Code":"IR","alpha3Code":"IRN","callingCodes":["98"],"capital":"Tehran","altSpellings":["IR","Islamic Republic of Iran","Jomhuri-ye Eslāmi-ye Irān"],"region":"Asia","subregion":"Southern Asia","population":79369900,"latlng":[32.0,53.0],"demonym":"Iranian","area":1648195.0,"gini":38.3,"timezones":["UTC+03:30"],"borders":["AFG","ARM","AZE","IRQ","PAK","TUR","TKM"],"nativeName":"ایران","numericCode":"364","currencies":[{"code":"IRR","name":"Iranian rial","symbol":"﷼"}],"languages":[{"iso639_1":"fa","iso639_2":"fas","name":"Persian (Farsi)","nativeName":"فارسی"}],"translations":{"de":"Iran","es":"Iran","fr":"Iran","ja":"イラン・イスラム共和国","it":null,"br":"Irã","pt":"Irão","nl":"Iran","hr":"Iran","fa":"ایران"},"flag":"https://restcountries.eu/data/irn.svg","regionalBlocs":[],"cioc":"IRI"} -{"name":"Iraq","topLevelDomain":[".iq"],"alpha2Code":"IQ","alpha3Code":"IRQ","callingCodes":["964"],"capital":"Baghdad","altSpellings":["IQ","Republic of Iraq","Jumhūriyyat al-‘Irāq"],"region":"Asia","subregion":"Western Asia","population":37883543,"latlng":[33.0,44.0],"demonym":"Iraqi","area":438317.0,"gini":30.9,"timezones":["UTC+03:00"],"borders":["IRN","JOR","KWT","SAU","SYR","TUR"],"nativeName":"العراق","numericCode":"368","currencies":[{"code":"IQD","name":"Iraqi dinar","symbol":"ع.د"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"},{"iso639_1":"ku","iso639_2":"kur","name":"Kurdish","nativeName":"Kurdî"}],"translations":{"de":"Irak","es":"Irak","fr":"Irak","ja":"イラク","it":"Iraq","br":"Iraque","pt":"Iraque","nl":"Irak","hr":"Irak","fa":"عراق"},"flag":"https://restcountries.eu/data/irq.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"IRQ"} -{"name":"Ireland","topLevelDomain":[".ie"],"alpha2Code":"IE","alpha3Code":"IRL","callingCodes":["353"],"capital":"Dublin","altSpellings":["IE","Éire","Republic of Ireland","Poblacht na hÉireann"],"region":"Europe","subregion":"Northern Europe","population":6378000,"latlng":[53.0,-8.0],"demonym":"Irish","area":70273.0,"gini":34.3,"timezones":["UTC"],"borders":["GBR"],"nativeName":"Éire","numericCode":"372","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"ga","iso639_2":"gle","name":"Irish","nativeName":"Gaeilge"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Irland","es":"Irlanda","fr":"Irlande","ja":"アイルランド","it":"Irlanda","br":"Irlanda","pt":"Irlanda","nl":"Ierland","hr":"Irska","fa":"ایرلند"},"flag":"https://restcountries.eu/data/irl.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"IRL"} -{"name":"Isle of Man","topLevelDomain":[".im"],"alpha2Code":"IM","alpha3Code":"IMN","callingCodes":["44"],"capital":"Douglas","altSpellings":["IM","Ellan Vannin","Mann","Mannin"],"region":"Europe","subregion":"Northern Europe","population":84497,"latlng":[54.25,-4.5],"demonym":"Manx","area":572.0,"gini":null,"timezones":["UTC+00:00"],"borders":[],"nativeName":"Isle of Man","numericCode":"833","currencies":[{"code":"GBP","name":"British pound","symbol":"£"},{"code":"IMP[G]","name":"Manx pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"gv","iso639_2":"glv","name":"Manx","nativeName":"Gaelg"}],"translations":{"de":"Insel Man","es":"Isla de Man","fr":"Île de Man","ja":"マン島","it":"Isola di Man","br":"Ilha de Man","pt":"Ilha de Man","nl":"Isle of Man","hr":"Otok Man","fa":"جزیره من"},"flag":"https://restcountries.eu/data/imn.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":""} -{"name":"Israel","topLevelDomain":[".il"],"alpha2Code":"IL","alpha3Code":"ISR","callingCodes":["972"],"capital":"Jerusalem","altSpellings":["IL","State of Israel","Medīnat Yisrā'el"],"region":"Asia","subregion":"Western Asia","population":8527400,"latlng":[31.5,34.75],"demonym":"Israeli","area":20770.0,"gini":39.2,"timezones":["UTC+02:00"],"borders":["EGY","JOR","LBN","SYR"],"nativeName":"יִשְׂרָאֵל","numericCode":"376","currencies":[{"code":"ILS","name":"Israeli new shekel","symbol":"₪"}],"languages":[{"iso639_1":"he","iso639_2":"heb","name":"Hebrew (modern)","nativeName":"עברית"},{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Israel","es":"Israel","fr":"Israël","ja":"イスラエル","it":"Israele","br":"Israel","pt":"Israel","nl":"Israël","hr":"Izrael","fa":"اسرائیل"},"flag":"https://restcountries.eu/data/isr.svg","regionalBlocs":[],"cioc":"ISR"} -{"name":"Italy","topLevelDomain":[".it"],"alpha2Code":"IT","alpha3Code":"ITA","callingCodes":["39"],"capital":"Rome","altSpellings":["IT","Italian Republic","Repubblica italiana"],"region":"Europe","subregion":"Southern Europe","population":60665551,"latlng":[42.83333333,12.83333333],"demonym":"Italian","area":301336.0,"gini":36.0,"timezones":["UTC+01:00"],"borders":["AUT","FRA","SMR","SVN","CHE","VAT"],"nativeName":"Italia","numericCode":"380","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"it","iso639_2":"ita","name":"Italian","nativeName":"Italiano"}],"translations":{"de":"Italien","es":"Italia","fr":"Italie","ja":"イタリア","it":"Italia","br":"Itália","pt":"Itália","nl":"Italië","hr":"Italija","fa":"ایتالیا"},"flag":"https://restcountries.eu/data/ita.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"ITA"} -{"name":"Jamaica","topLevelDomain":[".jm"],"alpha2Code":"JM","alpha3Code":"JAM","callingCodes":["1876"],"capital":"Kingston","altSpellings":["JM"],"region":"Americas","subregion":"Caribbean","population":2723246,"latlng":[18.25,-77.5],"demonym":"Jamaican","area":10991.0,"gini":45.5,"timezones":["UTC-05:00"],"borders":[],"nativeName":"Jamaica","numericCode":"388","currencies":[{"code":"JMD","name":"Jamaican dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Jamaika","es":"Jamaica","fr":"Jamaïque","ja":"ジャマイカ","it":"Giamaica","br":"Jamaica","pt":"Jamaica","nl":"Jamaica","hr":"Jamajka","fa":"جامائیکا"},"flag":"https://restcountries.eu/data/jam.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"JAM"} -{"name":"Japan","topLevelDomain":[".jp"],"alpha2Code":"JP","alpha3Code":"JPN","callingCodes":["81"],"capital":"Tokyo","altSpellings":["JP","Nippon","Nihon"],"region":"Asia","subregion":"Eastern Asia","population":126960000,"latlng":[36.0,138.0],"demonym":"Japanese","area":377930.0,"gini":38.1,"timezones":["UTC+09:00"],"borders":[],"nativeName":"日本","numericCode":"392","currencies":[{"code":"JPY","name":"Japanese yen","symbol":"¥"}],"languages":[{"iso639_1":"ja","iso639_2":"jpn","name":"Japanese","nativeName":"日本語 (にほんご)"}],"translations":{"de":"Japan","es":"Japón","fr":"Japon","ja":"日本","it":"Giappone","br":"Japão","pt":"Japão","nl":"Japan","hr":"Japan","fa":"ژاپن"},"flag":"https://restcountries.eu/data/jpn.svg","regionalBlocs":[],"cioc":"JPN"} -{"name":"Jersey","topLevelDomain":[".je"],"alpha2Code":"JE","alpha3Code":"JEY","callingCodes":["44"],"capital":"Saint Helier","altSpellings":["JE","Bailiwick of Jersey","Bailliage de Jersey","Bailliage dé Jèrri"],"region":"Europe","subregion":"Northern Europe","population":100800,"latlng":[49.25,-2.16666666],"demonym":"Channel Islander","area":116.0,"gini":null,"timezones":["UTC+01:00"],"borders":[],"nativeName":"Jersey","numericCode":"832","currencies":[{"code":"GBP","name":"British pound","symbol":"£"},{"code":"JEP[G]","name":"Jersey pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Jersey","es":"Jersey","fr":"Jersey","ja":"ジャージー","it":"Isola di Jersey","br":"Jersey","pt":"Jersey","nl":"Jersey","hr":"Jersey","fa":"جرزی"},"flag":"https://restcountries.eu/data/jey.svg","regionalBlocs":[],"cioc":""} -{"name":"Jordan","topLevelDomain":[".jo"],"alpha2Code":"JO","alpha3Code":"JOR","callingCodes":["962"],"capital":"Amman","altSpellings":["JO","Hashemite Kingdom of Jordan","al-Mamlakah al-Urdunīyah al-Hāshimīyah"],"region":"Asia","subregion":"Western Asia","population":9531712,"latlng":[31.0,36.0],"demonym":"Jordanian","area":89342.0,"gini":35.4,"timezones":["UTC+03:00"],"borders":["IRQ","ISR","SAU","SYR"],"nativeName":"الأردن","numericCode":"400","currencies":[{"code":"JOD","name":"Jordanian dinar","symbol":"د.ا"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Jordanien","es":"Jordania","fr":"Jordanie","ja":"ヨルダン","it":"Giordania","br":"Jordânia","pt":"Jordânia","nl":"Jordanië","hr":"Jordan","fa":"اردن"},"flag":"https://restcountries.eu/data/jor.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"JOR"} -{"name":"Kazakhstan","topLevelDomain":[".kz",".қаз"],"alpha2Code":"KZ","alpha3Code":"KAZ","callingCodes":["76","77"],"capital":"Astana","altSpellings":["KZ","Qazaqstan","Казахстан","Republic of Kazakhstan","Қазақстан Республикасы","Qazaqstan Respublïkası","Республика Казахстан","Respublika Kazakhstan"],"region":"Asia","subregion":"Central Asia","population":17753200,"latlng":[48.0,68.0],"demonym":"Kazakhstani","area":2724900.0,"gini":29.0,"timezones":["UTC+05:00","UTC+06:00"],"borders":["CHN","KGZ","RUS","TKM","UZB"],"nativeName":"Қазақстан","numericCode":"398","currencies":[{"code":"KZT","name":"Kazakhstani tenge","symbol":null}],"languages":[{"iso639_1":"kk","iso639_2":"kaz","name":"Kazakh","nativeName":"қазақ тілі"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Kasachstan","es":"Kazajistán","fr":"Kazakhstan","ja":"カザフスタン","it":"Kazakistan","br":"Cazaquistão","pt":"Cazaquistão","nl":"Kazachstan","hr":"Kazahstan","fa":"قزاقستان"},"flag":"https://restcountries.eu/data/kaz.svg","regionalBlocs":[{"acronym":"EEU","name":"Eurasian Economic Union","otherAcronyms":["EAEU"],"otherNames":[]}],"cioc":"KAZ"} -{"name":"Kenya","topLevelDomain":[".ke"],"alpha2Code":"KE","alpha3Code":"KEN","callingCodes":["254"],"capital":"Nairobi","altSpellings":["KE","Republic of Kenya","Jamhuri ya Kenya"],"region":"Africa","subregion":"Eastern Africa","population":47251000,"latlng":[1.0,38.0],"demonym":"Kenyan","area":580367.0,"gini":47.7,"timezones":["UTC+03:00"],"borders":["ETH","SOM","SSD","TZA","UGA"],"nativeName":"Kenya","numericCode":"404","currencies":[{"code":"KES","name":"Kenyan shilling","symbol":"Sh"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"sw","iso639_2":"swa","name":"Swahili","nativeName":"Kiswahili"}],"translations":{"de":"Kenia","es":"Kenia","fr":"Kenya","ja":"ケニア","it":"Kenya","br":"Quênia","pt":"Quénia","nl":"Kenia","hr":"Kenija","fa":"کنیا"},"flag":"https://restcountries.eu/data/ken.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"KEN"} -{"name":"Kiribati","topLevelDomain":[".ki"],"alpha2Code":"KI","alpha3Code":"KIR","callingCodes":["686"],"capital":"South Tarawa","altSpellings":["KI","Republic of Kiribati","Ribaberiki Kiribati"],"region":"Oceania","subregion":"Micronesia","population":113400,"latlng":[1.41666666,173.0],"demonym":"I-Kiribati","area":811.0,"gini":null,"timezones":["UTC+12:00","UTC+13:00","UTC+14:00"],"borders":[],"nativeName":"Kiribati","numericCode":"296","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"},{"code":"(none)","name":"Kiribati dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Kiribati","es":"Kiribati","fr":"Kiribati","ja":"キリバス","it":"Kiribati","br":"Kiribati","pt":"Quiribáti","nl":"Kiribati","hr":"Kiribati","fa":"کیریباتی"},"flag":"https://restcountries.eu/data/kir.svg","regionalBlocs":[],"cioc":"KIR"} -{"name":"Kuwait","topLevelDomain":[".kw"],"alpha2Code":"KW","alpha3Code":"KWT","callingCodes":["965"],"capital":"Kuwait City","altSpellings":["KW","State of Kuwait","Dawlat al-Kuwait"],"region":"Asia","subregion":"Western Asia","population":4183658,"latlng":[29.5,45.75],"demonym":"Kuwaiti","area":17818.0,"gini":null,"timezones":["UTC+03:00"],"borders":["IRN","SAU"],"nativeName":"الكويت","numericCode":"414","currencies":[{"code":"KWD","name":"Kuwaiti dinar","symbol":"د.ك"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Kuwait","es":"Kuwait","fr":"Koweït","ja":"クウェート","it":"Kuwait","br":"Kuwait","pt":"Kuwait","nl":"Koeweit","hr":"Kuvajt","fa":"کویت"},"flag":"https://restcountries.eu/data/kwt.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"KUW"} -{"name":"Kyrgyzstan","topLevelDomain":[".kg"],"alpha2Code":"KG","alpha3Code":"KGZ","callingCodes":["996"],"capital":"Bishkek","altSpellings":["KG","Киргизия","Kyrgyz Republic","Кыргыз Республикасы","Kyrgyz Respublikasy"],"region":"Asia","subregion":"Central Asia","population":6047800,"latlng":[41.0,75.0],"demonym":"Kirghiz","area":199951.0,"gini":36.2,"timezones":["UTC+06:00"],"borders":["CHN","KAZ","TJK","UZB"],"nativeName":"Кыргызстан","numericCode":"417","currencies":[{"code":"KGS","name":"Kyrgyzstani som","symbol":"с"}],"languages":[{"iso639_1":"ky","iso639_2":"kir","name":"Kyrgyz","nativeName":"Кыргызча"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Kirgisistan","es":"Kirguizistán","fr":"Kirghizistan","ja":"キルギス","it":"Kirghizistan","br":"Quirguistão","pt":"Quirguizistão","nl":"Kirgizië","hr":"Kirgistan","fa":"قرقیزستان"},"flag":"https://restcountries.eu/data/kgz.svg","regionalBlocs":[{"acronym":"EEU","name":"Eurasian Economic Union","otherAcronyms":["EAEU"],"otherNames":[]}],"cioc":"KGZ"} -{"name":"Lao People's Democratic Republic","topLevelDomain":[".la"],"alpha2Code":"LA","alpha3Code":"LAO","callingCodes":["856"],"capital":"Vientiane","altSpellings":["LA","Lao","Laos","Lao People's Democratic Republic","Sathalanalat Paxathipatai Paxaxon Lao"],"region":"Asia","subregion":"South-Eastern Asia","population":6492400,"latlng":[18.0,105.0],"demonym":"Laotian","area":236800.0,"gini":36.7,"timezones":["UTC+07:00"],"borders":["MMR","KHM","CHN","THA","VNM"],"nativeName":"ສປປລາວ","numericCode":"418","currencies":[{"code":"LAK","name":"Lao kip","symbol":"₭"}],"languages":[{"iso639_1":"lo","iso639_2":"lao","name":"Lao","nativeName":"ພາສາລາວ"}],"translations":{"de":"Laos","es":"Laos","fr":"Laos","ja":"ラオス人民民主共和国","it":"Laos","br":"Laos","pt":"Laos","nl":"Laos","hr":"Laos","fa":"لائوس"},"flag":"https://restcountries.eu/data/lao.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"LAO"} -{"name":"Latvia","topLevelDomain":[".lv"],"alpha2Code":"LV","alpha3Code":"LVA","callingCodes":["371"],"capital":"Riga","altSpellings":["LV","Republic of Latvia","Latvijas Republika"],"region":"Europe","subregion":"Northern Europe","population":1961600,"latlng":[57.0,25.0],"demonym":"Latvian","area":64559.0,"gini":36.6,"timezones":["UTC+02:00"],"borders":["BLR","EST","LTU","RUS"],"nativeName":"Latvija","numericCode":"428","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"lv","iso639_2":"lav","name":"Latvian","nativeName":"latviešu valoda"}],"translations":{"de":"Lettland","es":"Letonia","fr":"Lettonie","ja":"ラトビア","it":"Lettonia","br":"Letônia","pt":"Letónia","nl":"Letland","hr":"Latvija","fa":"لتونی"},"flag":"https://restcountries.eu/data/lva.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"LAT"} -{"name":"Lebanon","topLevelDomain":[".lb"],"alpha2Code":"LB","alpha3Code":"LBN","callingCodes":["961"],"capital":"Beirut","altSpellings":["LB","Lebanese Republic","Al-Jumhūrīyah Al-Libnānīyah"],"region":"Asia","subregion":"Western Asia","population":5988000,"latlng":[33.83333333,35.83333333],"demonym":"Lebanese","area":10452.0,"gini":null,"timezones":["UTC+02:00"],"borders":["ISR","SYR"],"nativeName":"لبنان","numericCode":"422","currencies":[{"code":"LBP","name":"Lebanese pound","symbol":"ل.ل"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Libanon","es":"Líbano","fr":"Liban","ja":"レバノン","it":"Libano","br":"Líbano","pt":"Líbano","nl":"Libanon","hr":"Libanon","fa":"لبنان"},"flag":"https://restcountries.eu/data/lbn.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"LIB"} -{"name":"Lesotho","topLevelDomain":[".ls"],"alpha2Code":"LS","alpha3Code":"LSO","callingCodes":["266"],"capital":"Maseru","altSpellings":["LS","Kingdom of Lesotho","Muso oa Lesotho"],"region":"Africa","subregion":"Southern Africa","population":1894194,"latlng":[-29.5,28.5],"demonym":"Mosotho","area":30355.0,"gini":52.5,"timezones":["UTC+02:00"],"borders":["ZAF"],"nativeName":"Lesotho","numericCode":"426","currencies":[{"code":"LSL","name":"Lesotho loti","symbol":"L"},{"code":"ZAR","name":"South African rand","symbol":"R"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"st","iso639_2":"sot","name":"Southern Sotho","nativeName":"Sesotho"}],"translations":{"de":"Lesotho","es":"Lesotho","fr":"Lesotho","ja":"レソト","it":"Lesotho","br":"Lesoto","pt":"Lesoto","nl":"Lesotho","hr":"Lesoto","fa":"لسوتو"},"flag":"https://restcountries.eu/data/lso.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"LES"} -{"name":"Liberia","topLevelDomain":[".lr"],"alpha2Code":"LR","alpha3Code":"LBR","callingCodes":["231"],"capital":"Monrovia","altSpellings":["LR","Republic of Liberia"],"region":"Africa","subregion":"Western Africa","population":4615000,"latlng":[6.5,-9.5],"demonym":"Liberian","area":111369.0,"gini":38.2,"timezones":["UTC"],"borders":["GIN","CIV","SLE"],"nativeName":"Liberia","numericCode":"430","currencies":[{"code":"LRD","name":"Liberian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Liberia","es":"Liberia","fr":"Liberia","ja":"リベリア","it":"Liberia","br":"Libéria","pt":"Libéria","nl":"Liberia","hr":"Liberija","fa":"لیبریا"},"flag":"https://restcountries.eu/data/lbr.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"LBR"} -{"name":"Libya","topLevelDomain":[".ly"],"alpha2Code":"LY","alpha3Code":"LBY","callingCodes":["218"],"capital":"Tripoli","altSpellings":["LY","State of Libya","Dawlat Libya"],"region":"Africa","subregion":"Northern Africa","population":6385000,"latlng":[25.0,17.0],"demonym":"Libyan","area":1759540.0,"gini":null,"timezones":["UTC+01:00"],"borders":["DZA","TCD","EGY","NER","SDN","TUN"],"nativeName":"‏ليبيا","numericCode":"434","currencies":[{"code":"LYD","name":"Libyan dinar","symbol":"ل.د"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Libyen","es":"Libia","fr":"Libye","ja":"リビア","it":"Libia","br":"Líbia","pt":"Líbia","nl":"Libië","hr":"Libija","fa":"لیبی"},"flag":"https://restcountries.eu/data/lby.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"LBA"} -{"name":"Liechtenstein","topLevelDomain":[".li"],"alpha2Code":"LI","alpha3Code":"LIE","callingCodes":["423"],"capital":"Vaduz","altSpellings":["LI","Principality of Liechtenstein","Fürstentum Liechtenstein"],"region":"Europe","subregion":"Western Europe","population":37623,"latlng":[47.26666666,9.53333333],"demonym":"Liechtensteiner","area":160.0,"gini":null,"timezones":["UTC+01:00"],"borders":["AUT","CHE"],"nativeName":"Liechtenstein","numericCode":"438","currencies":[{"code":"CHF","name":"Swiss franc","symbol":"Fr"}],"languages":[{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"}],"translations":{"de":"Liechtenstein","es":"Liechtenstein","fr":"Liechtenstein","ja":"リヒテンシュタイン","it":"Liechtenstein","br":"Liechtenstein","pt":"Listenstaine","nl":"Liechtenstein","hr":"Lihtenštajn","fa":"لیختن‌اشتاین"},"flag":"https://restcountries.eu/data/lie.svg","regionalBlocs":[{"acronym":"EFTA","name":"European Free Trade Association","otherAcronyms":[],"otherNames":[]}],"cioc":"LIE"} -{"name":"Lithuania","topLevelDomain":[".lt"],"alpha2Code":"LT","alpha3Code":"LTU","callingCodes":["370"],"capital":"Vilnius","altSpellings":["LT","Republic of Lithuania","Lietuvos Respublika"],"region":"Europe","subregion":"Northern Europe","population":2872294,"latlng":[56.0,24.0],"demonym":"Lithuanian","area":65300.0,"gini":37.6,"timezones":["UTC+02:00"],"borders":["BLR","LVA","POL","RUS"],"nativeName":"Lietuva","numericCode":"440","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"lt","iso639_2":"lit","name":"Lithuanian","nativeName":"lietuvių kalba"}],"translations":{"de":"Litauen","es":"Lituania","fr":"Lituanie","ja":"リトアニア","it":"Lituania","br":"Lituânia","pt":"Lituânia","nl":"Litouwen","hr":"Litva","fa":"لیتوانی"},"flag":"https://restcountries.eu/data/ltu.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"LTU"} -{"name":"Luxembourg","topLevelDomain":[".lu"],"alpha2Code":"LU","alpha3Code":"LUX","callingCodes":["352"],"capital":"Luxembourg","altSpellings":["LU","Grand Duchy of Luxembourg","Grand-Duché de Luxembourg","Großherzogtum Luxemburg","Groussherzogtum Lëtzebuerg"],"region":"Europe","subregion":"Western Europe","population":576200,"latlng":[49.75,6.16666666],"demonym":"Luxembourger","area":2586.0,"gini":30.8,"timezones":["UTC+01:00"],"borders":["BEL","FRA","DEU"],"nativeName":"Luxembourg","numericCode":"442","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"},{"iso639_1":"lb","iso639_2":"ltz","name":"Luxembourgish","nativeName":"Lëtzebuergesch"}],"translations":{"de":"Luxemburg","es":"Luxemburgo","fr":"Luxembourg","ja":"ルクセンブルク","it":"Lussemburgo","br":"Luxemburgo","pt":"Luxemburgo","nl":"Luxemburg","hr":"Luksemburg","fa":"لوکزامبورگ"},"flag":"https://restcountries.eu/data/lux.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"LUX"} -{"name":"Macao","topLevelDomain":[".mo"],"alpha2Code":"MO","alpha3Code":"MAC","callingCodes":["853"],"capital":"","altSpellings":["MO","澳门","Macao Special Administrative Region of the People's Republic of China","中華人民共和國澳門特別行政區","Região Administrativa Especial de Macau da República Popular da China"],"region":"Asia","subregion":"Eastern Asia","population":649100,"latlng":[22.16666666,113.55],"demonym":"Chinese","area":30.0,"gini":null,"timezones":["UTC+08:00"],"borders":["CHN"],"nativeName":"澳門","numericCode":"446","currencies":[{"code":"MOP","name":"Macanese pataca","symbol":"P"}],"languages":[{"iso639_1":"zh","iso639_2":"zho","name":"Chinese","nativeName":"中文 (Zhōngwén)"},{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Macao","es":"Macao","fr":"Macao","ja":"マカオ","it":"Macao","br":"Macau","pt":"Macau","nl":"Macao","hr":"Makao","fa":"مکائو"},"flag":"https://restcountries.eu/data/mac.svg","regionalBlocs":[],"cioc":""} -{"name":"Macedonia (the former Yugoslav Republic of)","topLevelDomain":[".mk"],"alpha2Code":"MK","alpha3Code":"MKD","callingCodes":["389"],"capital":"Skopje","altSpellings":["MK","Republic of Macedonia","Република Македонија"],"region":"Europe","subregion":"Southern Europe","population":2058539,"latlng":[41.83333333,22.0],"demonym":"Macedonian","area":25713.0,"gini":43.2,"timezones":["UTC+01:00"],"borders":["ALB","BGR","GRC","KOS","SRB"],"nativeName":"Македонија","numericCode":"807","currencies":[{"code":"MKD","name":"Macedonian denar","symbol":"ден"}],"languages":[{"iso639_1":"mk","iso639_2":"mkd","name":"Macedonian","nativeName":"македонски јазик"}],"translations":{"de":"Mazedonien","es":"Macedonia","fr":"Macédoine","ja":"マケドニア旧ユーゴスラビア共和国","it":"Macedonia","br":"Macedônia","pt":"Macedónia","nl":"Macedonië","hr":"Makedonija","fa":""},"flag":"https://restcountries.eu/data/mkd.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":"MKD"} -{"name":"Madagascar","topLevelDomain":[".mg"],"alpha2Code":"MG","alpha3Code":"MDG","callingCodes":["261"],"capital":"Antananarivo","altSpellings":["MG","Republic of Madagascar","Repoblikan'i Madagasikara","République de Madagascar"],"region":"Africa","subregion":"Eastern Africa","population":22434363,"latlng":[-20.0,47.0],"demonym":"Malagasy","area":587041.0,"gini":44.1,"timezones":["UTC+03:00"],"borders":[],"nativeName":"Madagasikara","numericCode":"450","currencies":[{"code":"MGA","name":"Malagasy ariary","symbol":"Ar"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"mg","iso639_2":"mlg","name":"Malagasy","nativeName":"fiteny malagasy"}],"translations":{"de":"Madagaskar","es":"Madagascar","fr":"Madagascar","ja":"マダガスカル","it":"Madagascar","br":"Madagascar","pt":"Madagáscar","nl":"Madagaskar","hr":"Madagaskar","fa":"ماداگاسکار"},"flag":"https://restcountries.eu/data/mdg.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"MAD"} -{"name":"Malawi","topLevelDomain":[".mw"],"alpha2Code":"MW","alpha3Code":"MWI","callingCodes":["265"],"capital":"Lilongwe","altSpellings":["MW","Republic of Malawi"],"region":"Africa","subregion":"Eastern Africa","population":16832910,"latlng":[-13.5,34.0],"demonym":"Malawian","area":118484.0,"gini":39.0,"timezones":["UTC+02:00"],"borders":["MOZ","TZA","ZMB"],"nativeName":"Malawi","numericCode":"454","currencies":[{"code":"MWK","name":"Malawian kwacha","symbol":"MK"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ny","iso639_2":"nya","name":"Chichewa","nativeName":"chiCheŵa"}],"translations":{"de":"Malawi","es":"Malawi","fr":"Malawi","ja":"マラウイ","it":"Malawi","br":"Malawi","pt":"Malávi","nl":"Malawi","hr":"Malavi","fa":"مالاوی"},"flag":"https://restcountries.eu/data/mwi.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"MAW"} -{"name":"Malaysia","topLevelDomain":[".my"],"alpha2Code":"MY","alpha3Code":"MYS","callingCodes":["60"],"capital":"Kuala Lumpur","altSpellings":["MY"],"region":"Asia","subregion":"South-Eastern Asia","population":31405416,"latlng":[2.5,112.5],"demonym":"Malaysian","area":330803.0,"gini":46.2,"timezones":["UTC+08:00"],"borders":["BRN","IDN","THA"],"nativeName":"Malaysia","numericCode":"458","currencies":[{"code":"MYR","name":"Malaysian ringgit","symbol":"RM"}],"languages":[{"iso639_1":null,"iso639_2":"zsm","name":"Malaysian","nativeName":"بهاس مليسيا"}],"translations":{"de":"Malaysia","es":"Malasia","fr":"Malaisie","ja":"マレーシア","it":"Malesia","br":"Malásia","pt":"Malásia","nl":"Maleisië","hr":"Malezija","fa":"مالزی"},"flag":"https://restcountries.eu/data/mys.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"MAS"} -{"name":"Maldives","topLevelDomain":[".mv"],"alpha2Code":"MV","alpha3Code":"MDV","callingCodes":["960"],"capital":"Malé","altSpellings":["MV","Maldive Islands","Republic of the Maldives","Dhivehi Raajjeyge Jumhooriyya"],"region":"Asia","subregion":"Southern Asia","population":344023,"latlng":[3.25,73.0],"demonym":"Maldivan","area":300.0,"gini":37.4,"timezones":["UTC+05:00"],"borders":[],"nativeName":"Maldives","numericCode":"462","currencies":[{"code":"MVR","name":"Maldivian rufiyaa","symbol":".ރ"}],"languages":[{"iso639_1":"dv","iso639_2":"div","name":"Divehi","nativeName":"ދިވެހި"}],"translations":{"de":"Malediven","es":"Maldivas","fr":"Maldives","ja":"モルディブ","it":"Maldive","br":"Maldivas","pt":"Maldivas","nl":"Maldiven","hr":"Maldivi","fa":"مالدیو"},"flag":"https://restcountries.eu/data/mdv.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"MDV"} -{"name":"Mali","topLevelDomain":[".ml"],"alpha2Code":"ML","alpha3Code":"MLI","callingCodes":["223"],"capital":"Bamako","altSpellings":["ML","Republic of Mali","République du Mali"],"region":"Africa","subregion":"Western Africa","population":18135000,"latlng":[17.0,-4.0],"demonym":"Malian","area":1240192.0,"gini":33.0,"timezones":["UTC"],"borders":["DZA","BFA","GIN","CIV","MRT","NER","SEN"],"nativeName":"Mali","numericCode":"466","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Mali","es":"Mali","fr":"Mali","ja":"マリ","it":"Mali","br":"Mali","pt":"Mali","nl":"Mali","hr":"Mali","fa":"مالی"},"flag":"https://restcountries.eu/data/mli.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"MLI"} -{"name":"Malta","topLevelDomain":[".mt"],"alpha2Code":"MT","alpha3Code":"MLT","callingCodes":["356"],"capital":"Valletta","altSpellings":["MT","Republic of Malta","Repubblika ta' Malta"],"region":"Europe","subregion":"Southern Europe","population":425384,"latlng":[35.83333333,14.58333333],"demonym":"Maltese","area":316.0,"gini":null,"timezones":["UTC+01:00"],"borders":[],"nativeName":"Malta","numericCode":"470","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"mt","iso639_2":"mlt","name":"Maltese","nativeName":"Malti"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Malta","es":"Malta","fr":"Malte","ja":"マルタ","it":"Malta","br":"Malta","pt":"Malta","nl":"Malta","hr":"Malta","fa":"مالت"},"flag":"https://restcountries.eu/data/mlt.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"MLT"} -{"name":"Marshall Islands","topLevelDomain":[".mh"],"alpha2Code":"MH","alpha3Code":"MHL","callingCodes":["692"],"capital":"Majuro","altSpellings":["MH","Republic of the Marshall Islands","Aolepān Aorōkin M̧ajeļ"],"region":"Oceania","subregion":"Micronesia","population":54880,"latlng":[9.0,168.0],"demonym":"Marshallese","area":181.0,"gini":null,"timezones":["UTC+12:00"],"borders":[],"nativeName":"M̧ajeļ","numericCode":"584","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"mh","iso639_2":"mah","name":"Marshallese","nativeName":"Kajin M̧ajeļ"}],"translations":{"de":"Marshallinseln","es":"Islas Marshall","fr":"Îles Marshall","ja":"マーシャル諸島","it":"Isole Marshall","br":"Ilhas Marshall","pt":"Ilhas Marshall","nl":"Marshalleilanden","hr":"Maršalovi Otoci","fa":"جزایر مارشال"},"flag":"https://restcountries.eu/data/mhl.svg","regionalBlocs":[],"cioc":"MHL"} -{"name":"Martinique","topLevelDomain":[".mq"],"alpha2Code":"MQ","alpha3Code":"MTQ","callingCodes":["596"],"capital":"Fort-de-France","altSpellings":["MQ"],"region":"Americas","subregion":"Caribbean","population":378243,"latlng":[14.666667,-61.0],"demonym":"French","area":null,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Martinique","numericCode":"474","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Martinique","es":"Martinica","fr":"Martinique","ja":"マルティニーク","it":"Martinica","br":"Martinica","pt":"Martinica","nl":"Martinique","hr":"Martinique","fa":"مونتسرات"},"flag":"https://restcountries.eu/data/mtq.svg","regionalBlocs":[],"cioc":""} -{"name":"Mauritania","topLevelDomain":[".mr"],"alpha2Code":"MR","alpha3Code":"MRT","callingCodes":["222"],"capital":"Nouakchott","altSpellings":["MR","Islamic Republic of Mauritania","al-Jumhūriyyah al-ʾIslāmiyyah al-Mūrītāniyyah"],"region":"Africa","subregion":"Western Africa","population":3718678,"latlng":[20.0,-12.0],"demonym":"Mauritanian","area":1030700.0,"gini":40.5,"timezones":["UTC"],"borders":["DZA","MLI","SEN","ESH"],"nativeName":"موريتانيا","numericCode":"478","currencies":[{"code":"MRO","name":"Mauritanian ouguiya","symbol":"UM"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Mauretanien","es":"Mauritania","fr":"Mauritanie","ja":"モーリタニア","it":"Mauritania","br":"Mauritânia","pt":"Mauritânia","nl":"Mauritanië","hr":"Mauritanija","fa":"موریتانی"},"flag":"https://restcountries.eu/data/mrt.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"MTN"} -{"name":"Mauritius","topLevelDomain":[".mu"],"alpha2Code":"MU","alpha3Code":"MUS","callingCodes":["230"],"capital":"Port Louis","altSpellings":["MU","Republic of Mauritius","République de Maurice"],"region":"Africa","subregion":"Eastern Africa","population":1262879,"latlng":[-20.28333333,57.55],"demonym":"Mauritian","area":2040.0,"gini":null,"timezones":["UTC+04:00"],"borders":[],"nativeName":"Maurice","numericCode":"480","currencies":[{"code":"MUR","name":"Mauritian rupee","symbol":"₨"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Mauritius","es":"Mauricio","fr":"Île Maurice","ja":"モーリシャス","it":"Mauritius","br":"Maurício","pt":"Maurícia","nl":"Mauritius","hr":"Mauricijus","fa":"موریس"},"flag":"https://restcountries.eu/data/mus.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"MRI"} -{"name":"Mayotte","topLevelDomain":[".yt"],"alpha2Code":"YT","alpha3Code":"MYT","callingCodes":["262"],"capital":"Mamoudzou","altSpellings":["YT","Department of Mayotte","Département de Mayotte"],"region":"Africa","subregion":"Eastern Africa","population":226915,"latlng":[-12.83333333,45.16666666],"demonym":"French","area":null,"gini":null,"timezones":["UTC+03:00"],"borders":[],"nativeName":"Mayotte","numericCode":"175","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Mayotte","es":"Mayotte","fr":"Mayotte","ja":"マヨット","it":"Mayotte","br":"Mayotte","pt":"Mayotte","nl":"Mayotte","hr":"Mayotte","fa":"مایوت"},"flag":"https://restcountries.eu/data/myt.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":""} -{"name":"Mexico","topLevelDomain":[".mx"],"alpha2Code":"MX","alpha3Code":"MEX","callingCodes":["52"],"capital":"Mexico City","altSpellings":["MX","Mexicanos","United Mexican States","Estados Unidos Mexicanos"],"region":"Americas","subregion":"Central America","population":122273473,"latlng":[23.0,-102.0],"demonym":"Mexican","area":1964375.0,"gini":47.0,"timezones":["UTC-08:00","UTC-07:00","UTC-06:00"],"borders":["BLZ","GTM","USA"],"nativeName":"México","numericCode":"484","currencies":[{"code":"MXN","name":"Mexican peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Mexiko","es":"México","fr":"Mexique","ja":"メキシコ","it":"Messico","br":"México","pt":"México","nl":"Mexico","hr":"Meksiko","fa":"مکزیک"},"flag":"https://restcountries.eu/data/mex.svg","regionalBlocs":[{"acronym":"PA","name":"Pacific Alliance","otherAcronyms":[],"otherNames":["Alianza del Pacífico"]},{"acronym":"NAFTA","name":"North American Free Trade Agreement","otherAcronyms":[],"otherNames":["Tratado de Libre Comercio de América del Norte","Accord de Libre-échange Nord-Américain"]}],"cioc":"MEX"} -{"name":"Micronesia (Federated States of)","topLevelDomain":[".fm"],"alpha2Code":"FM","alpha3Code":"FSM","callingCodes":["691"],"capital":"Palikir","altSpellings":["FM","Federated States of Micronesia"],"region":"Oceania","subregion":"Micronesia","population":102800,"latlng":[6.91666666,158.25],"demonym":"Micronesian","area":702.0,"gini":null,"timezones":["UTC+10:00","UTC+11"],"borders":[],"nativeName":"Micronesia","numericCode":"583","currencies":[{"code":null,"name":"[D]","symbol":"$"},{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Mikronesien","es":"Micronesia","fr":"Micronésie","ja":"ミクロネシア連邦","it":"Micronesia","br":"Micronésia","pt":"Micronésia","nl":"Micronesië","hr":"Mikronezija","fa":"ایالات فدرال میکرونزی"},"flag":"https://restcountries.eu/data/fsm.svg","regionalBlocs":[],"cioc":"FSM"} -{"name":"Moldova (Republic of)","topLevelDomain":[".md"],"alpha2Code":"MD","alpha3Code":"MDA","callingCodes":["373"],"capital":"Chișinău","altSpellings":["MD","Republic of Moldova","Republica Moldova"],"region":"Europe","subregion":"Eastern Europe","population":3553100,"latlng":[47.0,29.0],"demonym":"Moldovan","area":33846.0,"gini":33.0,"timezones":["UTC+02:00"],"borders":["ROU","UKR"],"nativeName":"Moldova","numericCode":"498","currencies":[{"code":"MDL","name":"Moldovan leu","symbol":"L"}],"languages":[{"iso639_1":"ro","iso639_2":"ron","name":"Romanian","nativeName":"Română"}],"translations":{"de":"Moldawie","es":"Moldavia","fr":"Moldavie","ja":"モルドバ共和国","it":"Moldavia","br":"Moldávia","pt":"Moldávia","nl":"Moldavië","hr":"Moldova","fa":"مولداوی"},"flag":"https://restcountries.eu/data/mda.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":"MDA"} -{"name":"Monaco","topLevelDomain":[".mc"],"alpha2Code":"MC","alpha3Code":"MCO","callingCodes":["377"],"capital":"Monaco","altSpellings":["MC","Principality of Monaco","Principauté de Monaco"],"region":"Europe","subregion":"Western Europe","population":38400,"latlng":[43.73333333,7.4],"demonym":"Monegasque","area":2.02,"gini":null,"timezones":["UTC+01:00"],"borders":["FRA"],"nativeName":"Monaco","numericCode":"492","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Monaco","es":"Mónaco","fr":"Monaco","ja":"モナコ","it":"Principato di Monaco","br":"Mônaco","pt":"Mónaco","nl":"Monaco","hr":"Monako","fa":"موناکو"},"flag":"https://restcountries.eu/data/mco.svg","regionalBlocs":[],"cioc":"MON"} -{"name":"Mongolia","topLevelDomain":[".mn"],"alpha2Code":"MN","alpha3Code":"MNG","callingCodes":["976"],"capital":"Ulan Bator","altSpellings":["MN"],"region":"Asia","subregion":"Eastern Asia","population":3093100,"latlng":[46.0,105.0],"demonym":"Mongolian","area":1564110.0,"gini":36.5,"timezones":["UTC+07:00","UTC+08:00"],"borders":["CHN","RUS"],"nativeName":"Монгол улс","numericCode":"496","currencies":[{"code":"MNT","name":"Mongolian tögrög","symbol":"₮"}],"languages":[{"iso639_1":"mn","iso639_2":"mon","name":"Mongolian","nativeName":"Монгол хэл"}],"translations":{"de":"Mongolei","es":"Mongolia","fr":"Mongolie","ja":"モンゴル","it":"Mongolia","br":"Mongólia","pt":"Mongólia","nl":"Mongolië","hr":"Mongolija","fa":"مغولستان"},"flag":"https://restcountries.eu/data/mng.svg","regionalBlocs":[],"cioc":"MGL"} -{"name":"Montenegro","topLevelDomain":[".me"],"alpha2Code":"ME","alpha3Code":"MNE","callingCodes":["382"],"capital":"Podgorica","altSpellings":["ME","Crna Gora"],"region":"Europe","subregion":"Southern Europe","population":621810,"latlng":[42.5,19.3],"demonym":"Montenegrin","area":13812.0,"gini":30.0,"timezones":["UTC+01:00"],"borders":["ALB","BIH","HRV","KOS","SRB"],"nativeName":"Црна Гора","numericCode":"499","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"sr","iso639_2":"srp","name":"Serbian","nativeName":"српски језик"},{"iso639_1":"bs","iso639_2":"bos","name":"Bosnian","nativeName":"bosanski jezik"},{"iso639_1":"sq","iso639_2":"sqi","name":"Albanian","nativeName":"Shqip"},{"iso639_1":"hr","iso639_2":"hrv","name":"Croatian","nativeName":"hrvatski jezik"}],"translations":{"de":"Montenegro","es":"Montenegro","fr":"Monténégro","ja":"モンテネグロ","it":"Montenegro","br":"Montenegro","pt":"Montenegro","nl":"Montenegro","hr":"Crna Gora","fa":"مونته‌نگرو"},"flag":"https://restcountries.eu/data/mne.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":"MNE"} -{"name":"Montserrat","topLevelDomain":[".ms"],"alpha2Code":"MS","alpha3Code":"MSR","callingCodes":["1664"],"capital":"Plymouth","altSpellings":["MS"],"region":"Americas","subregion":"Caribbean","population":4922,"latlng":[16.75,-62.2],"demonym":"Montserratian","area":102.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Montserrat","numericCode":"500","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Montserrat","es":"Montserrat","fr":"Montserrat","ja":"モントセラト","it":"Montserrat","br":"Montserrat","pt":"Monserrate","nl":"Montserrat","hr":"Montserrat","fa":"مایوت"},"flag":"https://restcountries.eu/data/msr.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":""} -{"name":"Morocco","topLevelDomain":[".ma"],"alpha2Code":"MA","alpha3Code":"MAR","callingCodes":["212"],"capital":"Rabat","altSpellings":["MA","Kingdom of Morocco","Al-Mamlakah al-Maġribiyah"],"region":"Africa","subregion":"Northern Africa","population":33337529,"latlng":[32.0,-5.0],"demonym":"Moroccan","area":446550.0,"gini":40.9,"timezones":["UTC"],"borders":["DZA","ESH","ESP"],"nativeName":"المغرب","numericCode":"504","currencies":[{"code":"MAD","name":"Moroccan dirham","symbol":"د.م."}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Marokko","es":"Marruecos","fr":"Maroc","ja":"モロッコ","it":"Marocco","br":"Marrocos","pt":"Marrocos","nl":"Marokko","hr":"Maroko","fa":"مراکش"},"flag":"https://restcountries.eu/data/mar.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"MAR"} -{"name":"Mozambique","topLevelDomain":[".mz"],"alpha2Code":"MZ","alpha3Code":"MOZ","callingCodes":["258"],"capital":"Maputo","altSpellings":["MZ","Republic of Mozambique","República de Moçambique"],"region":"Africa","subregion":"Eastern Africa","population":26423700,"latlng":[-18.25,35.0],"demonym":"Mozambican","area":801590.0,"gini":45.7,"timezones":["UTC+02:00"],"borders":["MWI","ZAF","SWZ","TZA","ZMB","ZWE"],"nativeName":"Moçambique","numericCode":"508","currencies":[{"code":"MZN","name":"Mozambican metical","symbol":"MT"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Mosambik","es":"Mozambique","fr":"Mozambique","ja":"モザンビーク","it":"Mozambico","br":"Moçambique","pt":"Moçambique","nl":"Mozambique","hr":"Mozambik","fa":"موزامبیک"},"flag":"https://restcountries.eu/data/moz.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"MOZ"} -{"name":"Myanmar","topLevelDomain":[".mm"],"alpha2Code":"MM","alpha3Code":"MMR","callingCodes":["95"],"capital":"Naypyidaw","altSpellings":["MM","Burma","Republic of the Union of Myanmar","Pyidaunzu Thanmăda Myăma Nainngandaw"],"region":"Asia","subregion":"South-Eastern Asia","population":51419420,"latlng":[22.0,98.0],"demonym":"Burmese","area":676578.0,"gini":null,"timezones":["UTC+06:30"],"borders":["BGD","CHN","IND","LAO","THA"],"nativeName":"Myanma","numericCode":"104","currencies":[{"code":"MMK","name":"Burmese kyat","symbol":"Ks"}],"languages":[{"iso639_1":"my","iso639_2":"mya","name":"Burmese","nativeName":"ဗမာစာ"}],"translations":{"de":"Myanmar","es":"Myanmar","fr":"Myanmar","ja":"ミャンマー","it":"Birmania","br":"Myanmar","pt":"Myanmar","nl":"Myanmar","hr":"Mijanmar","fa":"میانمار"},"flag":"https://restcountries.eu/data/mmr.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"MYA"} -{"name":"Namibia","topLevelDomain":[".na"],"alpha2Code":"NA","alpha3Code":"NAM","callingCodes":["264"],"capital":"Windhoek","altSpellings":["NA","Namibië","Republic of Namibia"],"region":"Africa","subregion":"Southern Africa","population":2324388,"latlng":[-22.0,17.0],"demonym":"Namibian","area":825615.0,"gini":63.9,"timezones":["UTC+01:00"],"borders":["AGO","BWA","ZAF","ZMB"],"nativeName":"Namibia","numericCode":"516","currencies":[{"code":"NAD","name":"Namibian dollar","symbol":"$"},{"code":"ZAR","name":"South African rand","symbol":"R"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"af","iso639_2":"afr","name":"Afrikaans","nativeName":"Afrikaans"}],"translations":{"de":"Namibia","es":"Namibia","fr":"Namibie","ja":"ナミビア","it":"Namibia","br":"Namíbia","pt":"Namíbia","nl":"Namibië","hr":"Namibija","fa":"نامیبیا"},"flag":"https://restcountries.eu/data/nam.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"NAM"} -{"name":"Nauru","topLevelDomain":[".nr"],"alpha2Code":"NR","alpha3Code":"NRU","callingCodes":["674"],"capital":"Yaren","altSpellings":["NR","Naoero","Pleasant Island","Republic of Nauru","Ripublik Naoero"],"region":"Oceania","subregion":"Micronesia","population":10084,"latlng":[-0.53333333,166.91666666],"demonym":"Nauruan","area":21.0,"gini":null,"timezones":["UTC+12:00"],"borders":[],"nativeName":"Nauru","numericCode":"520","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"},{"code":"(none)","name":null,"symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"na","iso639_2":"nau","name":"Nauruan","nativeName":"Dorerin Naoero"}],"translations":{"de":"Nauru","es":"Nauru","fr":"Nauru","ja":"ナウル","it":"Nauru","br":"Nauru","pt":"Nauru","nl":"Nauru","hr":"Nauru","fa":"نائورو"},"flag":"https://restcountries.eu/data/nru.svg","regionalBlocs":[],"cioc":"NRU"} -{"name":"Nepal","topLevelDomain":[".np"],"alpha2Code":"NP","alpha3Code":"NPL","callingCodes":["977"],"capital":"Kathmandu","altSpellings":["NP","Federal Democratic Republic of Nepal","Loktāntrik Ganatantra Nepāl"],"region":"Asia","subregion":"Southern Asia","population":28431500,"latlng":[28.0,84.0],"demonym":"Nepalese","area":147181.0,"gini":32.8,"timezones":["UTC+05:45"],"borders":["CHN","IND"],"nativeName":"नेपाल","numericCode":"524","currencies":[{"code":"NPR","name":"Nepalese rupee","symbol":"₨"}],"languages":[{"iso639_1":"ne","iso639_2":"nep","name":"Nepali","nativeName":"नेपाली"}],"translations":{"de":"Népal","es":"Nepal","fr":"Népal","ja":"ネパール","it":"Nepal","br":"Nepal","pt":"Nepal","nl":"Nepal","hr":"Nepal","fa":"نپال"},"flag":"https://restcountries.eu/data/npl.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"NEP"} -{"name":"Netherlands","topLevelDomain":[".nl"],"alpha2Code":"NL","alpha3Code":"NLD","callingCodes":["31"],"capital":"Amsterdam","altSpellings":["NL","Holland","Nederland"],"region":"Europe","subregion":"Western Europe","population":17019800,"latlng":[52.5,5.75],"demonym":"Dutch","area":41850.0,"gini":30.9,"timezones":["UTC-04:00","UTC+01:00"],"borders":["BEL","DEU"],"nativeName":"Nederland","numericCode":"528","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"}],"translations":{"de":"Niederlande","es":"Países Bajos","fr":"Pays-Bas","ja":"オランダ","it":"Paesi Bassi","br":"Holanda","pt":"Países Baixos","nl":"Nederland","hr":"Nizozemska","fa":"پادشاهی هلند"},"flag":"https://restcountries.eu/data/nld.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"NED"} -{"name":"New Caledonia","topLevelDomain":[".nc"],"alpha2Code":"NC","alpha3Code":"NCL","callingCodes":["687"],"capital":"Nouméa","altSpellings":["NC"],"region":"Oceania","subregion":"Melanesia","population":268767,"latlng":[-21.5,165.5],"demonym":"New Caledonian","area":18575.0,"gini":null,"timezones":["UTC+11:00"],"borders":[],"nativeName":"Nouvelle-Calédonie","numericCode":"540","currencies":[{"code":"XPF","name":"CFP franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Neukaledonien","es":"Nueva Caledonia","fr":"Nouvelle-Calédonie","ja":"ニューカレドニア","it":"Nuova Caledonia","br":"Nova Caledônia","pt":"Nova Caledónia","nl":"Nieuw-Caledonië","hr":"Nova Kaledonija","fa":"کالدونیای جدید"},"flag":"https://restcountries.eu/data/ncl.svg","regionalBlocs":[],"cioc":""} -{"name":"New Zealand","topLevelDomain":[".nz"],"alpha2Code":"NZ","alpha3Code":"NZL","callingCodes":["64"],"capital":"Wellington","altSpellings":["NZ","Aotearoa"],"region":"Oceania","subregion":"Australia and New Zealand","population":4697854,"latlng":[-41.0,174.0],"demonym":"New Zealander","area":270467.0,"gini":36.2,"timezones":["UTC-11:00","UTC-10:00","UTC+12:00","UTC+12:45","UTC+13:00"],"borders":[],"nativeName":"New Zealand","numericCode":"554","currencies":[{"code":"NZD","name":"New Zealand dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"mi","iso639_2":"mri","name":"Māori","nativeName":"te reo Māori"}],"translations":{"de":"Neuseeland","es":"Nueva Zelanda","fr":"Nouvelle-Zélande","ja":"ニュージーランド","it":"Nuova Zelanda","br":"Nova Zelândia","pt":"Nova Zelândia","nl":"Nieuw-Zeeland","hr":"Novi Zeland","fa":"نیوزیلند"},"flag":"https://restcountries.eu/data/nzl.svg","regionalBlocs":[],"cioc":"NZL"} -{"name":"Nicaragua","topLevelDomain":[".ni"],"alpha2Code":"NI","alpha3Code":"NIC","callingCodes":["505"],"capital":"Managua","altSpellings":["NI","Republic of Nicaragua","República de Nicaragua"],"region":"Americas","subregion":"Central America","population":6262703,"latlng":[13.0,-85.0],"demonym":"Nicaraguan","area":130373.0,"gini":40.5,"timezones":["UTC-06:00"],"borders":["CRI","HND"],"nativeName":"Nicaragua","numericCode":"558","currencies":[{"code":"NIO","name":"Nicaraguan córdoba","symbol":"C$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Nicaragua","es":"Nicaragua","fr":"Nicaragua","ja":"ニカラグア","it":"Nicaragua","br":"Nicarágua","pt":"Nicarágua","nl":"Nicaragua","hr":"Nikaragva","fa":"نیکاراگوئه"},"flag":"https://restcountries.eu/data/nic.svg","regionalBlocs":[{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"NCA"} -{"name":"Niger","topLevelDomain":[".ne"],"alpha2Code":"NE","alpha3Code":"NER","callingCodes":["227"],"capital":"Niamey","altSpellings":["NE","Nijar","Republic of Niger","République du Niger"],"region":"Africa","subregion":"Western Africa","population":20715000,"latlng":[16.0,8.0],"demonym":"Nigerien","area":1267000.0,"gini":34.6,"timezones":["UTC+01:00"],"borders":["DZA","BEN","BFA","TCD","LBY","MLI","NGA"],"nativeName":"Niger","numericCode":"562","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Niger","es":"Níger","fr":"Niger","ja":"ニジェール","it":"Niger","br":"Níger","pt":"Níger","nl":"Niger","hr":"Niger","fa":"نیجر"},"flag":"https://restcountries.eu/data/ner.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"NIG"} -{"name":"Nigeria","topLevelDomain":[".ng"],"alpha2Code":"NG","alpha3Code":"NGA","callingCodes":["234"],"capital":"Abuja","altSpellings":["NG","Nijeriya","Naíjíríà","Federal Republic of Nigeria"],"region":"Africa","subregion":"Western Africa","population":186988000,"latlng":[10.0,8.0],"demonym":"Nigerian","area":923768.0,"gini":48.8,"timezones":["UTC+01:00"],"borders":["BEN","CMR","TCD","NER"],"nativeName":"Nigeria","numericCode":"566","currencies":[{"code":"NGN","name":"Nigerian naira","symbol":"₦"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Nigeria","es":"Nigeria","fr":"Nigéria","ja":"ナイジェリア","it":"Nigeria","br":"Nigéria","pt":"Nigéria","nl":"Nigeria","hr":"Nigerija","fa":"نیجریه"},"flag":"https://restcountries.eu/data/nga.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"NGR"} -{"name":"Niue","topLevelDomain":[".nu"],"alpha2Code":"NU","alpha3Code":"NIU","callingCodes":["683"],"capital":"Alofi","altSpellings":["NU"],"region":"Oceania","subregion":"Polynesia","population":1470,"latlng":[-19.03333333,-169.86666666],"demonym":"Niuean","area":260.0,"gini":null,"timezones":["UTC-11:00"],"borders":[],"nativeName":"Niuē","numericCode":"570","currencies":[{"code":"NZD","name":"New Zealand dollar","symbol":"$"},{"code":"(none)","name":"Niue dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Niue","es":"Niue","fr":"Niue","ja":"ニウエ","it":"Niue","br":"Niue","pt":"Niue","nl":"Niue","hr":"Niue","fa":"نیووی"},"flag":"https://restcountries.eu/data/niu.svg","regionalBlocs":[],"cioc":""} -{"name":"Norfolk Island","topLevelDomain":[".nf"],"alpha2Code":"NF","alpha3Code":"NFK","callingCodes":["672"],"capital":"Kingston","altSpellings":["NF","Territory of Norfolk Island","Teratri of Norf'k Ailen"],"region":"Oceania","subregion":"Australia and New Zealand","population":2302,"latlng":[-29.03333333,167.95],"demonym":"Norfolk Islander","area":36.0,"gini":null,"timezones":["UTC+11:30"],"borders":[],"nativeName":"Norfolk Island","numericCode":"574","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Norfolkinsel","es":"Isla de Norfolk","fr":"Île de Norfolk","ja":"ノーフォーク島","it":"Isola Norfolk","br":"Ilha Norfolk","pt":"Ilha Norfolk","nl":"Norfolkeiland","hr":"Otok Norfolk","fa":"جزیره نورفک"},"flag":"https://restcountries.eu/data/nfk.svg","regionalBlocs":[],"cioc":""} -{"name":"Korea (Democratic People's Republic of)","topLevelDomain":[".kp"],"alpha2Code":"KP","alpha3Code":"PRK","callingCodes":["850"],"capital":"Pyongyang","altSpellings":["KP","Democratic People's Republic of Korea","조선민주주의인민공화국","Chosŏn Minjujuŭi Inmin Konghwaguk"],"region":"Asia","subregion":"Eastern Asia","population":25281000,"latlng":[40.0,127.0],"demonym":"North Korean","area":120538.0,"gini":null,"timezones":["UTC+09:00"],"borders":["CHN","KOR","RUS"],"nativeName":"북한","numericCode":"408","currencies":[{"code":"KPW","name":"North Korean won","symbol":"₩"}],"languages":[{"iso639_1":"ko","iso639_2":"kor","name":"Korean","nativeName":"한국어"}],"translations":{"de":"Nordkorea","es":"Corea del Norte","fr":"Corée du Nord","ja":"朝鮮民主主義人民共和国","it":"Corea del Nord","br":"Coreia do Norte","pt":"Coreia do Norte","nl":"Noord-Korea","hr":"Sjeverna Koreja","fa":"کره جنوبی"},"flag":"https://restcountries.eu/data/prk.svg","regionalBlocs":[],"cioc":"PRK"} -{"name":"Northern Mariana Islands","topLevelDomain":[".mp"],"alpha2Code":"MP","alpha3Code":"MNP","callingCodes":["1670"],"capital":"Saipan","altSpellings":["MP","Commonwealth of the Northern Mariana Islands","Sankattan Siha Na Islas Mariånas"],"region":"Oceania","subregion":"Micronesia","population":56940,"latlng":[15.2,145.75],"demonym":"American","area":464.0,"gini":null,"timezones":["UTC+10:00"],"borders":[],"nativeName":"Northern Mariana Islands","numericCode":"580","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ch","iso639_2":"cha","name":"Chamorro","nativeName":"Chamoru"}],"translations":{"de":"Nördliche Marianen","es":"Islas Marianas del Norte","fr":"Îles Mariannes du Nord","ja":"北マリアナ諸島","it":"Isole Marianne Settentrionali","br":"Ilhas Marianas","pt":"Ilhas Marianas","nl":"Noordelijke Marianeneilanden","hr":"Sjevernomarijanski otoci","fa":"جزایر ماریانای شمالی"},"flag":"https://restcountries.eu/data/mnp.svg","regionalBlocs":[],"cioc":""} -{"name":"Norway","topLevelDomain":[".no"],"alpha2Code":"NO","alpha3Code":"NOR","callingCodes":["47"],"capital":"Oslo","altSpellings":["NO","Norge","Noreg","Kingdom of Norway","Kongeriket Norge","Kongeriket Noreg"],"region":"Europe","subregion":"Northern Europe","population":5223256,"latlng":[62.0,10.0],"demonym":"Norwegian","area":323802.0,"gini":25.8,"timezones":["UTC+01:00"],"borders":["FIN","SWE","RUS"],"nativeName":"Norge","numericCode":"578","currencies":[{"code":"NOK","name":"Norwegian krone","symbol":"kr"}],"languages":[{"iso639_1":"no","iso639_2":"nor","name":"Norwegian","nativeName":"Norsk"},{"iso639_1":"nb","iso639_2":"nob","name":"Norwegian Bokmål","nativeName":"Norsk bokmål"},{"iso639_1":"nn","iso639_2":"nno","name":"Norwegian Nynorsk","nativeName":"Norsk nynorsk"}],"translations":{"de":"Norwegen","es":"Noruega","fr":"Norvège","ja":"ノルウェー","it":"Norvegia","br":"Noruega","pt":"Noruega","nl":"Noorwegen","hr":"Norveška","fa":"نروژ"},"flag":"https://restcountries.eu/data/nor.svg","regionalBlocs":[{"acronym":"EFTA","name":"European Free Trade Association","otherAcronyms":[],"otherNames":[]}],"cioc":"NOR"} -{"name":"Oman","topLevelDomain":[".om"],"alpha2Code":"OM","alpha3Code":"OMN","callingCodes":["968"],"capital":"Muscat","altSpellings":["OM","Sultanate of Oman","Salṭanat ʻUmān"],"region":"Asia","subregion":"Western Asia","population":4420133,"latlng":[21.0,57.0],"demonym":"Omani","area":309500.0,"gini":null,"timezones":["UTC+04:00"],"borders":["SAU","ARE","YEM"],"nativeName":"عمان","numericCode":"512","currencies":[{"code":"OMR","name":"Omani rial","symbol":"ر.ع."}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Oman","es":"Omán","fr":"Oman","ja":"オマーン","it":"oman","br":"Omã","pt":"Omã","nl":"Oman","hr":"Oman","fa":"عمان"},"flag":"https://restcountries.eu/data/omn.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"OMA"} -{"name":"Pakistan","topLevelDomain":[".pk"],"alpha2Code":"PK","alpha3Code":"PAK","callingCodes":["92"],"capital":"Islamabad","altSpellings":["PK","Pākistān","Islamic Republic of Pakistan","Islāmī Jumhūriya'eh Pākistān"],"region":"Asia","subregion":"Southern Asia","population":194125062,"latlng":[30.0,70.0],"demonym":"Pakistani","area":881912.0,"gini":30.0,"timezones":["UTC+05:00"],"borders":["AFG","CHN","IND","IRN"],"nativeName":"Pakistan","numericCode":"586","currencies":[{"code":"PKR","name":"Pakistani rupee","symbol":"₨"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ur","iso639_2":"urd","name":"Urdu","nativeName":"اردو"}],"translations":{"de":"Pakistan","es":"Pakistán","fr":"Pakistan","ja":"パキスタン","it":"Pakistan","br":"Paquistão","pt":"Paquistão","nl":"Pakistan","hr":"Pakistan","fa":"پاکستان"},"flag":"https://restcountries.eu/data/pak.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"PAK"} -{"name":"Palau","topLevelDomain":[".pw"],"alpha2Code":"PW","alpha3Code":"PLW","callingCodes":["680"],"capital":"Ngerulmud","altSpellings":["PW","Republic of Palau","Beluu er a Belau"],"region":"Oceania","subregion":"Micronesia","population":17950,"latlng":[7.5,134.5],"demonym":"Palauan","area":459.0,"gini":null,"timezones":["UTC+09:00"],"borders":[],"nativeName":"Palau","numericCode":"585","currencies":[{"code":"(none)","name":"[E]","symbol":"$"},{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Palau","es":"Palau","fr":"Palaos","ja":"パラオ","it":"Palau","br":"Palau","pt":"Palau","nl":"Palau","hr":"Palau","fa":"پالائو"},"flag":"https://restcountries.eu/data/plw.svg","regionalBlocs":[],"cioc":"PLW"} -{"name":"Palestine, State of","topLevelDomain":[".ps"],"alpha2Code":"PS","alpha3Code":"PSE","callingCodes":["970"],"capital":"Ramallah","altSpellings":["PS","State of Palestine","Dawlat Filasṭin"],"region":"Asia","subregion":"Western Asia","population":4682467,"latlng":[31.9,35.2],"demonym":"Palestinian","area":null,"gini":35.5,"timezones":["UTC+02:00"],"borders":["ISR","EGY","JOR"],"nativeName":"فلسطين","numericCode":"275","currencies":[{"code":"ILS","name":"Israeli new sheqel","symbol":"₪"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Palästina","es":"Palestina","fr":"Palestine","ja":"パレスチナ","it":"Palestina","br":"Palestina","pt":"Palestina","nl":"Palestijnse gebieden","hr":"Palestina","fa":"فلسطین"},"flag":"https://restcountries.eu/data/pse.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"PLE"} -{"name":"Panama","topLevelDomain":[".pa"],"alpha2Code":"PA","alpha3Code":"PAN","callingCodes":["507"],"capital":"Panama City","altSpellings":["PA","Republic of Panama","República de Panamá"],"region":"Americas","subregion":"Central America","population":3814672,"latlng":[9.0,-80.0],"demonym":"Panamanian","area":75417.0,"gini":51.9,"timezones":["UTC-05:00"],"borders":["COL","CRI"],"nativeName":"Panamá","numericCode":"591","currencies":[{"code":"PAB","name":"Panamanian balboa","symbol":"B/."},{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Panama","es":"Panamá","fr":"Panama","ja":"パナマ","it":"Panama","br":"Panamá","pt":"Panamá","nl":"Panama","hr":"Panama","fa":"پاناما"},"flag":"https://restcountries.eu/data/pan.svg","regionalBlocs":[{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"PAN"} -{"name":"Papua New Guinea","topLevelDomain":[".pg"],"alpha2Code":"PG","alpha3Code":"PNG","callingCodes":["675"],"capital":"Port Moresby","altSpellings":["PG","Independent State of Papua New Guinea","Independen Stet bilong Papua Niugini"],"region":"Oceania","subregion":"Melanesia","population":8083700,"latlng":[-6.0,147.0],"demonym":"Papua New Guinean","area":462840.0,"gini":50.9,"timezones":["UTC+10:00"],"borders":["IDN"],"nativeName":"Papua Niugini","numericCode":"598","currencies":[{"code":"PGK","name":"Papua New Guinean kina","symbol":"K"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Papua-Neuguinea","es":"Papúa Nueva Guinea","fr":"Papouasie-Nouvelle-Guinée","ja":"パプアニューギニア","it":"Papua Nuova Guinea","br":"Papua Nova Guiné","pt":"Papua Nova Guiné","nl":"Papoea-Nieuw-Guinea","hr":"Papua Nova Gvineja","fa":"پاپوآ گینه نو"},"flag":"https://restcountries.eu/data/png.svg","regionalBlocs":[],"cioc":"PNG"} -{"name":"Paraguay","topLevelDomain":[".py"],"alpha2Code":"PY","alpha3Code":"PRY","callingCodes":["595"],"capital":"Asunción","altSpellings":["PY","Republic of Paraguay","República del Paraguay","Tetã Paraguái"],"region":"Americas","subregion":"South America","population":6854536,"latlng":[-23.0,-58.0],"demonym":"Paraguayan","area":406752.0,"gini":52.4,"timezones":["UTC-04:00"],"borders":["ARG","BOL","BRA"],"nativeName":"Paraguay","numericCode":"600","currencies":[{"code":"PYG","name":"Paraguayan guaraní","symbol":"₲"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"},{"iso639_1":"gn","iso639_2":"grn","name":"Guaraní","nativeName":"Avañe'ẽ"}],"translations":{"de":"Paraguay","es":"Paraguay","fr":"Paraguay","ja":"パラグアイ","it":"Paraguay","br":"Paraguai","pt":"Paraguai","nl":"Paraguay","hr":"Paragvaj","fa":"پاراگوئه"},"flag":"https://restcountries.eu/data/pry.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"PAR"} -{"name":"Peru","topLevelDomain":[".pe"],"alpha2Code":"PE","alpha3Code":"PER","callingCodes":["51"],"capital":"Lima","altSpellings":["PE","Republic of Peru"," República del Perú"],"region":"Americas","subregion":"South America","population":31488700,"latlng":[-10.0,-76.0],"demonym":"Peruvian","area":1285216.0,"gini":48.1,"timezones":["UTC-05:00"],"borders":["BOL","BRA","CHL","COL","ECU"],"nativeName":"Perú","numericCode":"604","currencies":[{"code":"PEN","name":"Peruvian sol","symbol":"S/."}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Peru","es":"Perú","fr":"Pérou","ja":"ペルー","it":"Perù","br":"Peru","pt":"Peru","nl":"Peru","hr":"Peru","fa":"پرو"},"flag":"https://restcountries.eu/data/per.svg","regionalBlocs":[{"acronym":"PA","name":"Pacific Alliance","otherAcronyms":[],"otherNames":["Alianza del Pacífico"]},{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"PER"} -{"name":"Philippines","topLevelDomain":[".ph"],"alpha2Code":"PH","alpha3Code":"PHL","callingCodes":["63"],"capital":"Manila","altSpellings":["PH","Republic of the Philippines","Repúblika ng Pilipinas"],"region":"Asia","subregion":"South-Eastern Asia","population":103279800,"latlng":[13.0,122.0],"demonym":"Filipino","area":342353.0,"gini":43.0,"timezones":["UTC+08:00"],"borders":[],"nativeName":"Pilipinas","numericCode":"608","currencies":[{"code":"PHP","name":"Philippine peso","symbol":"₱"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Philippinen","es":"Filipinas","fr":"Philippines","ja":"フィリピン","it":"Filippine","br":"Filipinas","pt":"Filipinas","nl":"Filipijnen","hr":"Filipini","fa":"جزایر الندفیلیپین"},"flag":"https://restcountries.eu/data/phl.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"PHI"} -{"name":"Pitcairn","topLevelDomain":[".pn"],"alpha2Code":"PN","alpha3Code":"PCN","callingCodes":["64"],"capital":"Adamstown","altSpellings":["PN","Pitcairn Henderson Ducie and Oeno Islands"],"region":"Oceania","subregion":"Polynesia","population":56,"latlng":[-25.06666666,-130.1],"demonym":"Pitcairn Islander","area":47.0,"gini":null,"timezones":["UTC-08:00"],"borders":[],"nativeName":"Pitcairn Islands","numericCode":"612","currencies":[{"code":"NZD","name":"New Zealand dollar","symbol":"$"},{"code":null,"name":"Pitcairn Islands dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Pitcairn","es":"Islas Pitcairn","fr":"Îles Pitcairn","ja":"ピトケアン","it":"Isole Pitcairn","br":"Ilhas Pitcairn","pt":"Ilhas Picárnia","nl":"Pitcairneilanden","hr":"Pitcairnovo otočje","fa":"پیتکرن"},"flag":"https://restcountries.eu/data/pcn.svg","regionalBlocs":[],"cioc":""} -{"name":"Poland","topLevelDomain":[".pl"],"alpha2Code":"PL","alpha3Code":"POL","callingCodes":["48"],"capital":"Warsaw","altSpellings":["PL","Republic of Poland","Rzeczpospolita Polska"],"region":"Europe","subregion":"Eastern Europe","population":38437239,"latlng":[52.0,20.0],"demonym":"Polish","area":312679.0,"gini":34.1,"timezones":["UTC+01:00"],"borders":["BLR","CZE","DEU","LTU","RUS","SVK","UKR"],"nativeName":"Polska","numericCode":"616","currencies":[{"code":"PLN","name":"Polish złoty","symbol":"zł"}],"languages":[{"iso639_1":"pl","iso639_2":"pol","name":"Polish","nativeName":"język polski"}],"translations":{"de":"Polen","es":"Polonia","fr":"Pologne","ja":"ポーランド","it":"Polonia","br":"Polônia","pt":"Polónia","nl":"Polen","hr":"Poljska","fa":"لهستان"},"flag":"https://restcountries.eu/data/pol.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"POL"} -{"name":"Portugal","topLevelDomain":[".pt"],"alpha2Code":"PT","alpha3Code":"PRT","callingCodes":["351"],"capital":"Lisbon","altSpellings":["PT","Portuguesa","Portuguese Republic","República Portuguesa"],"region":"Europe","subregion":"Southern Europe","population":10374822,"latlng":[39.5,-8.0],"demonym":"Portuguese","area":92090.0,"gini":38.5,"timezones":["UTC-01:00","UTC"],"borders":["ESP"],"nativeName":"Portugal","numericCode":"620","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Portugal","es":"Portugal","fr":"Portugal","ja":"ポルトガル","it":"Portogallo","br":"Portugal","pt":"Portugal","nl":"Portugal","hr":"Portugal","fa":"پرتغال"},"flag":"https://restcountries.eu/data/prt.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"POR"} -{"name":"Puerto Rico","topLevelDomain":[".pr"],"alpha2Code":"PR","alpha3Code":"PRI","callingCodes":["1787","1939"],"capital":"San Juan","altSpellings":["PR","Commonwealth of Puerto Rico","Estado Libre Asociado de Puerto Rico"],"region":"Americas","subregion":"Caribbean","population":3474182,"latlng":[18.25,-66.5],"demonym":"Puerto Rican","area":8870.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Puerto Rico","numericCode":"630","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Puerto Rico","es":"Puerto Rico","fr":"Porto Rico","ja":"プエルトリコ","it":"Porto Rico","br":"Porto Rico","pt":"Porto Rico","nl":"Puerto Rico","hr":"Portoriko","fa":"پورتو ریکو"},"flag":"https://restcountries.eu/data/pri.svg","regionalBlocs":[],"cioc":"PUR"} -{"name":"Qatar","topLevelDomain":[".qa"],"alpha2Code":"QA","alpha3Code":"QAT","callingCodes":["974"],"capital":"Doha","altSpellings":["QA","State of Qatar","Dawlat Qaṭar"],"region":"Asia","subregion":"Western Asia","population":2587564,"latlng":[25.5,51.25],"demonym":"Qatari","area":11586.0,"gini":41.1,"timezones":["UTC+03:00"],"borders":["SAU"],"nativeName":"قطر","numericCode":"634","currencies":[{"code":"QAR","name":"Qatari riyal","symbol":"ر.ق"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Katar","es":"Catar","fr":"Qatar","ja":"カタール","it":"Qatar","br":"Catar","pt":"Catar","nl":"Qatar","hr":"Katar","fa":"قطر"},"flag":"https://restcountries.eu/data/qat.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"QAT"} -{"name":"Republic of Kosovo","topLevelDomain":[""],"alpha2Code":"XK","alpha3Code":"KOS","callingCodes":["383"],"capital":"Pristina","altSpellings":["XK","Република Косово"],"region":"Europe","subregion":"Eastern Europe","population":1733842,"latlng":[42.666667,21.166667],"demonym":"Kosovar","area":10908.0,"gini":null,"timezones":["UTC+01:00"],"borders":["ALB","MKD","MNE","SRB"],"nativeName":"Republika e Kosovës","numericCode":null,"currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"sq","iso639_2":"sqi","name":"Albanian","nativeName":"Shqip"},{"iso639_1":"sr","iso639_2":"srp","name":"Serbian","nativeName":"српски језик"}],"translations":{"de":null,"es":"Kosovo","fr":null,"ja":null,"it":null,"br":"Kosovo","pt":"Kosovo","nl":null,"hr":"Kosovo","fa":"کوزوو"},"flag":"https://restcountries.eu/data/kos.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":null} -{"name":"Réunion","topLevelDomain":[".re"],"alpha2Code":"RE","alpha3Code":"REU","callingCodes":["262"],"capital":"Saint-Denis","altSpellings":["RE","Reunion"],"region":"Africa","subregion":"Eastern Africa","population":840974,"latlng":[-21.15,55.5],"demonym":"French","area":null,"gini":null,"timezones":["UTC+04:00"],"borders":[],"nativeName":"La Réunion","numericCode":"638","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Réunion","es":"Reunión","fr":"Réunion","ja":"レユニオン","it":"Riunione","br":"Reunião","pt":"Reunião","nl":"Réunion","hr":"Réunion","fa":"رئونیون"},"flag":"https://restcountries.eu/data/reu.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":""} -{"name":"Romania","topLevelDomain":[".ro"],"alpha2Code":"RO","alpha3Code":"ROU","callingCodes":["40"],"capital":"Bucharest","altSpellings":["RO","Rumania","Roumania","România"],"region":"Europe","subregion":"Eastern Europe","population":19861408,"latlng":[46.0,25.0],"demonym":"Romanian","area":238391.0,"gini":30.0,"timezones":["UTC+02:00"],"borders":["BGR","HUN","MDA","SRB","UKR"],"nativeName":"România","numericCode":"642","currencies":[{"code":"RON","name":"Romanian leu","symbol":"lei"}],"languages":[{"iso639_1":"ro","iso639_2":"ron","name":"Romanian","nativeName":"Română"}],"translations":{"de":"Rumänien","es":"Rumania","fr":"Roumanie","ja":"ルーマニア","it":"Romania","br":"Romênia","pt":"Roménia","nl":"Roemenië","hr":"Rumunjska","fa":"رومانی"},"flag":"https://restcountries.eu/data/rou.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"ROU"} -{"name":"Russian Federation","topLevelDomain":[".ru"],"alpha2Code":"RU","alpha3Code":"RUS","callingCodes":["7"],"capital":"Moscow","altSpellings":["RU","Rossiya","Russian Federation","Российская Федерация","Rossiyskaya Federatsiya"],"region":"Europe","subregion":"Eastern Europe","population":146599183,"latlng":[60.0,100.0],"demonym":"Russian","area":1.7124442E7,"gini":40.1,"timezones":["UTC+03:00","UTC+04:00","UTC+06:00","UTC+07:00","UTC+08:00","UTC+09:00","UTC+10:00","UTC+11:00","UTC+12:00"],"borders":["AZE","BLR","CHN","EST","FIN","GEO","KAZ","PRK","LVA","LTU","MNG","NOR","POL","UKR"],"nativeName":"Россия","numericCode":"643","currencies":[{"code":"RUB","name":"Russian ruble","symbol":"₽"}],"languages":[{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Russland","es":"Rusia","fr":"Russie","ja":"ロシア連邦","it":"Russia","br":"Rússia","pt":"Rússia","nl":"Rusland","hr":"Rusija","fa":"روسیه"},"flag":"https://restcountries.eu/data/rus.svg","regionalBlocs":[{"acronym":"EEU","name":"Eurasian Economic Union","otherAcronyms":["EAEU"],"otherNames":[]}],"cioc":"RUS"} -{"name":"Rwanda","topLevelDomain":[".rw"],"alpha2Code":"RW","alpha3Code":"RWA","callingCodes":["250"],"capital":"Kigali","altSpellings":["RW","Republic of Rwanda","Repubulika y'u Rwanda","République du Rwanda"],"region":"Africa","subregion":"Eastern Africa","population":11553188,"latlng":[-2.0,30.0],"demonym":"Rwandan","area":26338.0,"gini":50.8,"timezones":["UTC+02:00"],"borders":["BDI","COD","TZA","UGA"],"nativeName":"Rwanda","numericCode":"646","currencies":[{"code":"RWF","name":"Rwandan franc","symbol":"Fr"}],"languages":[{"iso639_1":"rw","iso639_2":"kin","name":"Kinyarwanda","nativeName":"Ikinyarwanda"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Ruanda","es":"Ruanda","fr":"Rwanda","ja":"ルワンダ","it":"Ruanda","br":"Ruanda","pt":"Ruanda","nl":"Rwanda","hr":"Ruanda","fa":"رواندا"},"flag":"https://restcountries.eu/data/rwa.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"RWA"} -{"name":"Saint Barthélemy","topLevelDomain":[".bl"],"alpha2Code":"BL","alpha3Code":"BLM","callingCodes":["590"],"capital":"Gustavia","altSpellings":["BL","St. Barthelemy","Collectivity of Saint Barthélemy","Collectivité de Saint-Barthélemy"],"region":"Americas","subregion":"Caribbean","population":9417,"latlng":[18.5,-63.41666666],"demonym":"Saint Barthélemy Islander","area":21.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Saint-Barthélemy","numericCode":"652","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Saint-Barthélemy","es":"San Bartolomé","fr":"Saint-Barthélemy","ja":"サン・バルテルミー","it":"Antille Francesi","br":"São Bartolomeu","pt":"São Bartolomeu","nl":"Saint Barthélemy","hr":"Saint Barthélemy","fa":"سن-بارتلمی"},"flag":"https://restcountries.eu/data/blm.svg","regionalBlocs":[],"cioc":""} -{"name":"Saint Helena, Ascension and Tristan da Cunha","topLevelDomain":[".sh"],"alpha2Code":"SH","alpha3Code":"SHN","callingCodes":["290"],"capital":"Jamestown","altSpellings":["SH"],"region":"Africa","subregion":"Western Africa","population":4255,"latlng":[-15.95,-5.7],"demonym":"Saint Helenian","area":null,"gini":null,"timezones":["UTC+00:00"],"borders":[],"nativeName":"Saint Helena","numericCode":"654","currencies":[{"code":"SHP","name":"Saint Helena pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Sankt Helena","es":"Santa Helena","fr":"Sainte-Hélène","ja":"セントヘレナ・アセンションおよびトリスタンダクーニャ","it":"Sant'Elena","br":"Santa Helena","pt":"Santa Helena","nl":"Sint-Helena","hr":"Sveta Helena","fa":"سنت هلنا، اسنشن و تریستان دا کونا"},"flag":"https://restcountries.eu/data/shn.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":null} -{"name":"Saint Kitts and Nevis","topLevelDomain":[".kn"],"alpha2Code":"KN","alpha3Code":"KNA","callingCodes":["1869"],"capital":"Basseterre","altSpellings":["KN","Federation of Saint Christopher and Nevis"],"region":"Americas","subregion":"Caribbean","population":46204,"latlng":[17.33333333,-62.75],"demonym":"Kittian and Nevisian","area":261.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Saint Kitts and Nevis","numericCode":"659","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"St. Kitts und Nevis","es":"San Cristóbal y Nieves","fr":"Saint-Christophe-et-Niévès","ja":"セントクリストファー・ネイビス","it":"Saint Kitts e Nevis","br":"São Cristóvão e Neves","pt":"São Cristóvão e Neves","nl":"Saint Kitts en Nevis","hr":"Sveti Kristof i Nevis","fa":"سنت کیتس و نویس"},"flag":"https://restcountries.eu/data/kna.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"SKN"} -{"name":"Saint Lucia","topLevelDomain":[".lc"],"alpha2Code":"LC","alpha3Code":"LCA","callingCodes":["1758"],"capital":"Castries","altSpellings":["LC"],"region":"Americas","subregion":"Caribbean","population":186000,"latlng":[13.88333333,-60.96666666],"demonym":"Saint Lucian","area":616.0,"gini":42.6,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Saint Lucia","numericCode":"662","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Saint Lucia","es":"Santa Lucía","fr":"Saint-Lucie","ja":"セントルシア","it":"Santa Lucia","br":"Santa Lúcia","pt":"Santa Lúcia","nl":"Saint Lucia","hr":"Sveta Lucija","fa":"سنت لوسیا"},"flag":"https://restcountries.eu/data/lca.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"LCA"} -{"name":"Saint Martin (French part)","topLevelDomain":[".mf",".fr",".gp"],"alpha2Code":"MF","alpha3Code":"MAF","callingCodes":["590"],"capital":"Marigot","altSpellings":["MF","Collectivity of Saint Martin","Collectivité de Saint-Martin"],"region":"Americas","subregion":"Caribbean","population":36979,"latlng":[18.08333333,-63.95],"demonym":"Saint Martin Islander","area":53.0,"gini":null,"timezones":["UTC-04:00"],"borders":["SXM","NLD"],"nativeName":"Saint-Martin","numericCode":"663","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"}],"translations":{"de":"Saint Martin","es":"Saint Martin","fr":"Saint-Martin","ja":"サン・マルタン(フランス領)","it":"Saint Martin","br":"Saint Martin","pt":"Ilha São Martinho","nl":"Saint-Martin","hr":"Sveti Martin","fa":"سینت مارتن"},"flag":"https://restcountries.eu/data/maf.svg","regionalBlocs":[],"cioc":""} -{"name":"Saint Pierre and Miquelon","topLevelDomain":[".pm"],"alpha2Code":"PM","alpha3Code":"SPM","callingCodes":["508"],"capital":"Saint-Pierre","altSpellings":["PM","Collectivité territoriale de Saint-Pierre-et-Miquelon"],"region":"Americas","subregion":"Northern America","population":6069,"latlng":[46.83333333,-56.33333333],"demonym":"French","area":242.0,"gini":null,"timezones":["UTC-03:00"],"borders":[],"nativeName":"Saint-Pierre-et-Miquelon","numericCode":"666","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Saint-Pierre und Miquelon","es":"San Pedro y Miquelón","fr":"Saint-Pierre-et-Miquelon","ja":"サンピエール島・ミクロン島","it":"Saint-Pierre e Miquelon","br":"Saint-Pierre e Miquelon","pt":"São Pedro e Miquelon","nl":"Saint Pierre en Miquelon","hr":"Sveti Petar i Mikelon","fa":"سن پیر و میکلن"},"flag":"https://restcountries.eu/data/spm.svg","regionalBlocs":[],"cioc":""} -{"name":"Saint Vincent and the Grenadines","topLevelDomain":[".vc"],"alpha2Code":"VC","alpha3Code":"VCT","callingCodes":["1784"],"capital":"Kingstown","altSpellings":["VC"],"region":"Americas","subregion":"Caribbean","population":109991,"latlng":[13.25,-61.2],"demonym":"Saint Vincentian","area":389.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Saint Vincent and the Grenadines","numericCode":"670","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Saint Vincent und die Grenadinen","es":"San Vicente y Granadinas","fr":"Saint-Vincent-et-les-Grenadines","ja":"セントビンセントおよびグレナディーン諸島","it":"Saint Vincent e Grenadine","br":"São Vicente e Granadinas","pt":"São Vicente e Granadinas","nl":"Saint Vincent en de Grenadines","hr":"Sveti Vincent i Grenadini","fa":"سنت وینسنت و گرنادین‌ها"},"flag":"https://restcountries.eu/data/vct.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"VIN"} -{"name":"Samoa","topLevelDomain":[".ws"],"alpha2Code":"WS","alpha3Code":"WSM","callingCodes":["685"],"capital":"Apia","altSpellings":["WS","Independent State of Samoa","Malo Saʻoloto Tutoʻatasi o Sāmoa"],"region":"Oceania","subregion":"Polynesia","population":194899,"latlng":[-13.58333333,-172.33333333],"demonym":"Samoan","area":2842.0,"gini":null,"timezones":["UTC+13:00"],"borders":[],"nativeName":"Samoa","numericCode":"882","currencies":[{"code":"WST","name":"Samoan tālā","symbol":"T"}],"languages":[{"iso639_1":"sm","iso639_2":"smo","name":"Samoan","nativeName":"gagana fa'a Samoa"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Samoa","es":"Samoa","fr":"Samoa","ja":"サモア","it":"Samoa","br":"Samoa","pt":"Samoa","nl":"Samoa","hr":"Samoa","fa":"ساموآ"},"flag":"https://restcountries.eu/data/wsm.svg","regionalBlocs":[],"cioc":"SAM"} -{"name":"San Marino","topLevelDomain":[".sm"],"alpha2Code":"SM","alpha3Code":"SMR","callingCodes":["378"],"capital":"City of San Marino","altSpellings":["SM","Republic of San Marino","Repubblica di San Marino"],"region":"Europe","subregion":"Southern Europe","population":33005,"latlng":[43.76666666,12.41666666],"demonym":"Sammarinese","area":61.0,"gini":null,"timezones":["UTC+01:00"],"borders":["ITA"],"nativeName":"San Marino","numericCode":"674","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"it","iso639_2":"ita","name":"Italian","nativeName":"Italiano"}],"translations":{"de":"San Marino","es":"San Marino","fr":"Saint-Marin","ja":"サンマリノ","it":"San Marino","br":"San Marino","pt":"São Marinho","nl":"San Marino","hr":"San Marino","fa":"سان مارینو"},"flag":"https://restcountries.eu/data/smr.svg","regionalBlocs":[],"cioc":"SMR"} -{"name":"Sao Tome and Principe","topLevelDomain":[".st"],"alpha2Code":"ST","alpha3Code":"STP","callingCodes":["239"],"capital":"São Tomé","altSpellings":["ST","Democratic Republic of São Tomé and Príncipe","República Democrática de São Tomé e Príncipe"],"region":"Africa","subregion":"Middle Africa","population":187356,"latlng":[1.0,7.0],"demonym":"Sao Tomean","area":964.0,"gini":50.8,"timezones":["UTC"],"borders":[],"nativeName":"São Tomé e Príncipe","numericCode":"678","currencies":[{"code":"STD","name":"São Tomé and Príncipe dobra","symbol":"Db"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"São Tomé und Príncipe","es":"Santo Tomé y Príncipe","fr":"Sao Tomé-et-Principe","ja":"サントメ・プリンシペ","it":"São Tomé e Príncipe","br":"São Tomé e Príncipe","pt":"São Tomé e Príncipe","nl":"Sao Tomé en Principe","hr":"Sveti Toma i Princip","fa":"کواترو دو فرویرو"},"flag":"https://restcountries.eu/data/stp.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"STP"} -{"name":"Saudi Arabia","topLevelDomain":[".sa"],"alpha2Code":"SA","alpha3Code":"SAU","callingCodes":["966"],"capital":"Riyadh","altSpellings":["SA","Kingdom of Saudi Arabia","Al-Mamlakah al-‘Arabiyyah as-Su‘ūdiyyah"],"region":"Asia","subregion":"Western Asia","population":32248200,"latlng":[25.0,45.0],"demonym":"Saudi Arabian","area":2149690.0,"gini":null,"timezones":["UTC+03:00"],"borders":["IRQ","JOR","KWT","OMN","QAT","ARE","YEM"],"nativeName":"العربية السعودية","numericCode":"682","currencies":[{"code":"SAR","name":"Saudi riyal","symbol":"ر.س"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Saudi-Arabien","es":"Arabia Saudí","fr":"Arabie Saoudite","ja":"サウジアラビア","it":"Arabia Saudita","br":"Arábia Saudita","pt":"Arábia Saudita","nl":"Saoedi-Arabië","hr":"Saudijska Arabija","fa":"عربستان سعودی"},"flag":"https://restcountries.eu/data/sau.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"KSA"} -{"name":"Senegal","topLevelDomain":[".sn"],"alpha2Code":"SN","alpha3Code":"SEN","callingCodes":["221"],"capital":"Dakar","altSpellings":["SN","Republic of Senegal","République du Sénégal"],"region":"Africa","subregion":"Western Africa","population":14799859,"latlng":[14.0,-14.0],"demonym":"Senegalese","area":196722.0,"gini":39.2,"timezones":["UTC"],"borders":["GMB","GIN","GNB","MLI","MRT"],"nativeName":"Sénégal","numericCode":"686","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Senegal","es":"Senegal","fr":"Sénégal","ja":"セネガル","it":"Senegal","br":"Senegal","pt":"Senegal","nl":"Senegal","hr":"Senegal","fa":"سنگال"},"flag":"https://restcountries.eu/data/sen.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"SEN"} -{"name":"Serbia","topLevelDomain":[".rs"],"alpha2Code":"RS","alpha3Code":"SRB","callingCodes":["381"],"capital":"Belgrade","altSpellings":["RS","Srbija","Republic of Serbia","Република Србија","Republika Srbija"],"region":"Europe","subregion":"Southern Europe","population":7076372,"latlng":[44.0,21.0],"demonym":"Serbian","area":88361.0,"gini":27.8,"timezones":["UTC+01:00"],"borders":["BIH","BGR","HRV","HUN","KOS","MKD","MNE","ROU"],"nativeName":"Србија","numericCode":"688","currencies":[{"code":"RSD","name":"Serbian dinar","symbol":"дин."}],"languages":[{"iso639_1":"sr","iso639_2":"srp","name":"Serbian","nativeName":"српски језик"}],"translations":{"de":"Serbien","es":"Serbia","fr":"Serbie","ja":"セルビア","it":"Serbia","br":"Sérvia","pt":"Sérvia","nl":"Servië","hr":"Srbija","fa":"صربستان"},"flag":"https://restcountries.eu/data/srb.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":"SRB"} -{"name":"Seychelles","topLevelDomain":[".sc"],"alpha2Code":"SC","alpha3Code":"SYC","callingCodes":["248"],"capital":"Victoria","altSpellings":["SC","Republic of Seychelles","Repiblik Sesel","République des Seychelles"],"region":"Africa","subregion":"Eastern Africa","population":91400,"latlng":[-4.58333333,55.66666666],"demonym":"Seychellois","area":452.0,"gini":65.8,"timezones":["UTC+04:00"],"borders":[],"nativeName":"Seychelles","numericCode":"690","currencies":[{"code":"SCR","name":"Seychellois rupee","symbol":"₨"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Seychellen","es":"Seychelles","fr":"Seychelles","ja":"セーシェル","it":"Seychelles","br":"Seicheles","pt":"Seicheles","nl":"Seychellen","hr":"Sejšeli","fa":"سیشل"},"flag":"https://restcountries.eu/data/syc.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"SEY"} -{"name":"Sierra Leone","topLevelDomain":[".sl"],"alpha2Code":"SL","alpha3Code":"SLE","callingCodes":["232"],"capital":"Freetown","altSpellings":["SL","Republic of Sierra Leone"],"region":"Africa","subregion":"Western Africa","population":7075641,"latlng":[8.5,-11.5],"demonym":"Sierra Leonean","area":71740.0,"gini":42.5,"timezones":["UTC"],"borders":["GIN","LBR"],"nativeName":"Sierra Leone","numericCode":"694","currencies":[{"code":"SLL","name":"Sierra Leonean leone","symbol":"Le"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Sierra Leone","es":"Sierra Leone","fr":"Sierra Leone","ja":"シエラレオネ","it":"Sierra Leone","br":"Serra Leoa","pt":"Serra Leoa","nl":"Sierra Leone","hr":"Sijera Leone","fa":"سیرالئون"},"flag":"https://restcountries.eu/data/sle.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"SLE"} -{"name":"Singapore","topLevelDomain":[".sg"],"alpha2Code":"SG","alpha3Code":"SGP","callingCodes":["65"],"capital":"Singapore","altSpellings":["SG","Singapura","Republik Singapura","新加坡共和国"],"region":"Asia","subregion":"South-Eastern Asia","population":5535000,"latlng":[1.36666666,103.8],"demonym":"Singaporean","area":710.0,"gini":48.1,"timezones":["UTC+08:00"],"borders":[],"nativeName":"Singapore","numericCode":"702","currencies":[{"code":"BND","name":"Brunei dollar","symbol":"$"},{"code":"SGD","name":"Singapore dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ms","iso639_2":"msa","name":"Malay","nativeName":"bahasa Melayu"},{"iso639_1":"ta","iso639_2":"tam","name":"Tamil","nativeName":"தமிழ்"},{"iso639_1":"zh","iso639_2":"zho","name":"Chinese","nativeName":"中文 (Zhōngwén)"}],"translations":{"de":"Singapur","es":"Singapur","fr":"Singapour","ja":"シンガポール","it":"Singapore","br":"Singapura","pt":"Singapura","nl":"Singapore","hr":"Singapur","fa":"سنگاپور"},"flag":"https://restcountries.eu/data/sgp.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"SIN"} -{"name":"Sint Maarten (Dutch part)","topLevelDomain":[".sx"],"alpha2Code":"SX","alpha3Code":"SXM","callingCodes":["1721"],"capital":"Philipsburg","altSpellings":["SX"],"region":"Americas","subregion":"Caribbean","population":38247,"latlng":[18.033333,-63.05],"demonym":"Dutch","area":34.0,"gini":null,"timezones":["UTC-04:00"],"borders":["MAF"],"nativeName":"Sint Maarten","numericCode":"534","currencies":[{"code":"ANG","name":"Netherlands Antillean guilder","symbol":"ƒ"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Sint Maarten (niederl. Teil)","es":null,"fr":"Saint Martin (partie néerlandaise)","ja":null,"it":"Saint Martin (parte olandese)","br":"Sint Maarten","pt":"São Martinho","nl":"Sint Maarten","hr":null,"fa":"سینت مارتن"},"flag":"https://restcountries.eu/data/sxm.svg","regionalBlocs":[],"cioc":""} -{"name":"Slovakia","topLevelDomain":[".sk"],"alpha2Code":"SK","alpha3Code":"SVK","callingCodes":["421"],"capital":"Bratislava","altSpellings":["SK","Slovak Republic","Slovenská republika"],"region":"Europe","subregion":"Eastern Europe","population":5426252,"latlng":[48.66666666,19.5],"demonym":"Slovak","area":49037.0,"gini":26.0,"timezones":["UTC+01:00"],"borders":["AUT","CZE","HUN","POL","UKR"],"nativeName":"Slovensko","numericCode":"703","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"sk","iso639_2":"slk","name":"Slovak","nativeName":"slovenčina"}],"translations":{"de":"Slowakei","es":"República Eslovaca","fr":"Slovaquie","ja":"スロバキア","it":"Slovacchia","br":"Eslováquia","pt":"Eslováquia","nl":"Slowakije","hr":"Slovačka","fa":"اسلواکی"},"flag":"https://restcountries.eu/data/svk.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"SVK"} -{"name":"Slovenia","topLevelDomain":[".si"],"alpha2Code":"SI","alpha3Code":"SVN","callingCodes":["386"],"capital":"Ljubljana","altSpellings":["SI","Republic of Slovenia","Republika Slovenija"],"region":"Europe","subregion":"Southern Europe","population":2064188,"latlng":[46.11666666,14.81666666],"demonym":"Slovene","area":20273.0,"gini":31.2,"timezones":["UTC+01:00"],"borders":["AUT","HRV","ITA","HUN"],"nativeName":"Slovenija","numericCode":"705","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"sl","iso639_2":"slv","name":"Slovene","nativeName":"slovenski jezik"}],"translations":{"de":"Slowenien","es":"Eslovenia","fr":"Slovénie","ja":"スロベニア","it":"Slovenia","br":"Eslovênia","pt":"Eslovénia","nl":"Slovenië","hr":"Slovenija","fa":"اسلوونی"},"flag":"https://restcountries.eu/data/svn.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"SLO"} -{"name":"Solomon Islands","topLevelDomain":[".sb"],"alpha2Code":"SB","alpha3Code":"SLB","callingCodes":["677"],"capital":"Honiara","altSpellings":["SB"],"region":"Oceania","subregion":"Melanesia","population":642000,"latlng":[-8.0,159.0],"demonym":"Solomon Islander","area":28896.0,"gini":null,"timezones":["UTC+11:00"],"borders":[],"nativeName":"Solomon Islands","numericCode":"090","currencies":[{"code":"SBD","name":"Solomon Islands dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Salomonen","es":"Islas Salomón","fr":"Îles Salomon","ja":"ソロモン諸島","it":"Isole Salomone","br":"Ilhas Salomão","pt":"Ilhas Salomão","nl":"Salomonseilanden","hr":"Solomonski Otoci","fa":"جزایر سلیمان"},"flag":"https://restcountries.eu/data/slb.svg","regionalBlocs":[],"cioc":"SOL"} -{"name":"Somalia","topLevelDomain":[".so"],"alpha2Code":"SO","alpha3Code":"SOM","callingCodes":["252"],"capital":"Mogadishu","altSpellings":["SO","aṣ-Ṣūmāl","Federal Republic of Somalia","Jamhuuriyadda Federaalka Soomaaliya","Jumhūriyyat aṣ-Ṣūmāl al-Fiderāliyya"],"region":"Africa","subregion":"Eastern Africa","population":11079000,"latlng":[10.0,49.0],"demonym":"Somali","area":637657.0,"gini":null,"timezones":["UTC+03:00"],"borders":["DJI","ETH","KEN"],"nativeName":"Soomaaliya","numericCode":"706","currencies":[{"code":"SOS","name":"Somali shilling","symbol":"Sh"}],"languages":[{"iso639_1":"so","iso639_2":"som","name":"Somali","nativeName":"Soomaaliga"},{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Somalia","es":"Somalia","fr":"Somalie","ja":"ソマリア","it":"Somalia","br":"Somália","pt":"Somália","nl":"Somalië","hr":"Somalija","fa":"سومالی"},"flag":"https://restcountries.eu/data/som.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"SOM"} -{"name":"South Africa","topLevelDomain":[".za"],"alpha2Code":"ZA","alpha3Code":"ZAF","callingCodes":["27"],"capital":"Pretoria","altSpellings":["ZA","RSA","Suid-Afrika","Republic of South Africa"],"region":"Africa","subregion":"Southern Africa","population":55653654,"latlng":[-29.0,24.0],"demonym":"South African","area":1221037.0,"gini":63.1,"timezones":["UTC+02:00"],"borders":["BWA","LSO","MOZ","NAM","SWZ","ZWE"],"nativeName":"South Africa","numericCode":"710","currencies":[{"code":"ZAR","name":"South African rand","symbol":"R"}],"languages":[{"iso639_1":"af","iso639_2":"afr","name":"Afrikaans","nativeName":"Afrikaans"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"nr","iso639_2":"nbl","name":"Southern Ndebele","nativeName":"isiNdebele"},{"iso639_1":"st","iso639_2":"sot","name":"Southern Sotho","nativeName":"Sesotho"},{"iso639_1":"ss","iso639_2":"ssw","name":"Swati","nativeName":"SiSwati"},{"iso639_1":"tn","iso639_2":"tsn","name":"Tswana","nativeName":"Setswana"},{"iso639_1":"ts","iso639_2":"tso","name":"Tsonga","nativeName":"Xitsonga"},{"iso639_1":"ve","iso639_2":"ven","name":"Venda","nativeName":"Tshivenḓa"},{"iso639_1":"xh","iso639_2":"xho","name":"Xhosa","nativeName":"isiXhosa"},{"iso639_1":"zu","iso639_2":"zul","name":"Zulu","nativeName":"isiZulu"}],"translations":{"de":"Republik Südafrika","es":"República de Sudáfrica","fr":"Afrique du Sud","ja":"南アフリカ","it":"Sud Africa","br":"República Sul-Africana","pt":"República Sul-Africana","nl":"Zuid-Afrika","hr":"Južnoafrička Republika","fa":"آفریقای جنوبی"},"flag":"https://restcountries.eu/data/zaf.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"RSA"} -{"name":"South Georgia and the South Sandwich Islands","topLevelDomain":[".gs"],"alpha2Code":"GS","alpha3Code":"SGS","callingCodes":["500"],"capital":"King Edward Point","altSpellings":["GS","South Georgia and the South Sandwich Islands"],"region":"Americas","subregion":"South America","population":30,"latlng":[-54.5,-37.0],"demonym":"South Georgia and the South Sandwich Islander","area":null,"gini":null,"timezones":["UTC-02:00"],"borders":[],"nativeName":"South Georgia","numericCode":"239","currencies":[{"code":"GBP","name":"British pound","symbol":"£"},{"code":"(none)","name":null,"symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Südgeorgien und die Südlichen Sandwichinseln","es":"Islas Georgias del Sur y Sandwich del Sur","fr":"Géorgie du Sud-et-les Îles Sandwich du Sud","ja":"サウスジョージア・サウスサンドウィッチ諸島","it":"Georgia del Sud e Isole Sandwich Meridionali","br":"Ilhas Geórgias do Sul e Sandwich do Sul","pt":"Ilhas Geórgia do Sul e Sanduíche do Sul","nl":"Zuid-Georgia en Zuidelijke Sandwicheilanden","hr":"Južna Georgija i otočje Južni Sandwich","fa":"جزایر جورجیای جنوبی و ساندویچ جنوبی"},"flag":"https://restcountries.eu/data/sgs.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":""} -{"name":"Korea (Republic of)","topLevelDomain":[".kr"],"alpha2Code":"KR","alpha3Code":"KOR","callingCodes":["82"],"capital":"Seoul","altSpellings":["KR","Republic of Korea"],"region":"Asia","subregion":"Eastern Asia","population":50801405,"latlng":[37.0,127.5],"demonym":"South Korean","area":100210.0,"gini":31.3,"timezones":["UTC+09:00"],"borders":["PRK"],"nativeName":"대한민국","numericCode":"410","currencies":[{"code":"KRW","name":"South Korean won","symbol":"₩"}],"languages":[{"iso639_1":"ko","iso639_2":"kor","name":"Korean","nativeName":"한국어"}],"translations":{"de":"Südkorea","es":"Corea del Sur","fr":"Corée du Sud","ja":"大韓民国","it":"Corea del Sud","br":"Coreia do Sul","pt":"Coreia do Sul","nl":"Zuid-Korea","hr":"Južna Koreja","fa":"کره شمالی"},"flag":"https://restcountries.eu/data/kor.svg","regionalBlocs":[],"cioc":"KOR"} -{"name":"South Sudan","topLevelDomain":[".ss"],"alpha2Code":"SS","alpha3Code":"SSD","callingCodes":["211"],"capital":"Juba","altSpellings":["SS"],"region":"Africa","subregion":"Middle Africa","population":12131000,"latlng":[7.0,30.0],"demonym":"South Sudanese","area":619745.0,"gini":45.5,"timezones":["UTC+03:00"],"borders":["CAF","COD","ETH","KEN","SDN","UGA"],"nativeName":"South Sudan","numericCode":"728","currencies":[{"code":"SSP","name":"South Sudanese pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Südsudan","es":"Sudán del Sur","fr":"Soudan du Sud","ja":"南スーダン","it":"Sudan del sud","br":"Sudão do Sul","pt":"Sudão do Sul","nl":"Zuid-Soedan","hr":"Južni Sudan","fa":"سودان جنوبی"},"flag":"https://restcountries.eu/data/ssd.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":""} -{"name":"Spain","topLevelDomain":[".es"],"alpha2Code":"ES","alpha3Code":"ESP","callingCodes":["34"],"capital":"Madrid","altSpellings":["ES","Kingdom of Spain","Reino de España"],"region":"Europe","subregion":"Southern Europe","population":46438422,"latlng":[40.0,-4.0],"demonym":"Spanish","area":505992.0,"gini":34.7,"timezones":["UTC","UTC+01:00"],"borders":["AND","FRA","GIB","PRT","MAR"],"nativeName":"España","numericCode":"724","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Spanien","es":"España","fr":"Espagne","ja":"スペイン","it":"Spagna","br":"Espanha","pt":"Espanha","nl":"Spanje","hr":"Španjolska","fa":"اسپانیا"},"flag":"https://restcountries.eu/data/esp.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"ESP"} -{"name":"Sri Lanka","topLevelDomain":[".lk"],"alpha2Code":"LK","alpha3Code":"LKA","callingCodes":["94"],"capital":"Colombo","altSpellings":["LK","ilaṅkai","Democratic Socialist Republic of Sri Lanka"],"region":"Asia","subregion":"Southern Asia","population":20966000,"latlng":[7.0,81.0],"demonym":"Sri Lankan","area":65610.0,"gini":40.3,"timezones":["UTC+05:30"],"borders":["IND"],"nativeName":"śrī laṃkāva","numericCode":"144","currencies":[{"code":"LKR","name":"Sri Lankan rupee","symbol":"Rs"}],"languages":[{"iso639_1":"si","iso639_2":"sin","name":"Sinhalese","nativeName":"සිංහල"},{"iso639_1":"ta","iso639_2":"tam","name":"Tamil","nativeName":"தமிழ்"}],"translations":{"de":"Sri Lanka","es":"Sri Lanka","fr":"Sri Lanka","ja":"スリランカ","it":"Sri Lanka","br":"Sri Lanka","pt":"Sri Lanka","nl":"Sri Lanka","hr":"Šri Lanka","fa":"سری‌لانکا"},"flag":"https://restcountries.eu/data/lka.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"SRI"} -{"name":"Sudan","topLevelDomain":[".sd"],"alpha2Code":"SD","alpha3Code":"SDN","callingCodes":["249"],"capital":"Khartoum","altSpellings":["SD","Republic of the Sudan","Jumhūrīyat as-Sūdān"],"region":"Africa","subregion":"Northern Africa","population":39598700,"latlng":[15.0,30.0],"demonym":"Sudanese","area":1886068.0,"gini":35.3,"timezones":["UTC+03:00"],"borders":["CAF","TCD","EGY","ERI","ETH","LBY","SSD"],"nativeName":"السودان","numericCode":"729","currencies":[{"code":"SDG","name":"Sudanese pound","symbol":"ج.س."}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Sudan","es":"Sudán","fr":"Soudan","ja":"スーダン","it":"Sudan","br":"Sudão","pt":"Sudão","nl":"Soedan","hr":"Sudan","fa":"سودان"},"flag":"https://restcountries.eu/data/sdn.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"SUD"} -{"name":"Suriname","topLevelDomain":[".sr"],"alpha2Code":"SR","alpha3Code":"SUR","callingCodes":["597"],"capital":"Paramaribo","altSpellings":["SR","Sarnam","Sranangron","Republic of Suriname","Republiek Suriname"],"region":"Americas","subregion":"South America","population":541638,"latlng":[4.0,-56.0],"demonym":"Surinamer","area":163820.0,"gini":52.9,"timezones":["UTC-03:00"],"borders":["BRA","GUF","FRA","GUY"],"nativeName":"Suriname","numericCode":"740","currencies":[{"code":"SRD","name":"Surinamese dollar","symbol":"$"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"}],"translations":{"de":"Suriname","es":"Surinam","fr":"Surinam","ja":"スリナム","it":"Suriname","br":"Suriname","pt":"Suriname","nl":"Suriname","hr":"Surinam","fa":"سورینام"},"flag":"https://restcountries.eu/data/sur.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]},{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"SUR"} -{"name":"Svalbard and Jan Mayen","topLevelDomain":[".sj"],"alpha2Code":"SJ","alpha3Code":"SJM","callingCodes":["4779"],"capital":"Longyearbyen","altSpellings":["SJ","Svalbard and Jan Mayen Islands"],"region":"Europe","subregion":"Northern Europe","population":2562,"latlng":[78.0,20.0],"demonym":"Norwegian","area":null,"gini":null,"timezones":["UTC+01:00"],"borders":[],"nativeName":"Svalbard og Jan Mayen","numericCode":"744","currencies":[{"code":"NOK","name":"Norwegian krone","symbol":"kr"}],"languages":[{"iso639_1":"no","iso639_2":"nor","name":"Norwegian","nativeName":"Norsk"}],"translations":{"de":"Svalbard und Jan Mayen","es":"Islas Svalbard y Jan Mayen","fr":"Svalbard et Jan Mayen","ja":"スヴァールバル諸島およびヤンマイエン島","it":"Svalbard e Jan Mayen","br":"Svalbard","pt":"Svalbard","nl":"Svalbard en Jan Mayen","hr":"Svalbard i Jan Mayen","fa":"سوالبارد و یان ماین"},"flag":"https://restcountries.eu/data/sjm.svg","regionalBlocs":[],"cioc":""} -{"name":"Swaziland","topLevelDomain":[".sz"],"alpha2Code":"SZ","alpha3Code":"SWZ","callingCodes":["268"],"capital":"Lobamba","altSpellings":["SZ","weSwatini","Swatini","Ngwane","Kingdom of Swaziland","Umbuso waseSwatini"],"region":"Africa","subregion":"Southern Africa","population":1132657,"latlng":[-26.5,31.5],"demonym":"Swazi","area":17364.0,"gini":51.5,"timezones":["UTC+02:00"],"borders":["MOZ","ZAF"],"nativeName":"Swaziland","numericCode":"748","currencies":[{"code":"SZL","name":"Swazi lilangeni","symbol":"L"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ss","iso639_2":"ssw","name":"Swati","nativeName":"SiSwati"}],"translations":{"de":"Swasiland","es":"Suazilandia","fr":"Swaziland","ja":"スワジランド","it":"Swaziland","br":"Suazilândia","pt":"Suazilândia","nl":"Swaziland","hr":"Svazi","fa":"سوازیلند"},"flag":"https://restcountries.eu/data/swz.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"SWZ"} -{"name":"Sweden","topLevelDomain":[".se"],"alpha2Code":"SE","alpha3Code":"SWE","callingCodes":["46"],"capital":"Stockholm","altSpellings":["SE","Kingdom of Sweden","Konungariket Sverige"],"region":"Europe","subregion":"Northern Europe","population":9894888,"latlng":[62.0,15.0],"demonym":"Swedish","area":450295.0,"gini":25.0,"timezones":["UTC+01:00"],"borders":["FIN","NOR"],"nativeName":"Sverige","numericCode":"752","currencies":[{"code":"SEK","name":"Swedish krona","symbol":"kr"}],"languages":[{"iso639_1":"sv","iso639_2":"swe","name":"Swedish","nativeName":"svenska"}],"translations":{"de":"Schweden","es":"Suecia","fr":"Suède","ja":"スウェーデン","it":"Svezia","br":"Suécia","pt":"Suécia","nl":"Zweden","hr":"Švedska","fa":"سوئد"},"flag":"https://restcountries.eu/data/swe.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"SWE"} -{"name":"Switzerland","topLevelDomain":[".ch"],"alpha2Code":"CH","alpha3Code":"CHE","callingCodes":["41"],"capital":"Bern","altSpellings":["CH","Swiss Confederation","Schweiz","Suisse","Svizzera","Svizra"],"region":"Europe","subregion":"Western Europe","population":8341600,"latlng":[47.0,8.0],"demonym":"Swiss","area":41284.0,"gini":33.7,"timezones":["UTC+01:00"],"borders":["AUT","FRA","ITA","LIE","DEU"],"nativeName":"Schweiz","numericCode":"756","currencies":[{"code":"CHF","name":"Swiss franc","symbol":"Fr"}],"languages":[{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"it","iso639_2":"ita","name":"Italian","nativeName":"Italiano"}],"translations":{"de":"Schweiz","es":"Suiza","fr":"Suisse","ja":"スイス","it":"Svizzera","br":"Suíça","pt":"Suíça","nl":"Zwitserland","hr":"Švicarska","fa":"سوئیس"},"flag":"https://restcountries.eu/data/che.svg","regionalBlocs":[{"acronym":"EFTA","name":"European Free Trade Association","otherAcronyms":[],"otherNames":[]}],"cioc":"SUI"} -{"name":"Syrian Arab Republic","topLevelDomain":[".sy"],"alpha2Code":"SY","alpha3Code":"SYR","callingCodes":["963"],"capital":"Damascus","altSpellings":["SY","Syrian Arab Republic","Al-Jumhūrīyah Al-ʻArabīyah As-Sūrīyah"],"region":"Asia","subregion":"Western Asia","population":18564000,"latlng":[35.0,38.0],"demonym":"Syrian","area":185180.0,"gini":35.8,"timezones":["UTC+02:00"],"borders":["IRQ","ISR","JOR","LBN","TUR"],"nativeName":"سوريا","numericCode":"760","currencies":[{"code":"SYP","name":"Syrian pound","symbol":"£"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Syrien","es":"Siria","fr":"Syrie","ja":"シリア・アラブ共和国","it":"Siria","br":"Síria","pt":"Síria","nl":"Syrië","hr":"Sirija","fa":"سوریه"},"flag":"https://restcountries.eu/data/syr.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"SYR"} -{"name":"Taiwan","topLevelDomain":[".tw"],"alpha2Code":"TW","alpha3Code":"TWN","callingCodes":["886"],"capital":"Taipei","altSpellings":["TW","Táiwān","Republic of China","中華民國","Zhōnghuá Mínguó"],"region":"Asia","subregion":"Eastern Asia","population":23503349,"latlng":[23.5,121.0],"demonym":"Taiwanese","area":36193.0,"gini":null,"timezones":["UTC+08:00"],"borders":[],"nativeName":"臺灣","numericCode":"158","currencies":[{"code":"TWD","name":"New Taiwan dollar","symbol":"$"}],"languages":[{"iso639_1":"zh","iso639_2":"zho","name":"Chinese","nativeName":"中文 (Zhōngwén)"}],"translations":{"de":"Taiwan","es":"Taiwán","fr":"Taïwan","ja":"台湾(中華民国)","it":"Taiwan","br":"Taiwan","pt":"Taiwan","nl":"Taiwan","hr":"Tajvan","fa":"تایوان"},"flag":"https://restcountries.eu/data/twn.svg","regionalBlocs":[],"cioc":"TPE"} -{"name":"Tajikistan","topLevelDomain":[".tj"],"alpha2Code":"TJ","alpha3Code":"TJK","callingCodes":["992"],"capital":"Dushanbe","altSpellings":["TJ","Toçikiston","Republic of Tajikistan","Ҷумҳурии Тоҷикистон","Çumhuriyi Toçikiston"],"region":"Asia","subregion":"Central Asia","population":8593600,"latlng":[39.0,71.0],"demonym":"Tadzhik","area":143100.0,"gini":30.8,"timezones":["UTC+05:00"],"borders":["AFG","CHN","KGZ","UZB"],"nativeName":"Тоҷикистон","numericCode":"762","currencies":[{"code":"TJS","name":"Tajikistani somoni","symbol":"ЅМ"}],"languages":[{"iso639_1":"tg","iso639_2":"tgk","name":"Tajik","nativeName":"тоҷикӣ"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Tadschikistan","es":"Tayikistán","fr":"Tadjikistan","ja":"タジキスタン","it":"Tagikistan","br":"Tajiquistão","pt":"Tajiquistão","nl":"Tadzjikistan","hr":"Tađikistan","fa":"تاجیکستان"},"flag":"https://restcountries.eu/data/tjk.svg","regionalBlocs":[],"cioc":"TJK"} -{"name":"Tanzania, United Republic of","topLevelDomain":[".tz"],"alpha2Code":"TZ","alpha3Code":"TZA","callingCodes":["255"],"capital":"Dodoma","altSpellings":["TZ","United Republic of Tanzania","Jamhuri ya Muungano wa Tanzania"],"region":"Africa","subregion":"Eastern Africa","population":55155000,"latlng":[-6.0,35.0],"demonym":"Tanzanian","area":945087.0,"gini":37.6,"timezones":["UTC+03:00"],"borders":["BDI","COD","KEN","MWI","MOZ","RWA","UGA","ZMB"],"nativeName":"Tanzania","numericCode":"834","currencies":[{"code":"TZS","name":"Tanzanian shilling","symbol":"Sh"}],"languages":[{"iso639_1":"sw","iso639_2":"swa","name":"Swahili","nativeName":"Kiswahili"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Tansania","es":"Tanzania","fr":"Tanzanie","ja":"タンザニア","it":"Tanzania","br":"Tanzânia","pt":"Tanzânia","nl":"Tanzania","hr":"Tanzanija","fa":"تانزانیا"},"flag":"https://restcountries.eu/data/tza.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"TAN"} -{"name":"Thailand","topLevelDomain":[".th"],"alpha2Code":"TH","alpha3Code":"THA","callingCodes":["66"],"capital":"Bangkok","altSpellings":["TH","Prathet","Thai","Kingdom of Thailand","ราชอาณาจักรไทย","Ratcha Anachak Thai"],"region":"Asia","subregion":"South-Eastern Asia","population":65327652,"latlng":[15.0,100.0],"demonym":"Thai","area":513120.0,"gini":40.0,"timezones":["UTC+07:00"],"borders":["MMR","KHM","LAO","MYS"],"nativeName":"ประเทศไทย","numericCode":"764","currencies":[{"code":"THB","name":"Thai baht","symbol":"฿"}],"languages":[{"iso639_1":"th","iso639_2":"tha","name":"Thai","nativeName":"ไทย"}],"translations":{"de":"Thailand","es":"Tailandia","fr":"Thaïlande","ja":"タイ","it":"Tailandia","br":"Tailândia","pt":"Tailândia","nl":"Thailand","hr":"Tajland","fa":"تایلند"},"flag":"https://restcountries.eu/data/tha.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"THA"} -{"name":"Timor-Leste","topLevelDomain":[".tl"],"alpha2Code":"TL","alpha3Code":"TLS","callingCodes":["670"],"capital":"Dili","altSpellings":["TL","East Timor","Democratic Republic of Timor-Leste","República Democrática de Timor-Leste","Repúblika Demokrátika Timór-Leste"],"region":"Asia","subregion":"South-Eastern Asia","population":1167242,"latlng":[-8.83333333,125.91666666],"demonym":"East Timorese","area":14874.0,"gini":31.9,"timezones":["UTC+09:00"],"borders":["IDN"],"nativeName":"Timor-Leste","numericCode":"626","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"},{"code":null,"name":null,"symbol":null}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Timor-Leste","es":"Timor Oriental","fr":"Timor oriental","ja":"東ティモール","it":"Timor Est","br":"Timor Leste","pt":"Timor Leste","nl":"Oost-Timor","hr":"Istočni Timor","fa":"تیمور شرقی"},"flag":"https://restcountries.eu/data/tls.svg","regionalBlocs":[],"cioc":"TLS"} -{"name":"Togo","topLevelDomain":[".tg"],"alpha2Code":"TG","alpha3Code":"TGO","callingCodes":["228"],"capital":"Lomé","altSpellings":["TG","Togolese","Togolese Republic","République Togolaise"],"region":"Africa","subregion":"Western Africa","population":7143000,"latlng":[8.0,1.16666666],"demonym":"Togolese","area":56785.0,"gini":34.4,"timezones":["UTC"],"borders":["BEN","BFA","GHA"],"nativeName":"Togo","numericCode":"768","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Togo","es":"Togo","fr":"Togo","ja":"トーゴ","it":"Togo","br":"Togo","pt":"Togo","nl":"Togo","hr":"Togo","fa":"توگو"},"flag":"https://restcountries.eu/data/tgo.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"TOG"} -{"name":"Tokelau","topLevelDomain":[".tk"],"alpha2Code":"TK","alpha3Code":"TKL","callingCodes":["690"],"capital":"Fakaofo","altSpellings":["TK"],"region":"Oceania","subregion":"Polynesia","population":1411,"latlng":[-9.0,-172.0],"demonym":"Tokelauan","area":12.0,"gini":null,"timezones":["UTC+13:00"],"borders":[],"nativeName":"Tokelau","numericCode":"772","currencies":[{"code":"NZD","name":"New Zealand dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Tokelau","es":"Islas Tokelau","fr":"Tokelau","ja":"トケラウ","it":"Isole Tokelau","br":"Tokelau","pt":"Toquelau","nl":"Tokelau","hr":"Tokelau","fa":"توکلائو"},"flag":"https://restcountries.eu/data/tkl.svg","regionalBlocs":[],"cioc":""} -{"name":"Tonga","topLevelDomain":[".to"],"alpha2Code":"TO","alpha3Code":"TON","callingCodes":["676"],"capital":"Nuku'alofa","altSpellings":["TO"],"region":"Oceania","subregion":"Polynesia","population":103252,"latlng":[-20.0,-175.0],"demonym":"Tongan","area":747.0,"gini":null,"timezones":["UTC+13:00"],"borders":[],"nativeName":"Tonga","numericCode":"776","currencies":[{"code":"TOP","name":"Tongan paʻanga","symbol":"T$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"to","iso639_2":"ton","name":"Tonga (Tonga Islands)","nativeName":"faka Tonga"}],"translations":{"de":"Tonga","es":"Tonga","fr":"Tonga","ja":"トンガ","it":"Tonga","br":"Tonga","pt":"Tonga","nl":"Tonga","hr":"Tonga","fa":"تونگا"},"flag":"https://restcountries.eu/data/ton.svg","regionalBlocs":[],"cioc":"TGA"} -{"name":"Trinidad and Tobago","topLevelDomain":[".tt"],"alpha2Code":"TT","alpha3Code":"TTO","callingCodes":["1868"],"capital":"Port of Spain","altSpellings":["TT","Republic of Trinidad and Tobago"],"region":"Americas","subregion":"Caribbean","population":1349667,"latlng":[11.0,-61.0],"demonym":"Trinidadian","area":5130.0,"gini":40.3,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Trinidad and Tobago","numericCode":"780","currencies":[{"code":"TTD","name":"Trinidad and Tobago dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Trinidad und Tobago","es":"Trinidad y Tobago","fr":"Trinité et Tobago","ja":"トリニダード・トバゴ","it":"Trinidad e Tobago","br":"Trinidad e Tobago","pt":"Trindade e Tobago","nl":"Trinidad en Tobago","hr":"Trinidad i Tobago","fa":"ترینیداد و توباگو"},"flag":"https://restcountries.eu/data/tto.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"TTO"} -{"name":"Tunisia","topLevelDomain":[".tn"],"alpha2Code":"TN","alpha3Code":"TUN","callingCodes":["216"],"capital":"Tunis","altSpellings":["TN","Republic of Tunisia","al-Jumhūriyyah at-Tūnisiyyah"],"region":"Africa","subregion":"Northern Africa","population":11154400,"latlng":[34.0,9.0],"demonym":"Tunisian","area":163610.0,"gini":41.4,"timezones":["UTC+01:00"],"borders":["DZA","LBY"],"nativeName":"تونس","numericCode":"788","currencies":[{"code":"TND","name":"Tunisian dinar","symbol":"د.ت"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Tunesien","es":"Túnez","fr":"Tunisie","ja":"チュニジア","it":"Tunisia","br":"Tunísia","pt":"Tunísia","nl":"Tunesië","hr":"Tunis","fa":"تونس"},"flag":"https://restcountries.eu/data/tun.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"TUN"} -{"name":"Turkey","topLevelDomain":[".tr"],"alpha2Code":"TR","alpha3Code":"TUR","callingCodes":["90"],"capital":"Ankara","altSpellings":["TR","Turkiye","Republic of Turkey","Türkiye Cumhuriyeti"],"region":"Asia","subregion":"Western Asia","population":78741053,"latlng":[39.0,35.0],"demonym":"Turkish","area":783562.0,"gini":39.0,"timezones":["UTC+03:00"],"borders":["ARM","AZE","BGR","GEO","GRC","IRN","IRQ","SYR"],"nativeName":"Türkiye","numericCode":"792","currencies":[{"code":"TRY","name":"Turkish lira","symbol":null}],"languages":[{"iso639_1":"tr","iso639_2":"tur","name":"Turkish","nativeName":"Türkçe"}],"translations":{"de":"Türkei","es":"Turquía","fr":"Turquie","ja":"トルコ","it":"Turchia","br":"Turquia","pt":"Turquia","nl":"Turkije","hr":"Turska","fa":"ترکیه"},"flag":"https://restcountries.eu/data/tur.svg","regionalBlocs":[],"cioc":"TUR"} -{"name":"Turkmenistan","topLevelDomain":[".tm"],"alpha2Code":"TM","alpha3Code":"TKM","callingCodes":["993"],"capital":"Ashgabat","altSpellings":["TM"],"region":"Asia","subregion":"Central Asia","population":4751120,"latlng":[40.0,60.0],"demonym":"Turkmen","area":488100.0,"gini":40.8,"timezones":["UTC+05:00"],"borders":["AFG","IRN","KAZ","UZB"],"nativeName":"Türkmenistan","numericCode":"795","currencies":[{"code":"TMT","name":"Turkmenistan manat","symbol":"m"}],"languages":[{"iso639_1":"tk","iso639_2":"tuk","name":"Turkmen","nativeName":"Türkmen"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Turkmenistan","es":"Turkmenistán","fr":"Turkménistan","ja":"トルクメニスタン","it":"Turkmenistan","br":"Turcomenistão","pt":"Turquemenistão","nl":"Turkmenistan","hr":"Turkmenistan","fa":"ترکمنستان"},"flag":"https://restcountries.eu/data/tkm.svg","regionalBlocs":[],"cioc":"TKM"} -{"name":"Turks and Caicos Islands","topLevelDomain":[".tc"],"alpha2Code":"TC","alpha3Code":"TCA","callingCodes":["1649"],"capital":"Cockburn Town","altSpellings":["TC"],"region":"Americas","subregion":"Caribbean","population":31458,"latlng":[21.75,-71.58333333],"demonym":"Turks and Caicos Islander","area":948.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Turks and Caicos Islands","numericCode":"796","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Turks- und Caicosinseln","es":"Islas Turks y Caicos","fr":"Îles Turques-et-Caïques","ja":"タークス・カイコス諸島","it":"Isole Turks e Caicos","br":"Ilhas Turcas e Caicos","pt":"Ilhas Turcas e Caicos","nl":"Turks- en Caicoseilanden","hr":"Otoci Turks i Caicos","fa":"جزایر تورکس و کایکوس"},"flag":"https://restcountries.eu/data/tca.svg","regionalBlocs":[],"cioc":""} -{"name":"Tuvalu","topLevelDomain":[".tv"],"alpha2Code":"TV","alpha3Code":"TUV","callingCodes":["688"],"capital":"Funafuti","altSpellings":["TV"],"region":"Oceania","subregion":"Polynesia","population":10640,"latlng":[-8.0,178.0],"demonym":"Tuvaluan","area":26.0,"gini":null,"timezones":["UTC+12:00"],"borders":[],"nativeName":"Tuvalu","numericCode":"798","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"},{"code":"TVD[G]","name":"Tuvaluan dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Tuvalu","es":"Tuvalu","fr":"Tuvalu","ja":"ツバル","it":"Tuvalu","br":"Tuvalu","pt":"Tuvalu","nl":"Tuvalu","hr":"Tuvalu","fa":"تووالو"},"flag":"https://restcountries.eu/data/tuv.svg","regionalBlocs":[],"cioc":"TUV"} -{"name":"Uganda","topLevelDomain":[".ug"],"alpha2Code":"UG","alpha3Code":"UGA","callingCodes":["256"],"capital":"Kampala","altSpellings":["UG","Republic of Uganda","Jamhuri ya Uganda"],"region":"Africa","subregion":"Eastern Africa","population":33860700,"latlng":[1.0,32.0],"demonym":"Ugandan","area":241550.0,"gini":44.3,"timezones":["UTC+03:00"],"borders":["COD","KEN","RWA","SSD","TZA"],"nativeName":"Uganda","numericCode":"800","currencies":[{"code":"UGX","name":"Ugandan shilling","symbol":"Sh"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"sw","iso639_2":"swa","name":"Swahili","nativeName":"Kiswahili"}],"translations":{"de":"Uganda","es":"Uganda","fr":"Uganda","ja":"ウガンダ","it":"Uganda","br":"Uganda","pt":"Uganda","nl":"Oeganda","hr":"Uganda","fa":"اوگاندا"},"flag":"https://restcountries.eu/data/uga.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"UGA"} -{"name":"Ukraine","topLevelDomain":[".ua"],"alpha2Code":"UA","alpha3Code":"UKR","callingCodes":["380"],"capital":"Kiev","altSpellings":["UA","Ukrayina"],"region":"Europe","subregion":"Eastern Europe","population":42692393,"latlng":[49.0,32.0],"demonym":"Ukrainian","area":603700.0,"gini":26.4,"timezones":["UTC+02:00"],"borders":["BLR","HUN","MDA","POL","ROU","RUS","SVK"],"nativeName":"Україна","numericCode":"804","currencies":[{"code":"UAH","name":"Ukrainian hryvnia","symbol":"₴"}],"languages":[{"iso639_1":"uk","iso639_2":"ukr","name":"Ukrainian","nativeName":"Українська"}],"translations":{"de":"Ukraine","es":"Ucrania","fr":"Ukraine","ja":"ウクライナ","it":"Ucraina","br":"Ucrânia","pt":"Ucrânia","nl":"Oekraïne","hr":"Ukrajina","fa":"وکراین"},"flag":"https://restcountries.eu/data/ukr.svg","regionalBlocs":[],"cioc":"UKR"} -{"name":"United Arab Emirates","topLevelDomain":[".ae"],"alpha2Code":"AE","alpha3Code":"ARE","callingCodes":["971"],"capital":"Abu Dhabi","altSpellings":["AE","UAE"],"region":"Asia","subregion":"Western Asia","population":9856000,"latlng":[24.0,54.0],"demonym":"Emirati","area":83600.0,"gini":null,"timezones":["UTC+04"],"borders":["OMN","SAU"],"nativeName":"دولة الإمارات العربية المتحدة","numericCode":"784","currencies":[{"code":"AED","name":"United Arab Emirates dirham","symbol":"د.إ"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Vereinigte Arabische Emirate","es":"Emiratos Árabes Unidos","fr":"Émirats arabes unis","ja":"アラブ首長国連邦","it":"Emirati Arabi Uniti","br":"Emirados árabes Unidos","pt":"Emirados árabes Unidos","nl":"Verenigde Arabische Emiraten","hr":"Ujedinjeni Arapski Emirati","fa":"امارات متحده عربی"},"flag":"https://restcountries.eu/data/are.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"UAE"} -{"name":"United Kingdom of Great Britain and Northern Ireland","topLevelDomain":[".uk"],"alpha2Code":"GB","alpha3Code":"GBR","callingCodes":["44"],"capital":"London","altSpellings":["GB","UK","Great Britain"],"region":"Europe","subregion":"Northern Europe","population":65110000,"latlng":[54.0,-2.0],"demonym":"British","area":242900.0,"gini":34.0,"timezones":["UTC-08:00","UTC-05:00","UTC-04:00","UTC-03:00","UTC-02:00","UTC","UTC+01:00","UTC+02:00","UTC+06:00"],"borders":["IRL"],"nativeName":"United Kingdom","numericCode":"826","currencies":[{"code":"GBP","name":"British pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Vereinigtes Königreich","es":"Reino Unido","fr":"Royaume-Uni","ja":"イギリス","it":"Regno Unito","br":"Reino Unido","pt":"Reino Unido","nl":"Verenigd Koninkrijk","hr":"Ujedinjeno Kraljevstvo","fa":"بریتانیای کبیر و ایرلند شمالی"},"flag":"https://restcountries.eu/data/gbr.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"GBR"} -{"name":"United States of America","topLevelDomain":[".us"],"alpha2Code":"US","alpha3Code":"USA","callingCodes":["1"],"capital":"Washington, D.C.","altSpellings":["US","USA","United States of America"],"region":"Americas","subregion":"Northern America","population":323947000,"latlng":[38.0,-97.0],"demonym":"American","area":9629091.0,"gini":48.0,"timezones":["UTC-12:00","UTC-11:00","UTC-10:00","UTC-09:00","UTC-08:00","UTC-07:00","UTC-06:00","UTC-05:00","UTC-04:00","UTC+10:00","UTC+12:00"],"borders":["CAN","MEX"],"nativeName":"United States","numericCode":"840","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Vereinigte Staaten von Amerika","es":"Estados Unidos","fr":"États-Unis","ja":"アメリカ合衆国","it":"Stati Uniti D'America","br":"Estados Unidos","pt":"Estados Unidos","nl":"Verenigde Staten","hr":"Sjedinjene Američke Države","fa":"ایالات متحده آمریکا"},"flag":"https://restcountries.eu/data/usa.svg","regionalBlocs":[{"acronym":"NAFTA","name":"North American Free Trade Agreement","otherAcronyms":[],"otherNames":["Tratado de Libre Comercio de América del Norte","Accord de Libre-échange Nord-Américain"]}],"cioc":"USA"} -{"name":"Uruguay","topLevelDomain":[".uy"],"alpha2Code":"UY","alpha3Code":"URY","callingCodes":["598"],"capital":"Montevideo","altSpellings":["UY","Oriental Republic of Uruguay","República Oriental del Uruguay"],"region":"Americas","subregion":"South America","population":3480222,"latlng":[-33.0,-56.0],"demonym":"Uruguayan","area":181034.0,"gini":39.7,"timezones":["UTC-03:00"],"borders":["ARG","BRA"],"nativeName":"Uruguay","numericCode":"858","currencies":[{"code":"UYU","name":"Uruguayan peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Uruguay","es":"Uruguay","fr":"Uruguay","ja":"ウルグアイ","it":"Uruguay","br":"Uruguai","pt":"Uruguai","nl":"Uruguay","hr":"Urugvaj","fa":"اروگوئه"},"flag":"https://restcountries.eu/data/ury.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"URU"} -{"name":"Uzbekistan","topLevelDomain":[".uz"],"alpha2Code":"UZ","alpha3Code":"UZB","callingCodes":["998"],"capital":"Tashkent","altSpellings":["UZ","Republic of Uzbekistan","O‘zbekiston Respublikasi","Ўзбекистон Республикаси"],"region":"Asia","subregion":"Central Asia","population":31576400,"latlng":[41.0,64.0],"demonym":"Uzbekistani","area":447400.0,"gini":36.7,"timezones":["UTC+05:00"],"borders":["AFG","KAZ","KGZ","TJK","TKM"],"nativeName":"O‘zbekiston","numericCode":"860","currencies":[{"code":"UZS","name":"Uzbekistani so'm","symbol":null}],"languages":[{"iso639_1":"uz","iso639_2":"uzb","name":"Uzbek","nativeName":"Oʻzbek"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Usbekistan","es":"Uzbekistán","fr":"Ouzbékistan","ja":"ウズベキスタン","it":"Uzbekistan","br":"Uzbequistão","pt":"Usbequistão","nl":"Oezbekistan","hr":"Uzbekistan","fa":"ازبکستان"},"flag":"https://restcountries.eu/data/uzb.svg","regionalBlocs":[],"cioc":"UZB"} -{"name":"Vanuatu","topLevelDomain":[".vu"],"alpha2Code":"VU","alpha3Code":"VUT","callingCodes":["678"],"capital":"Port Vila","altSpellings":["VU","Republic of Vanuatu","Ripablik blong Vanuatu","République de Vanuatu"],"region":"Oceania","subregion":"Melanesia","population":277500,"latlng":[-16.0,167.0],"demonym":"Ni-Vanuatu","area":12189.0,"gini":null,"timezones":["UTC+11:00"],"borders":[],"nativeName":"Vanuatu","numericCode":"548","currencies":[{"code":"VUV","name":"Vanuatu vatu","symbol":"Vt"}],"languages":[{"iso639_1":"bi","iso639_2":"bis","name":"Bislama","nativeName":"Bislama"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Vanuatu","es":"Vanuatu","fr":"Vanuatu","ja":"バヌアツ","it":"Vanuatu","br":"Vanuatu","pt":"Vanuatu","nl":"Vanuatu","hr":"Vanuatu","fa":"وانواتو"},"flag":"https://restcountries.eu/data/vut.svg","regionalBlocs":[],"cioc":"VAN"} -{"name":"Venezuela (Bolivarian Republic of)","topLevelDomain":[".ve"],"alpha2Code":"VE","alpha3Code":"VEN","callingCodes":["58"],"capital":"Caracas","altSpellings":["VE","Bolivarian Republic of Venezuela","República Bolivariana de Venezuela"],"region":"Americas","subregion":"South America","population":31028700,"latlng":[8.0,-66.0],"demonym":"Venezuelan","area":916445.0,"gini":44.8,"timezones":["UTC-04:00"],"borders":["BRA","COL","GUY"],"nativeName":"Venezuela","numericCode":"862","currencies":[{"code":"VEF","name":"Venezuelan bolívar","symbol":"Bs F"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Venezuela","es":"Venezuela","fr":"Venezuela","ja":"ベネズエラ・ボリバル共和国","it":"Venezuela","br":"Venezuela","pt":"Venezuela","nl":"Venezuela","hr":"Venezuela","fa":"ونزوئلا"},"flag":"https://restcountries.eu/data/ven.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"VEN"} -{"name":"Viet Nam","topLevelDomain":[".vn"],"alpha2Code":"VN","alpha3Code":"VNM","callingCodes":["84"],"capital":"Hanoi","altSpellings":["VN","Socialist Republic of Vietnam","Cộng hòa Xã hội chủ nghĩa Việt Nam"],"region":"Asia","subregion":"South-Eastern Asia","population":92700000,"latlng":[16.16666666,107.83333333],"demonym":"Vietnamese","area":331212.0,"gini":35.6,"timezones":["UTC+07:00"],"borders":["KHM","CHN","LAO"],"nativeName":"Việt Nam","numericCode":"704","currencies":[{"code":"VND","name":"Vietnamese đồng","symbol":"₫"}],"languages":[{"iso639_1":"vi","iso639_2":"vie","name":"Vietnamese","nativeName":"Tiếng Việt"}],"translations":{"de":"Vietnam","es":"Vietnam","fr":"Viêt Nam","ja":"ベトナム","it":"Vietnam","br":"Vietnã","pt":"Vietname","nl":"Vietnam","hr":"Vijetnam","fa":"ویتنام"},"flag":"https://restcountries.eu/data/vnm.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"VIE"} -{"name":"Wallis and Futuna","topLevelDomain":[".wf"],"alpha2Code":"WF","alpha3Code":"WLF","callingCodes":["681"],"capital":"Mata-Utu","altSpellings":["WF","Territory of the Wallis and Futuna Islands","Territoire des îles Wallis et Futuna"],"region":"Oceania","subregion":"Polynesia","population":11750,"latlng":[-13.3,-176.2],"demonym":"Wallis and Futuna Islander","area":142.0,"gini":null,"timezones":["UTC+12:00"],"borders":[],"nativeName":"Wallis et Futuna","numericCode":"876","currencies":[{"code":"XPF","name":"CFP franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Wallis und Futuna","es":"Wallis y Futuna","fr":"Wallis-et-Futuna","ja":"ウォリス・フツナ","it":"Wallis e Futuna","br":"Wallis e Futuna","pt":"Wallis e Futuna","nl":"Wallis en Futuna","hr":"Wallis i Fortuna","fa":"والیس و فوتونا"},"flag":"https://restcountries.eu/data/wlf.svg","regionalBlocs":[],"cioc":""} -{"name":"Western Sahara","topLevelDomain":[".eh"],"alpha2Code":"EH","alpha3Code":"ESH","callingCodes":["212"],"capital":"El Aaiún","altSpellings":["EH","Taneẓroft Tutrimt"],"region":"Africa","subregion":"Northern Africa","population":510713,"latlng":[24.5,-13.0],"demonym":"Sahrawi","area":266000.0,"gini":null,"timezones":["UTC+00:00"],"borders":["DZA","MRT","MAR"],"nativeName":"الصحراء الغربية","numericCode":"732","currencies":[{"code":"MAD","name":"Moroccan dirham","symbol":"د.م."},{"code":"DZD","name":"Algerian dinar","symbol":"د.ج"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Westsahara","es":"Sahara Occidental","fr":"Sahara Occidental","ja":"西サハラ","it":"Sahara Occidentale","br":"Saara Ocidental","pt":"Saara Ocidental","nl":"Westelijke Sahara","hr":"Zapadna Sahara","fa":"جمهوری دموکراتیک عربی صحرا"},"flag":"https://restcountries.eu/data/esh.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":""} -{"name":"Yemen","topLevelDomain":[".ye"],"alpha2Code":"YE","alpha3Code":"YEM","callingCodes":["967"],"capital":"Sana'a","altSpellings":["YE","Yemeni Republic","al-Jumhūriyyah al-Yamaniyyah"],"region":"Asia","subregion":"Western Asia","population":27478000,"latlng":[15.0,48.0],"demonym":"Yemeni","area":527968.0,"gini":37.7,"timezones":["UTC+03:00"],"borders":["OMN","SAU"],"nativeName":"اليَمَن","numericCode":"887","currencies":[{"code":"YER","name":"Yemeni rial","symbol":"﷼"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Jemen","es":"Yemen","fr":"Yémen","ja":"イエメン","it":"Yemen","br":"Iêmen","pt":"Iémen","nl":"Jemen","hr":"Jemen","fa":"یمن"},"flag":"https://restcountries.eu/data/yem.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"YEM"} -{"name":"Zambia","topLevelDomain":[".zm"],"alpha2Code":"ZM","alpha3Code":"ZMB","callingCodes":["260"],"capital":"Lusaka","altSpellings":["ZM","Republic of Zambia"],"region":"Africa","subregion":"Eastern Africa","population":15933883,"latlng":[-15.0,30.0],"demonym":"Zambian","area":752612.0,"gini":54.6,"timezones":["UTC+02:00"],"borders":["AGO","BWA","COD","MWI","MOZ","NAM","TZA","ZWE"],"nativeName":"Zambia","numericCode":"894","currencies":[{"code":"ZMW","name":"Zambian kwacha","symbol":"ZK"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Sambia","es":"Zambia","fr":"Zambie","ja":"ザンビア","it":"Zambia","br":"Zâmbia","pt":"Zâmbia","nl":"Zambia","hr":"Zambija","fa":"زامبیا"},"flag":"https://restcountries.eu/data/zmb.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"ZAM"} +{"name":"Afghanistan","topLevelDomain":[".af"],"alpha2Code":"AF","alpha3Code":"AFG","callingCodes":["93"],"capital":"Kabul","altSpellings":["AF","Afġānistān"],"region":"Asia","subregion":"Southern Asia","population":27657145,"latlng":[33.0,65.0],"demonym":"Afghan","area":652230.0,"gini":27.8,"timezones":["UTC+04:30"],"borders":["IRN","PAK","TKM","UZB","TJK","CHN"],"nativeName":"افغانستان","numericCode":"004","currencies":[{"code":"AFN","name":"Afghan afghani","symbol":"؋"}],"languages":[{"iso639_1":"ps","iso639_2":"pus","name":"Pashto","nativeName":"پښتو"},{"iso639_1":"uz","iso639_2":"uzb","name":"Uzbek","nativeName":"Oʻzbek"},{"iso639_1":"tk","iso639_2":"tuk","name":"Turkmen","nativeName":"Türkmen"}],"translations":{"de":"Afghanistan","es":"Afganistán","fr":"Afghanistan","ja":"アフガニスタン","it":"Afghanistan","br":"Afeganistão","pt":"Afeganistão","nl":"Afghanistan","hr":"Afganistan","fa":"افغانستان"},"flag":"https://restcountries.eu/data/afg.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"AFG"} +{"name":"Åland Islands","topLevelDomain":[".ax"],"alpha2Code":"AX","alpha3Code":"ALA","callingCodes":["358"],"capital":"Mariehamn","altSpellings":["AX","Aaland","Aland","Ahvenanmaa"],"region":"Europe","subregion":"Northern Europe","population":28875,"latlng":[60.116667,19.9],"demonym":"Ålandish","area":1580.0,"gini":null,"timezones":["UTC+02:00"],"borders":[],"nativeName":"Åland","numericCode":"248","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"sv","iso639_2":"swe","name":"Swedish","nativeName":"svenska"}],"translations":{"de":"Åland","es":"Alandia","fr":"Åland","ja":"オーランド諸島","it":"Isole Aland","br":"Ilhas de Aland","pt":"Ilhas de Aland","nl":"Ålandeilanden","hr":"Ålandski otoci","fa":"جزایر الند"},"flag":"https://restcountries.eu/data/ala.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":""} +{"name":"Albania","topLevelDomain":[".al"],"alpha2Code":"AL","alpha3Code":"ALB","callingCodes":["355"],"capital":"Tirana","altSpellings":["AL","Shqipëri","Shqipëria","Shqipnia"],"region":"Europe","subregion":"Southern Europe","population":2886026,"latlng":[41.0,20.0],"demonym":"Albanian","area":28748.0,"gini":34.5,"timezones":["UTC+01:00"],"borders":["MNE","GRC","MKD","KOS"],"nativeName":"Shqipëria","numericCode":"008","currencies":[{"code":"ALL","name":"Albanian lek","symbol":"L"}],"languages":[{"iso639_1":"sq","iso639_2":"sqi","name":"Albanian","nativeName":"Shqip"}],"translations":{"de":"Albanien","es":"Albania","fr":"Albanie","ja":"アルバニア","it":"Albania","br":"Albânia","pt":"Albânia","nl":"Albanië","hr":"Albanija","fa":"آلبانی"},"flag":"https://restcountries.eu/data/alb.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":"ALB"} +{"name":"Algeria","topLevelDomain":[".dz"],"alpha2Code":"DZ","alpha3Code":"DZA","callingCodes":["213"],"capital":"Algiers","altSpellings":["DZ","Dzayer","Algérie"],"region":"Africa","subregion":"Northern Africa","population":40400000,"latlng":[28.0,3.0],"demonym":"Algerian","area":2381741.0,"gini":35.3,"timezones":["UTC+01:00"],"borders":["TUN","LBY","NER","ESH","MRT","MLI","MAR"],"nativeName":"الجزائر","numericCode":"012","currencies":[{"code":"DZD","name":"Algerian dinar","symbol":"د.ج"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Algerien","es":"Argelia","fr":"Algérie","ja":"アルジェリア","it":"Algeria","br":"Argélia","pt":"Argélia","nl":"Algerije","hr":"Alžir","fa":"الجزایر"},"flag":"https://restcountries.eu/data/dza.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"ALG"} +{"name":"American Samoa","topLevelDomain":[".as"],"alpha2Code":"AS","alpha3Code":"ASM","callingCodes":["1684"],"capital":"Pago Pago","altSpellings":["AS","Amerika Sāmoa","Amelika Sāmoa","Sāmoa Amelika"],"region":"Oceania","subregion":"Polynesia","population":57100,"latlng":[-14.33333333,-170.0],"demonym":"American Samoan","area":199.0,"gini":null,"timezones":["UTC-11:00"],"borders":[],"nativeName":"American Samoa","numericCode":"016","currencies":[{"code":"USD","name":"United State Dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"sm","iso639_2":"smo","name":"Samoan","nativeName":"gagana fa'a Samoa"}],"translations":{"de":"Amerikanisch-Samoa","es":"Samoa Americana","fr":"Samoa américaines","ja":"アメリカ領サモア","it":"Samoa Americane","br":"Samoa Americana","pt":"Samoa Americana","nl":"Amerikaans Samoa","hr":"Američka Samoa","fa":"ساموآی آمریکا"},"flag":"https://restcountries.eu/data/asm.svg","regionalBlocs":[],"cioc":"ASA"} +{"name":"Andorra","topLevelDomain":[".ad"],"alpha2Code":"AD","alpha3Code":"AND","callingCodes":["376"],"capital":"Andorra la Vella","altSpellings":["AD","Principality of Andorra","Principat d'Andorra"],"region":"Europe","subregion":"Southern Europe","population":78014,"latlng":[42.5,1.5],"demonym":"Andorran","area":468.0,"gini":null,"timezones":["UTC+01:00"],"borders":["FRA","ESP"],"nativeName":"Andorra","numericCode":"020","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"ca","iso639_2":"cat","name":"Catalan","nativeName":"català"}],"translations":{"de":"Andorra","es":"Andorra","fr":"Andorre","ja":"アンドラ","it":"Andorra","br":"Andorra","pt":"Andorra","nl":"Andorra","hr":"Andora","fa":"آندورا"},"flag":"https://restcountries.eu/data/and.svg","regionalBlocs":[],"cioc":"AND"} +{"name":"Angola","topLevelDomain":[".ao"],"alpha2Code":"AO","alpha3Code":"AGO","callingCodes":["244"],"capital":"Luanda","altSpellings":["AO","República de Angola","ʁɛpublika de an'ɡɔla"],"region":"Africa","subregion":"Middle Africa","population":25868000,"latlng":[-12.5,18.5],"demonym":"Angolan","area":1246700.0,"gini":58.6,"timezones":["UTC+01:00"],"borders":["COG","COD","ZMB","NAM"],"nativeName":"Angola","numericCode":"024","currencies":[{"code":"AOA","name":"Angolan kwanza","symbol":"Kz"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Angola","es":"Angola","fr":"Angola","ja":"アンゴラ","it":"Angola","br":"Angola","pt":"Angola","nl":"Angola","hr":"Angola","fa":"آنگولا"},"flag":"https://restcountries.eu/data/ago.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"ANG"} +{"name":"Anguilla","topLevelDomain":[".ai"],"alpha2Code":"AI","alpha3Code":"AIA","callingCodes":["1264"],"capital":"The Valley","altSpellings":["AI"],"region":"Americas","subregion":"Caribbean","population":13452,"latlng":[18.25,-63.16666666],"demonym":"Anguillian","area":91.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Anguilla","numericCode":"660","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Anguilla","es":"Anguilla","fr":"Anguilla","ja":"アンギラ","it":"Anguilla","br":"Anguila","pt":"Anguila","nl":"Anguilla","hr":"Angvila","fa":"آنگویلا"},"flag":"https://restcountries.eu/data/aia.svg","regionalBlocs":[],"cioc":""} +{"name":"Antarctica","topLevelDomain":[".aq"],"alpha2Code":"AQ","alpha3Code":"ATA","callingCodes":["672"],"capital":"","altSpellings":[],"region":"Polar","subregion":"","population":1000,"latlng":[-74.65,4.48],"demonym":"","area":1.4E7,"gini":null,"timezones":["UTC-03:00","UTC+03:00","UTC+05:00","UTC+06:00","UTC+07:00","UTC+08:00","UTC+10:00","UTC+12:00"],"borders":[],"nativeName":"Antarctica","numericCode":"010","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"},{"code":"GBP","name":"British pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Antarktika","es":"Antártida","fr":"Antarctique","ja":"南極大陸","it":"Antartide","br":"Antártida","pt":"Antárctida","nl":"Antarctica","hr":"Antarktika","fa":"جنوبگان"},"flag":"https://restcountries.eu/data/ata.svg","regionalBlocs":[],"cioc":""} +{"name":"Antigua and Barbuda","topLevelDomain":[".ag"],"alpha2Code":"AG","alpha3Code":"ATG","callingCodes":["1268"],"capital":"Saint John's","altSpellings":["AG"],"region":"Americas","subregion":"Caribbean","population":86295,"latlng":[17.05,-61.8],"demonym":"Antiguan, Barbudan","area":442.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Antigua and Barbuda","numericCode":"028","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Antigua und Barbuda","es":"Antigua y Barbuda","fr":"Antigua-et-Barbuda","ja":"アンティグア・バーブーダ","it":"Antigua e Barbuda","br":"Antígua e Barbuda","pt":"Antígua e Barbuda","nl":"Antigua en Barbuda","hr":"Antigva i Barbuda","fa":"آنتیگوا و باربودا"},"flag":"https://restcountries.eu/data/atg.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"ANT"} +{"name":"Argentina","topLevelDomain":[".ar"],"alpha2Code":"AR","alpha3Code":"ARG","callingCodes":["54"],"capital":"Buenos Aires","altSpellings":["AR","Argentine Republic","República Argentina"],"region":"Americas","subregion":"South America","population":43590400,"latlng":[-34.0,-64.0],"demonym":"Argentinean","area":2780400.0,"gini":44.5,"timezones":["UTC-03:00"],"borders":["BOL","BRA","CHL","PRY","URY"],"nativeName":"Argentina","numericCode":"032","currencies":[{"code":"ARS","name":"Argentine peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"},{"iso639_1":"gn","iso639_2":"grn","name":"Guaraní","nativeName":"Avañe'ẽ"}],"translations":{"de":"Argentinien","es":"Argentina","fr":"Argentine","ja":"アルゼンチン","it":"Argentina","br":"Argentina","pt":"Argentina","nl":"Argentinië","hr":"Argentina","fa":"آرژانتین"},"flag":"https://restcountries.eu/data/arg.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"ARG"} +{"name":"Armenia","topLevelDomain":[".am"],"alpha2Code":"AM","alpha3Code":"ARM","callingCodes":["374"],"capital":"Yerevan","altSpellings":["AM","Hayastan","Republic of Armenia","Հայաստանի Հանրապետություն"],"region":"Asia","subregion":"Western Asia","population":2994400,"latlng":[40.0,45.0],"demonym":"Armenian","area":29743.0,"gini":30.9,"timezones":["UTC+04:00"],"borders":["AZE","GEO","IRN","TUR"],"nativeName":"Հայաստան","numericCode":"051","currencies":[{"code":"AMD","name":"Armenian dram","symbol":null}],"languages":[{"iso639_1":"hy","iso639_2":"hye","name":"Armenian","nativeName":"Հայերեն"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Armenien","es":"Armenia","fr":"Arménie","ja":"アルメニア","it":"Armenia","br":"Armênia","pt":"Arménia","nl":"Armenië","hr":"Armenija","fa":"ارمنستان"},"flag":"https://restcountries.eu/data/arm.svg","regionalBlocs":[{"acronym":"EEU","name":"Eurasian Economic Union","otherAcronyms":["EAEU"],"otherNames":[]}],"cioc":"ARM"} +{"name":"Aruba","topLevelDomain":[".aw"],"alpha2Code":"AW","alpha3Code":"ABW","callingCodes":["297"],"capital":"Oranjestad","altSpellings":["AW"],"region":"Americas","subregion":"Caribbean","population":107394,"latlng":[12.5,-69.96666666],"demonym":"Aruban","area":180.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Aruba","numericCode":"533","currencies":[{"code":"AWG","name":"Aruban florin","symbol":"ƒ"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"},{"iso639_1":"pa","iso639_2":"pan","name":"(Eastern) Punjabi","nativeName":"ਪੰਜਾਬੀ"}],"translations":{"de":"Aruba","es":"Aruba","fr":"Aruba","ja":"アルバ","it":"Aruba","br":"Aruba","pt":"Aruba","nl":"Aruba","hr":"Aruba","fa":"آروبا"},"flag":"https://restcountries.eu/data/abw.svg","regionalBlocs":[],"cioc":"ARU"} +{"name":"Australia","topLevelDomain":[".au"],"alpha2Code":"AU","alpha3Code":"AUS","callingCodes":["61"],"capital":"Canberra","altSpellings":["AU"],"region":"Oceania","subregion":"Australia and New Zealand","population":24117360,"latlng":[-27.0,133.0],"demonym":"Australian","area":7692024.0,"gini":30.5,"timezones":["UTC+05:00","UTC+06:30","UTC+07:00","UTC+08:00","UTC+09:30","UTC+10:00","UTC+10:30","UTC+11:30"],"borders":[],"nativeName":"Australia","numericCode":"036","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Australien","es":"Australia","fr":"Australie","ja":"オーストラリア","it":"Australia","br":"Austrália","pt":"Austrália","nl":"Australië","hr":"Australija","fa":"استرالیا"},"flag":"https://restcountries.eu/data/aus.svg","regionalBlocs":[],"cioc":"AUS"} +{"name":"Austria","topLevelDomain":[".at"],"alpha2Code":"AT","alpha3Code":"AUT","callingCodes":["43"],"capital":"Vienna","altSpellings":["AT","Österreich","Osterreich","Oesterreich"],"region":"Europe","subregion":"Western Europe","population":8725931,"latlng":[47.33333333,13.33333333],"demonym":"Austrian","area":83871.0,"gini":26.0,"timezones":["UTC+01:00"],"borders":["CZE","DEU","HUN","ITA","LIE","SVK","SVN","CHE"],"nativeName":"Österreich","numericCode":"040","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"}],"translations":{"de":"Österreich","es":"Austria","fr":"Autriche","ja":"オーストリア","it":"Austria","br":"áustria","pt":"áustria","nl":"Oostenrijk","hr":"Austrija","fa":"اتریش"},"flag":"https://restcountries.eu/data/aut.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"AUT"} +{"name":"Azerbaijan","topLevelDomain":[".az"],"alpha2Code":"AZ","alpha3Code":"AZE","callingCodes":["994"],"capital":"Baku","altSpellings":["AZ","Republic of Azerbaijan","Azərbaycan Respublikası"],"region":"Asia","subregion":"Western Asia","population":9730500,"latlng":[40.5,47.5],"demonym":"Azerbaijani","area":86600.0,"gini":33.7,"timezones":["UTC+04:00"],"borders":["ARM","GEO","IRN","RUS","TUR"],"nativeName":"Azərbaycan","numericCode":"031","currencies":[{"code":"AZN","name":"Azerbaijani manat","symbol":null}],"languages":[{"iso639_1":"az","iso639_2":"aze","name":"Azerbaijani","nativeName":"azərbaycan dili"}],"translations":{"de":"Aserbaidschan","es":"Azerbaiyán","fr":"Azerbaïdjan","ja":"アゼルバイジャン","it":"Azerbaijan","br":"Azerbaijão","pt":"Azerbaijão","nl":"Azerbeidzjan","hr":"Azerbajdžan","fa":"آذربایجان"},"flag":"https://restcountries.eu/data/aze.svg","regionalBlocs":[],"cioc":"AZE"} +{"name":"Bahamas","topLevelDomain":[".bs"],"alpha2Code":"BS","alpha3Code":"BHS","callingCodes":["1242"],"capital":"Nassau","altSpellings":["BS","Commonwealth of the Bahamas"],"region":"Americas","subregion":"Caribbean","population":378040,"latlng":[24.25,-76.0],"demonym":"Bahamian","area":13943.0,"gini":null,"timezones":["UTC-05:00"],"borders":[],"nativeName":"Bahamas","numericCode":"044","currencies":[{"code":"BSD","name":"Bahamian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Bahamas","es":"Bahamas","fr":"Bahamas","ja":"バハマ","it":"Bahamas","br":"Bahamas","pt":"Baamas","nl":"Bahama’s","hr":"Bahami","fa":"باهاما"},"flag":"https://restcountries.eu/data/bhs.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"BAH"} +{"name":"Bahrain","topLevelDomain":[".bh"],"alpha2Code":"BH","alpha3Code":"BHR","callingCodes":["973"],"capital":"Manama","altSpellings":["BH","Kingdom of Bahrain","Mamlakat al-Baḥrayn"],"region":"Asia","subregion":"Western Asia","population":1404900,"latlng":[26.0,50.55],"demonym":"Bahraini","area":765.0,"gini":null,"timezones":["UTC+03:00"],"borders":[],"nativeName":"‏البحرين","numericCode":"048","currencies":[{"code":"BHD","name":"Bahraini dinar","symbol":".د.ب"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Bahrain","es":"Bahrein","fr":"Bahreïn","ja":"バーレーン","it":"Bahrein","br":"Bahrein","pt":"Barém","nl":"Bahrein","hr":"Bahrein","fa":"بحرین"},"flag":"https://restcountries.eu/data/bhr.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"BRN"} +{"name":"Bangladesh","topLevelDomain":[".bd"],"alpha2Code":"BD","alpha3Code":"BGD","callingCodes":["880"],"capital":"Dhaka","altSpellings":["BD","People's Republic of Bangladesh","Gônôprôjatôntri Bangladesh"],"region":"Asia","subregion":"Southern Asia","population":161006790,"latlng":[24.0,90.0],"demonym":"Bangladeshi","area":147570.0,"gini":32.1,"timezones":["UTC+06:00"],"borders":["MMR","IND"],"nativeName":"Bangladesh","numericCode":"050","currencies":[{"code":"BDT","name":"Bangladeshi taka","symbol":"৳"}],"languages":[{"iso639_1":"bn","iso639_2":"ben","name":"Bengali","nativeName":"বাংলা"}],"translations":{"de":"Bangladesch","es":"Bangladesh","fr":"Bangladesh","ja":"バングラデシュ","it":"Bangladesh","br":"Bangladesh","pt":"Bangladeche","nl":"Bangladesh","hr":"Bangladeš","fa":"بنگلادش"},"flag":"https://restcountries.eu/data/bgd.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"BAN"} +{"name":"Barbados","topLevelDomain":[".bb"],"alpha2Code":"BB","alpha3Code":"BRB","callingCodes":["1246"],"capital":"Bridgetown","altSpellings":["BB"],"region":"Americas","subregion":"Caribbean","population":285000,"latlng":[13.16666666,-59.53333333],"demonym":"Barbadian","area":430.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Barbados","numericCode":"052","currencies":[{"code":"BBD","name":"Barbadian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Barbados","es":"Barbados","fr":"Barbade","ja":"バルバドス","it":"Barbados","br":"Barbados","pt":"Barbados","nl":"Barbados","hr":"Barbados","fa":"باربادوس"},"flag":"https://restcountries.eu/data/brb.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"BAR"} +{"name":"Belarus","topLevelDomain":[".by"],"alpha2Code":"BY","alpha3Code":"BLR","callingCodes":["375"],"capital":"Minsk","altSpellings":["BY","Bielaruś","Republic of Belarus","Белоруссия","Республика Беларусь","Belorussiya","Respublika Belarus’"],"region":"Europe","subregion":"Eastern Europe","population":9498700,"latlng":[53.0,28.0],"demonym":"Belarusian","area":207600.0,"gini":26.5,"timezones":["UTC+03:00"],"borders":["LVA","LTU","POL","RUS","UKR"],"nativeName":"Белару́сь","numericCode":"112","currencies":[{"code":"BYN","name":"New Belarusian ruble","symbol":"Br"},{"code":"BYR","name":"Old Belarusian ruble","symbol":"Br"}],"languages":[{"iso639_1":"be","iso639_2":"bel","name":"Belarusian","nativeName":"беларуская мова"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Weißrussland","es":"Bielorrusia","fr":"Biélorussie","ja":"ベラルーシ","it":"Bielorussia","br":"Bielorrússia","pt":"Bielorrússia","nl":"Wit-Rusland","hr":"Bjelorusija","fa":"بلاروس"},"flag":"https://restcountries.eu/data/blr.svg","regionalBlocs":[{"acronym":"EEU","name":"Eurasian Economic Union","otherAcronyms":["EAEU"],"otherNames":[]}],"cioc":"BLR"} +{"name":"Belgium","topLevelDomain":[".be"],"alpha2Code":"BE","alpha3Code":"BEL","callingCodes":["32"],"capital":"Brussels","altSpellings":["BE","België","Belgie","Belgien","Belgique","Kingdom of Belgium","Koninkrijk België","Royaume de Belgique","Königreich Belgien"],"region":"Europe","subregion":"Western Europe","population":11319511,"latlng":[50.83333333,4.0],"demonym":"Belgian","area":30528.0,"gini":33.0,"timezones":["UTC+01:00"],"borders":["FRA","DEU","LUX","NLD"],"nativeName":"België","numericCode":"056","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"}],"translations":{"de":"Belgien","es":"Bélgica","fr":"Belgique","ja":"ベルギー","it":"Belgio","br":"Bélgica","pt":"Bélgica","nl":"België","hr":"Belgija","fa":"بلژیک"},"flag":"https://restcountries.eu/data/bel.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"BEL"} +{"name":"Belize","topLevelDomain":[".bz"],"alpha2Code":"BZ","alpha3Code":"BLZ","callingCodes":["501"],"capital":"Belmopan","altSpellings":["BZ"],"region":"Americas","subregion":"Central America","population":370300,"latlng":[17.25,-88.75],"demonym":"Belizean","area":22966.0,"gini":53.1,"timezones":["UTC-06:00"],"borders":["GTM","MEX"],"nativeName":"Belize","numericCode":"084","currencies":[{"code":"BZD","name":"Belize dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Belize","es":"Belice","fr":"Belize","ja":"ベリーズ","it":"Belize","br":"Belize","pt":"Belize","nl":"Belize","hr":"Belize","fa":"بلیز"},"flag":"https://restcountries.eu/data/blz.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]},{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"BIZ"} +{"name":"Benin","topLevelDomain":[".bj"],"alpha2Code":"BJ","alpha3Code":"BEN","callingCodes":["229"],"capital":"Porto-Novo","altSpellings":["BJ","Republic of Benin","République du Bénin"],"region":"Africa","subregion":"Western Africa","population":10653654,"latlng":[9.5,2.25],"demonym":"Beninese","area":112622.0,"gini":38.6,"timezones":["UTC+01:00"],"borders":["BFA","NER","NGA","TGO"],"nativeName":"Bénin","numericCode":"204","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Benin","es":"Benín","fr":"Bénin","ja":"ベナン","it":"Benin","br":"Benin","pt":"Benim","nl":"Benin","hr":"Benin","fa":"بنین"},"flag":"https://restcountries.eu/data/ben.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"BEN"} +{"name":"Bermuda","topLevelDomain":[".bm"],"alpha2Code":"BM","alpha3Code":"BMU","callingCodes":["1441"],"capital":"Hamilton","altSpellings":["BM","The Islands of Bermuda","The Bermudas","Somers Isles"],"region":"Americas","subregion":"Northern America","population":61954,"latlng":[32.33333333,-64.75],"demonym":"Bermudian","area":54.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Bermuda","numericCode":"060","currencies":[{"code":"BMD","name":"Bermudian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Bermuda","es":"Bermudas","fr":"Bermudes","ja":"バミューダ","it":"Bermuda","br":"Bermudas","pt":"Bermudas","nl":"Bermuda","hr":"Bermudi","fa":"برمودا"},"flag":"https://restcountries.eu/data/bmu.svg","regionalBlocs":[],"cioc":"BER"} +{"name":"Bhutan","topLevelDomain":[".bt"],"alpha2Code":"BT","alpha3Code":"BTN","callingCodes":["975"],"capital":"Thimphu","altSpellings":["BT","Kingdom of Bhutan"],"region":"Asia","subregion":"Southern Asia","population":775620,"latlng":[27.5,90.5],"demonym":"Bhutanese","area":38394.0,"gini":38.1,"timezones":["UTC+06:00"],"borders":["CHN","IND"],"nativeName":"ʼbrug-yul","numericCode":"064","currencies":[{"code":"BTN","name":"Bhutanese ngultrum","symbol":"Nu."},{"code":"INR","name":"Indian rupee","symbol":"₹"}],"languages":[{"iso639_1":"dz","iso639_2":"dzo","name":"Dzongkha","nativeName":"རྫོང་ཁ"}],"translations":{"de":"Bhutan","es":"Bután","fr":"Bhoutan","ja":"ブータン","it":"Bhutan","br":"Butão","pt":"Butão","nl":"Bhutan","hr":"Butan","fa":"بوتان"},"flag":"https://restcountries.eu/data/btn.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"BHU"} +{"name":"Bolivia (Plurinational State of)","topLevelDomain":[".bo"],"alpha2Code":"BO","alpha3Code":"BOL","callingCodes":["591"],"capital":"Sucre","altSpellings":["BO","Buliwya","Wuliwya","Plurinational State of Bolivia","Estado Plurinacional de Bolivia","Buliwya Mamallaqta","Wuliwya Suyu","Tetã Volívia"],"region":"Americas","subregion":"South America","population":10985059,"latlng":[-17.0,-65.0],"demonym":"Bolivian","area":1098581.0,"gini":56.3,"timezones":["UTC-04:00"],"borders":["ARG","BRA","CHL","PRY","PER"],"nativeName":"Bolivia","numericCode":"068","currencies":[{"code":"BOB","name":"Bolivian boliviano","symbol":"Bs."}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"},{"iso639_1":"ay","iso639_2":"aym","name":"Aymara","nativeName":"aymar aru"},{"iso639_1":"qu","iso639_2":"que","name":"Quechua","nativeName":"Runa Simi"}],"translations":{"de":"Bolivien","es":"Bolivia","fr":"Bolivie","ja":"ボリビア多民族国","it":"Bolivia","br":"Bolívia","pt":"Bolívia","nl":"Bolivia","hr":"Bolivija","fa":"بولیوی"},"flag":"https://restcountries.eu/data/bol.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"BOL"} +{"name":"Bonaire, Sint Eustatius and Saba","topLevelDomain":[".an",".nl"],"alpha2Code":"BQ","alpha3Code":"BES","callingCodes":["5997"],"capital":"Kralendijk","altSpellings":["BQ","Boneiru"],"region":"Americas","subregion":"Caribbean","population":17408,"latlng":[12.15,-68.266667],"demonym":"Dutch","area":294.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Bonaire","numericCode":"535","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"}],"translations":{"de":"Bonaire, Sint Eustatius und Saba","es":null,"fr":"Bonaire, Saint-Eustache et Saba","ja":null,"it":"Bonaire, Saint-Eustache e Saba","br":"Bonaire","pt":"Bonaire","nl":null,"hr":null,"fa":"بونیر"},"flag":"https://restcountries.eu/data/bes.svg","regionalBlocs":[],"cioc":null} +{"name":"Bosnia and Herzegovina","topLevelDomain":[".ba"],"alpha2Code":"BA","alpha3Code":"BIH","callingCodes":["387"],"capital":"Sarajevo","altSpellings":["BA","Bosnia-Herzegovina","Босна и Херцеговина"],"region":"Europe","subregion":"Southern Europe","population":3531159,"latlng":[44.0,18.0],"demonym":"Bosnian, Herzegovinian","area":51209.0,"gini":36.2,"timezones":["UTC+01:00"],"borders":["HRV","MNE","SRB"],"nativeName":"Bosna i Hercegovina","numericCode":"070","currencies":[{"code":"BAM","name":"Bosnia and Herzegovina convertible mark","symbol":null}],"languages":[{"iso639_1":"bs","iso639_2":"bos","name":"Bosnian","nativeName":"bosanski jezik"},{"iso639_1":"hr","iso639_2":"hrv","name":"Croatian","nativeName":"hrvatski jezik"},{"iso639_1":"sr","iso639_2":"srp","name":"Serbian","nativeName":"српски језик"}],"translations":{"de":"Bosnien und Herzegowina","es":"Bosnia y Herzegovina","fr":"Bosnie-Herzégovine","ja":"ボスニア・ヘルツェゴビナ","it":"Bosnia ed Erzegovina","br":"Bósnia e Herzegovina","pt":"Bósnia e Herzegovina","nl":"Bosnië en Herzegovina","hr":"Bosna i Hercegovina","fa":"بوسنی و هرزگوین"},"flag":"https://restcountries.eu/data/bih.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":"BIH"} +{"name":"Botswana","topLevelDomain":[".bw"],"alpha2Code":"BW","alpha3Code":"BWA","callingCodes":["267"],"capital":"Gaborone","altSpellings":["BW","Republic of Botswana","Lefatshe la Botswana"],"region":"Africa","subregion":"Southern Africa","population":2141206,"latlng":[-22.0,24.0],"demonym":"Motswana","area":582000.0,"gini":61.0,"timezones":["UTC+02:00"],"borders":["NAM","ZAF","ZMB","ZWE"],"nativeName":"Botswana","numericCode":"072","currencies":[{"code":"BWP","name":"Botswana pula","symbol":"P"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"tn","iso639_2":"tsn","name":"Tswana","nativeName":"Setswana"}],"translations":{"de":"Botswana","es":"Botswana","fr":"Botswana","ja":"ボツワナ","it":"Botswana","br":"Botsuana","pt":"Botsuana","nl":"Botswana","hr":"Bocvana","fa":"بوتسوانا"},"flag":"https://restcountries.eu/data/bwa.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"BOT"} +{"name":"Bouvet Island","topLevelDomain":[".bv"],"alpha2Code":"BV","alpha3Code":"BVT","callingCodes":[""],"capital":"","altSpellings":["BV","Bouvetøya","Bouvet-øya"],"region":"","subregion":"","population":0,"latlng":[-54.43333333,3.4],"demonym":"","area":49.0,"gini":null,"timezones":["UTC+01:00"],"borders":[],"nativeName":"Bouvetøya","numericCode":"074","currencies":[{"code":"NOK","name":"Norwegian krone","symbol":"kr"}],"languages":[{"iso639_1":"no","iso639_2":"nor","name":"Norwegian","nativeName":"Norsk"},{"iso639_1":"nb","iso639_2":"nob","name":"Norwegian Bokmål","nativeName":"Norsk bokmål"},{"iso639_1":"nn","iso639_2":"nno","name":"Norwegian Nynorsk","nativeName":"Norsk nynorsk"}],"translations":{"de":"Bouvetinsel","es":"Isla Bouvet","fr":"Île Bouvet","ja":"ブーベ島","it":"Isola Bouvet","br":"Ilha Bouvet","pt":"Ilha Bouvet","nl":"Bouveteiland","hr":"Otok Bouvet","fa":"جزیره بووه"},"flag":"https://restcountries.eu/data/bvt.svg","regionalBlocs":[],"cioc":""} +{"name":"Brazil","topLevelDomain":[".br"],"alpha2Code":"BR","alpha3Code":"BRA","callingCodes":["55"],"capital":"Brasília","altSpellings":["BR","Brasil","Federative Republic of Brazil","República Federativa do Brasil"],"region":"Americas","subregion":"South America","population":206135893,"latlng":[-10.0,-55.0],"demonym":"Brazilian","area":8515767.0,"gini":54.7,"timezones":["UTC-05:00","UTC-04:00","UTC-03:00","UTC-02:00"],"borders":["ARG","BOL","COL","GUF","GUY","PRY","PER","SUR","URY","VEN"],"nativeName":"Brasil","numericCode":"076","currencies":[{"code":"BRL","name":"Brazilian real","symbol":"R$"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Brasilien","es":"Brasil","fr":"Brésil","ja":"ブラジル","it":"Brasile","br":"Brasil","pt":"Brasil","nl":"Brazilië","hr":"Brazil","fa":"برزیل"},"flag":"https://restcountries.eu/data/bra.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"BRA"} +{"name":"British Indian Ocean Territory","topLevelDomain":[".io"],"alpha2Code":"IO","alpha3Code":"IOT","callingCodes":["246"],"capital":"Diego Garcia","altSpellings":["IO"],"region":"Africa","subregion":"Eastern Africa","population":3000,"latlng":[-6.0,71.5],"demonym":"Indian","area":60.0,"gini":null,"timezones":["UTC+06:00"],"borders":[],"nativeName":"British Indian Ocean Territory","numericCode":"086","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Britisches Territorium im Indischen Ozean","es":"Territorio Británico del Océano Índico","fr":"Territoire britannique de l'océan Indien","ja":"イギリス領インド洋地域","it":"Territorio britannico dell'oceano indiano","br":"Território Britânico do Oceano íÍdico","pt":"Território Britânico do Oceano Índico","nl":"Britse Gebieden in de Indische Oceaan","hr":"Britanski Indijskooceanski teritorij","fa":"قلمرو بریتانیا در اقیانوس هند"},"flag":"https://restcountries.eu/data/iot.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":""} +{"name":"United States Minor Outlying Islands","topLevelDomain":[".us"],"alpha2Code":"UM","alpha3Code":"UMI","callingCodes":[""],"capital":"","altSpellings":["UM"],"region":"Americas","subregion":"Northern America","population":300,"latlng":[],"demonym":"American","area":null,"gini":null,"timezones":["UTC-11:00","UTC-10:00","UTC+12:00"],"borders":[],"nativeName":"United States Minor Outlying Islands","numericCode":"581","currencies":[{"code":"USD","name":"United States Dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Kleinere Inselbesitzungen der Vereinigten Staaten","es":"Islas Ultramarinas Menores de Estados Unidos","fr":"Îles mineures éloignées des États-Unis","ja":"合衆国領有小離島","it":"Isole minori esterne degli Stati Uniti d'America","br":"Ilhas Menores Distantes dos Estados Unidos","pt":"Ilhas Menores Distantes dos Estados Unidos","nl":"Kleine afgelegen eilanden van de Verenigde Staten","hr":"Mali udaljeni otoci SAD-a","fa":"جزایر کوچک حاشیه‌ای ایالات متحده آمریکا"},"flag":"https://restcountries.eu/data/umi.svg","regionalBlocs":[],"cioc":""} +{"name":"Virgin Islands (British)","topLevelDomain":[".vg"],"alpha2Code":"VG","alpha3Code":"VGB","callingCodes":["1284"],"capital":"Road Town","altSpellings":["VG"],"region":"Americas","subregion":"Caribbean","population":28514,"latlng":[18.431383,-64.62305],"demonym":"Virgin Islander","area":151.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"British Virgin Islands","numericCode":"092","currencies":[{"code":null,"name":"[D]","symbol":"$"},{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Britische Jungferninseln","es":"Islas Vírgenes del Reino Unido","fr":"Îles Vierges britanniques","ja":"イギリス領ヴァージン諸島","it":"Isole Vergini Britanniche","br":"Ilhas Virgens Britânicas","pt":"Ilhas Virgens Britânicas","nl":"Britse Maagdeneilanden","hr":"Britanski Djevičanski Otoci","fa":"جزایر ویرجین بریتانیا"},"flag":"https://restcountries.eu/data/vgb.svg","regionalBlocs":[],"cioc":"IVB"} +{"name":"Virgin Islands (U.S.)","topLevelDomain":[".vi"],"alpha2Code":"VI","alpha3Code":"VIR","callingCodes":["1 340"],"capital":"Charlotte Amalie","altSpellings":["VI","USVI","American Virgin Islands","U.S. Virgin Islands"],"region":"Americas","subregion":"Caribbean","population":114743,"latlng":[18.34,-64.93],"demonym":"Virgin Islander","area":346.36,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Virgin Islands of the United States","numericCode":"850","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Amerikanische Jungferninseln","es":"Islas Vírgenes de los Estados Unidos","fr":"Îles Vierges des États-Unis","ja":"アメリカ領ヴァージン諸島","it":"Isole Vergini americane","br":"Ilhas Virgens Americanas","pt":"Ilhas Virgens Americanas","nl":"Verenigde Staten Maagdeneilanden","hr":null,"fa":"جزایر ویرجین آمریکا"},"flag":"https://restcountries.eu/data/vir.svg","regionalBlocs":[],"cioc":"ISV"} +{"name":"Brunei Darussalam","topLevelDomain":[".bn"],"alpha2Code":"BN","alpha3Code":"BRN","callingCodes":["673"],"capital":"Bandar Seri Begawan","altSpellings":["BN","Nation of Brunei"," the Abode of Peace"],"region":"Asia","subregion":"South-Eastern Asia","population":411900,"latlng":[4.5,114.66666666],"demonym":"Bruneian","area":5765.0,"gini":null,"timezones":["UTC+08:00"],"borders":["MYS"],"nativeName":"Negara Brunei Darussalam","numericCode":"096","currencies":[{"code":"BND","name":"Brunei dollar","symbol":"$"},{"code":"SGD","name":"Singapore dollar","symbol":"$"}],"languages":[{"iso639_1":"ms","iso639_2":"msa","name":"Malay","nativeName":"bahasa Melayu"}],"translations":{"de":"Brunei","es":"Brunei","fr":"Brunei","ja":"ブルネイ・ダルサラーム","it":"Brunei","br":"Brunei","pt":"Brunei","nl":"Brunei","hr":"Brunej","fa":"برونئی"},"flag":"https://restcountries.eu/data/brn.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"BRU"} +{"name":"Bulgaria","topLevelDomain":[".bg"],"alpha2Code":"BG","alpha3Code":"BGR","callingCodes":["359"],"capital":"Sofia","altSpellings":["BG","Republic of Bulgaria","Република България"],"region":"Europe","subregion":"Eastern Europe","population":7153784,"latlng":[43.0,25.0],"demonym":"Bulgarian","area":110879.0,"gini":28.2,"timezones":["UTC+02:00"],"borders":["GRC","MKD","ROU","SRB","TUR"],"nativeName":"България","numericCode":"100","currencies":[{"code":"BGN","name":"Bulgarian lev","symbol":"лв"}],"languages":[{"iso639_1":"bg","iso639_2":"bul","name":"Bulgarian","nativeName":"български език"}],"translations":{"de":"Bulgarien","es":"Bulgaria","fr":"Bulgarie","ja":"ブルガリア","it":"Bulgaria","br":"Bulgária","pt":"Bulgária","nl":"Bulgarije","hr":"Bugarska","fa":"بلغارستان"},"flag":"https://restcountries.eu/data/bgr.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"BUL"} +{"name":"Burkina Faso","topLevelDomain":[".bf"],"alpha2Code":"BF","alpha3Code":"BFA","callingCodes":["226"],"capital":"Ouagadougou","altSpellings":["BF"],"region":"Africa","subregion":"Western Africa","population":19034397,"latlng":[13.0,-2.0],"demonym":"Burkinabe","area":272967.0,"gini":39.8,"timezones":["UTC"],"borders":["BEN","CIV","GHA","MLI","NER","TGO"],"nativeName":"Burkina Faso","numericCode":"854","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ff","iso639_2":"ful","name":"Fula","nativeName":"Fulfulde"}],"translations":{"de":"Burkina Faso","es":"Burkina Faso","fr":"Burkina Faso","ja":"ブルキナファソ","it":"Burkina Faso","br":"Burkina Faso","pt":"Burquina Faso","nl":"Burkina Faso","hr":"Burkina Faso","fa":"بورکینافاسو"},"flag":"https://restcountries.eu/data/bfa.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"BUR"} +{"name":"Burundi","topLevelDomain":[".bi"],"alpha2Code":"BI","alpha3Code":"BDI","callingCodes":["257"],"capital":"Bujumbura","altSpellings":["BI","Republic of Burundi","Republika y'Uburundi","République du Burundi"],"region":"Africa","subregion":"Eastern Africa","population":10114505,"latlng":[-3.5,30.0],"demonym":"Burundian","area":27834.0,"gini":33.3,"timezones":["UTC+02:00"],"borders":["COD","RWA","TZA"],"nativeName":"Burundi","numericCode":"108","currencies":[{"code":"BIF","name":"Burundian franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"rn","iso639_2":"run","name":"Kirundi","nativeName":"Ikirundi"}],"translations":{"de":"Burundi","es":"Burundi","fr":"Burundi","ja":"ブルンジ","it":"Burundi","br":"Burundi","pt":"Burúndi","nl":"Burundi","hr":"Burundi","fa":"بوروندی"},"flag":"https://restcountries.eu/data/bdi.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"BDI"} +{"name":"Cambodia","topLevelDomain":[".kh"],"alpha2Code":"KH","alpha3Code":"KHM","callingCodes":["855"],"capital":"Phnom Penh","altSpellings":["KH","Kingdom of Cambodia"],"region":"Asia","subregion":"South-Eastern Asia","population":15626444,"latlng":[13.0,105.0],"demonym":"Cambodian","area":181035.0,"gini":37.9,"timezones":["UTC+07:00"],"borders":["LAO","THA","VNM"],"nativeName":"Kâmpŭchéa","numericCode":"116","currencies":[{"code":"KHR","name":"Cambodian riel","symbol":"៛"},{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"km","iso639_2":"khm","name":"Khmer","nativeName":"ខ្មែរ"}],"translations":{"de":"Kambodscha","es":"Camboya","fr":"Cambodge","ja":"カンボジア","it":"Cambogia","br":"Camboja","pt":"Camboja","nl":"Cambodja","hr":"Kambodža","fa":"کامبوج"},"flag":"https://restcountries.eu/data/khm.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"CAM"} +{"name":"Cameroon","topLevelDomain":[".cm"],"alpha2Code":"CM","alpha3Code":"CMR","callingCodes":["237"],"capital":"Yaoundé","altSpellings":["CM","Republic of Cameroon","République du Cameroun"],"region":"Africa","subregion":"Middle Africa","population":22709892,"latlng":[6.0,12.0],"demonym":"Cameroonian","area":475442.0,"gini":38.9,"timezones":["UTC+01:00"],"borders":["CAF","TCD","COG","GNQ","GAB","NGA"],"nativeName":"Cameroon","numericCode":"120","currencies":[{"code":"XAF","name":"Central African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Kamerun","es":"Camerún","fr":"Cameroun","ja":"カメルーン","it":"Camerun","br":"Camarões","pt":"Camarões","nl":"Kameroen","hr":"Kamerun","fa":"کامرون"},"flag":"https://restcountries.eu/data/cmr.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"CMR"} +{"name":"Canada","topLevelDomain":[".ca"],"alpha2Code":"CA","alpha3Code":"CAN","callingCodes":["1"],"capital":"Ottawa","altSpellings":["CA"],"region":"Americas","subregion":"Northern America","population":36155487,"latlng":[60.0,-95.0],"demonym":"Canadian","area":9984670.0,"gini":32.6,"timezones":["UTC-08:00","UTC-07:00","UTC-06:00","UTC-05:00","UTC-04:00","UTC-03:30"],"borders":["USA"],"nativeName":"Canada","numericCode":"124","currencies":[{"code":"CAD","name":"Canadian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Kanada","es":"Canadá","fr":"Canada","ja":"カナダ","it":"Canada","br":"Canadá","pt":"Canadá","nl":"Canada","hr":"Kanada","fa":"کانادا"},"flag":"https://restcountries.eu/data/can.svg","regionalBlocs":[{"acronym":"NAFTA","name":"North American Free Trade Agreement","otherAcronyms":[],"otherNames":["Tratado de Libre Comercio de América del Norte","Accord de Libre-échange Nord-Américain"]}],"cioc":"CAN"} +{"name":"Cabo Verde","topLevelDomain":[".cv"],"alpha2Code":"CV","alpha3Code":"CPV","callingCodes":["238"],"capital":"Praia","altSpellings":["CV","Republic of Cabo Verde","República de Cabo Verde"],"region":"Africa","subregion":"Western Africa","population":531239,"latlng":[16.0,-24.0],"demonym":"Cape Verdian","area":4033.0,"gini":50.5,"timezones":["UTC-01:00"],"borders":[],"nativeName":"Cabo Verde","numericCode":"132","currencies":[{"code":"CVE","name":"Cape Verdean escudo","symbol":"Esc"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Kap Verde","es":"Cabo Verde","fr":"Cap Vert","ja":"カーボベルデ","it":"Capo Verde","br":"Cabo Verde","pt":"Cabo Verde","nl":"Kaapverdië","hr":"Zelenortska Republika","fa":"کیپ ورد"},"flag":"https://restcountries.eu/data/cpv.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"CPV"} +{"name":"Cayman Islands","topLevelDomain":[".ky"],"alpha2Code":"KY","alpha3Code":"CYM","callingCodes":["1345"],"capital":"George Town","altSpellings":["KY"],"region":"Americas","subregion":"Caribbean","population":58238,"latlng":[19.5,-80.5],"demonym":"Caymanian","area":264.0,"gini":null,"timezones":["UTC-05:00"],"borders":[],"nativeName":"Cayman Islands","numericCode":"136","currencies":[{"code":"KYD","name":"Cayman Islands dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Kaimaninseln","es":"Islas Caimán","fr":"Îles Caïmans","ja":"ケイマン諸島","it":"Isole Cayman","br":"Ilhas Cayman","pt":"Ilhas Caimão","nl":"Caymaneilanden","hr":"Kajmanski otoci","fa":"جزایر کیمن"},"flag":"https://restcountries.eu/data/cym.svg","regionalBlocs":[],"cioc":"CAY"} +{"name":"Central African Republic","topLevelDomain":[".cf"],"alpha2Code":"CF","alpha3Code":"CAF","callingCodes":["236"],"capital":"Bangui","altSpellings":["CF","Central African Republic","République centrafricaine"],"region":"Africa","subregion":"Middle Africa","population":4998000,"latlng":[7.0,21.0],"demonym":"Central African","area":622984.0,"gini":56.3,"timezones":["UTC+01:00"],"borders":["CMR","TCD","COD","COG","SSD","SDN"],"nativeName":"Ködörösêse tî Bêafrîka","numericCode":"140","currencies":[{"code":"XAF","name":"Central African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"sg","iso639_2":"sag","name":"Sango","nativeName":"yângâ tî sängö"}],"translations":{"de":"Zentralafrikanische Republik","es":"República Centroafricana","fr":"République centrafricaine","ja":"中央アフリカ共和国","it":"Repubblica Centrafricana","br":"República Centro-Africana","pt":"República Centro-Africana","nl":"Centraal-Afrikaanse Republiek","hr":"Srednjoafrička Republika","fa":"جمهوری آفریقای مرکزی"},"flag":"https://restcountries.eu/data/caf.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"CAF"} +{"name":"Chad","topLevelDomain":[".td"],"alpha2Code":"TD","alpha3Code":"TCD","callingCodes":["235"],"capital":"N'Djamena","altSpellings":["TD","Tchad","Republic of Chad","République du Tchad"],"region":"Africa","subregion":"Middle Africa","population":14497000,"latlng":[15.0,19.0],"demonym":"Chadian","area":1284000.0,"gini":39.8,"timezones":["UTC+01:00"],"borders":["CMR","CAF","LBY","NER","NGA","SSD"],"nativeName":"Tchad","numericCode":"148","currencies":[{"code":"XAF","name":"Central African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Tschad","es":"Chad","fr":"Tchad","ja":"チャド","it":"Ciad","br":"Chade","pt":"Chade","nl":"Tsjaad","hr":"Čad","fa":"چاد"},"flag":"https://restcountries.eu/data/tcd.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"CHA"} +{"name":"Chile","topLevelDomain":[".cl"],"alpha2Code":"CL","alpha3Code":"CHL","callingCodes":["56"],"capital":"Santiago","altSpellings":["CL","Republic of Chile","República de Chile"],"region":"Americas","subregion":"South America","population":18191900,"latlng":[-30.0,-71.0],"demonym":"Chilean","area":756102.0,"gini":52.1,"timezones":["UTC-06:00","UTC-04:00"],"borders":["ARG","BOL","PER"],"nativeName":"Chile","numericCode":"152","currencies":[{"code":"CLP","name":"Chilean peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Chile","es":"Chile","fr":"Chili","ja":"チリ","it":"Cile","br":"Chile","pt":"Chile","nl":"Chili","hr":"Čile","fa":"شیلی"},"flag":"https://restcountries.eu/data/chl.svg","regionalBlocs":[{"acronym":"PA","name":"Pacific Alliance","otherAcronyms":[],"otherNames":["Alianza del Pacífico"]},{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"CHI"} +{"name":"China","topLevelDomain":[".cn"],"alpha2Code":"CN","alpha3Code":"CHN","callingCodes":["86"],"capital":"Beijing","altSpellings":["CN","Zhōngguó","Zhongguo","Zhonghua","People's Republic of China","中华人民共和国","Zhōnghuá Rénmín Gònghéguó"],"region":"Asia","subregion":"Eastern Asia","population":1377422166,"latlng":[35.0,105.0],"demonym":"Chinese","area":9640011.0,"gini":47.0,"timezones":["UTC+08:00"],"borders":["AFG","BTN","MMR","HKG","IND","KAZ","PRK","KGZ","LAO","MAC","MNG","PAK","RUS","TJK","VNM"],"nativeName":"中国","numericCode":"156","currencies":[{"code":"CNY","name":"Chinese yuan","symbol":"¥"}],"languages":[{"iso639_1":"zh","iso639_2":"zho","name":"Chinese","nativeName":"中文 (Zhōngwén)"}],"translations":{"de":"China","es":"China","fr":"Chine","ja":"中国","it":"Cina","br":"China","pt":"China","nl":"China","hr":"Kina","fa":"چین"},"flag":"https://restcountries.eu/data/chn.svg","regionalBlocs":[],"cioc":"CHN"} +{"name":"Christmas Island","topLevelDomain":[".cx"],"alpha2Code":"CX","alpha3Code":"CXR","callingCodes":["61"],"capital":"Flying Fish Cove","altSpellings":["CX","Territory of Christmas Island"],"region":"Oceania","subregion":"Australia and New Zealand","population":2072,"latlng":[-10.5,105.66666666],"demonym":"Christmas Island","area":135.0,"gini":null,"timezones":["UTC+07:00"],"borders":[],"nativeName":"Christmas Island","numericCode":"162","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Weihnachtsinsel","es":"Isla de Navidad","fr":"Île Christmas","ja":"クリスマス島","it":"Isola di Natale","br":"Ilha Christmas","pt":"Ilha do Natal","nl":"Christmaseiland","hr":"Božićni otok","fa":"جزیره کریسمس"},"flag":"https://restcountries.eu/data/cxr.svg","regionalBlocs":[],"cioc":""} +{"name":"Cocos (Keeling) Islands","topLevelDomain":[".cc"],"alpha2Code":"CC","alpha3Code":"CCK","callingCodes":["61"],"capital":"West Island","altSpellings":["CC","Territory of the Cocos (Keeling) Islands","Keeling Islands"],"region":"Oceania","subregion":"Australia and New Zealand","population":550,"latlng":[-12.5,96.83333333],"demonym":"Cocos Islander","area":14.0,"gini":null,"timezones":["UTC+06:30"],"borders":[],"nativeName":"Cocos (Keeling) Islands","numericCode":"166","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Kokosinseln","es":"Islas Cocos o Islas Keeling","fr":"Îles Cocos","ja":"ココス(キーリング)諸島","it":"Isole Cocos e Keeling","br":"Ilhas Cocos","pt":"Ilhas dos Cocos","nl":"Cocoseilanden","hr":"Kokosovi Otoci","fa":"جزایر کوکوس"},"flag":"https://restcountries.eu/data/cck.svg","regionalBlocs":[],"cioc":""} +{"name":"Colombia","topLevelDomain":[".co"],"alpha2Code":"CO","alpha3Code":"COL","callingCodes":["57"],"capital":"Bogotá","altSpellings":["CO","Republic of Colombia","República de Colombia"],"region":"Americas","subregion":"South America","population":48759958,"latlng":[4.0,-72.0],"demonym":"Colombian","area":1141748.0,"gini":55.9,"timezones":["UTC-05:00"],"borders":["BRA","ECU","PAN","PER","VEN"],"nativeName":"Colombia","numericCode":"170","currencies":[{"code":"COP","name":"Colombian peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Kolumbien","es":"Colombia","fr":"Colombie","ja":"コロンビア","it":"Colombia","br":"Colômbia","pt":"Colômbia","nl":"Colombia","hr":"Kolumbija","fa":"کلمبیا"},"flag":"https://restcountries.eu/data/col.svg","regionalBlocs":[{"acronym":"PA","name":"Pacific Alliance","otherAcronyms":[],"otherNames":["Alianza del Pacífico"]},{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"COL"} +{"name":"Comoros","topLevelDomain":[".km"],"alpha2Code":"KM","alpha3Code":"COM","callingCodes":["269"],"capital":"Moroni","altSpellings":["KM","Union of the Comoros","Union des Comores","Udzima wa Komori","al-Ittiḥād al-Qumurī"],"region":"Africa","subregion":"Eastern Africa","population":806153,"latlng":[-12.16666666,44.25],"demonym":"Comoran","area":1862.0,"gini":64.3,"timezones":["UTC+03:00"],"borders":[],"nativeName":"Komori","numericCode":"174","currencies":[{"code":"KMF","name":"Comorian franc","symbol":"Fr"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Union der Komoren","es":"Comoras","fr":"Comores","ja":"コモロ","it":"Comore","br":"Comores","pt":"Comores","nl":"Comoren","hr":"Komori","fa":"کومور"},"flag":"https://restcountries.eu/data/com.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"COM"} +{"name":"Congo","topLevelDomain":[".cg"],"alpha2Code":"CG","alpha3Code":"COG","callingCodes":["242"],"capital":"Brazzaville","altSpellings":["CG","Congo-Brazzaville"],"region":"Africa","subregion":"Middle Africa","population":4741000,"latlng":[-1.0,15.0],"demonym":"Congolese","area":342000.0,"gini":47.3,"timezones":["UTC+01:00"],"borders":["AGO","CMR","CAF","COD","GAB"],"nativeName":"République du Congo","numericCode":"178","currencies":[{"code":"XAF","name":"Central African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ln","iso639_2":"lin","name":"Lingala","nativeName":"Lingála"}],"translations":{"de":"Kongo","es":"Congo","fr":"Congo","ja":"コンゴ共和国","it":"Congo","br":"Congo","pt":"Congo","nl":"Congo [Republiek]","hr":"Kongo","fa":"کنگو"},"flag":"https://restcountries.eu/data/cog.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"CGO"} +{"name":"Congo (Democratic Republic of the)","topLevelDomain":[".cd"],"alpha2Code":"CD","alpha3Code":"COD","callingCodes":["243"],"capital":"Kinshasa","altSpellings":["CD","DR Congo","Congo-Kinshasa","DRC"],"region":"Africa","subregion":"Middle Africa","population":85026000,"latlng":[0.0,25.0],"demonym":"Congolese","area":2344858.0,"gini":null,"timezones":["UTC+01:00","UTC+02:00"],"borders":["AGO","BDI","CAF","COG","RWA","SSD","TZA","UGA","ZMB"],"nativeName":"République démocratique du Congo","numericCode":"180","currencies":[{"code":"CDF","name":"Congolese franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ln","iso639_2":"lin","name":"Lingala","nativeName":"Lingála"},{"iso639_1":"kg","iso639_2":"kon","name":"Kongo","nativeName":"Kikongo"},{"iso639_1":"sw","iso639_2":"swa","name":"Swahili","nativeName":"Kiswahili"},{"iso639_1":"lu","iso639_2":"lub","name":"Luba-Katanga","nativeName":"Tshiluba"}],"translations":{"de":"Kongo (Dem. Rep.)","es":"Congo (Rep. Dem.)","fr":"Congo (Rép. dém.)","ja":"コンゴ民主共和国","it":"Congo (Rep. Dem.)","br":"RD Congo","pt":"RD Congo","nl":"Congo [DRC]","hr":"Kongo, Demokratska Republika","fa":"جمهوری کنگو"},"flag":"https://restcountries.eu/data/cod.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"COD"} +{"name":"Cook Islands","topLevelDomain":[".ck"],"alpha2Code":"CK","alpha3Code":"COK","callingCodes":["682"],"capital":"Avarua","altSpellings":["CK","Kūki 'Āirani"],"region":"Oceania","subregion":"Polynesia","population":18100,"latlng":[-21.23333333,-159.76666666],"demonym":"Cook Islander","area":236.0,"gini":null,"timezones":["UTC-10:00"],"borders":[],"nativeName":"Cook Islands","numericCode":"184","currencies":[{"code":"NZD","name":"New Zealand dollar","symbol":"$"},{"code":"CKD","name":"Cook Islands dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Cookinseln","es":"Islas Cook","fr":"Îles Cook","ja":"クック諸島","it":"Isole Cook","br":"Ilhas Cook","pt":"Ilhas Cook","nl":"Cookeilanden","hr":"Cookovo Otočje","fa":"جزایر کوک"},"flag":"https://restcountries.eu/data/cok.svg","regionalBlocs":[],"cioc":"COK"} +{"name":"Costa Rica","topLevelDomain":[".cr"],"alpha2Code":"CR","alpha3Code":"CRI","callingCodes":["506"],"capital":"San José","altSpellings":["CR","Republic of Costa Rica","República de Costa Rica"],"region":"Americas","subregion":"Central America","population":4890379,"latlng":[10.0,-84.0],"demonym":"Costa Rican","area":51100.0,"gini":50.7,"timezones":["UTC-06:00"],"borders":["NIC","PAN"],"nativeName":"Costa Rica","numericCode":"188","currencies":[{"code":"CRC","name":"Costa Rican colón","symbol":"₡"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Costa Rica","es":"Costa Rica","fr":"Costa Rica","ja":"コスタリカ","it":"Costa Rica","br":"Costa Rica","pt":"Costa Rica","nl":"Costa Rica","hr":"Kostarika","fa":"کاستاریکا"},"flag":"https://restcountries.eu/data/cri.svg","regionalBlocs":[{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"CRC"} +{"name":"Croatia","topLevelDomain":[".hr"],"alpha2Code":"HR","alpha3Code":"HRV","callingCodes":["385"],"capital":"Zagreb","altSpellings":["HR","Hrvatska","Republic of Croatia","Republika Hrvatska"],"region":"Europe","subregion":"Southern Europe","population":4190669,"latlng":[45.16666666,15.5],"demonym":"Croatian","area":56594.0,"gini":33.7,"timezones":["UTC+01:00"],"borders":["BIH","HUN","MNE","SRB","SVN"],"nativeName":"Hrvatska","numericCode":"191","currencies":[{"code":"HRK","name":"Croatian kuna","symbol":"kn"}],"languages":[{"iso639_1":"hr","iso639_2":"hrv","name":"Croatian","nativeName":"hrvatski jezik"}],"translations":{"de":"Kroatien","es":"Croacia","fr":"Croatie","ja":"クロアチア","it":"Croazia","br":"Croácia","pt":"Croácia","nl":"Kroatië","hr":"Hrvatska","fa":"کرواسی"},"flag":"https://restcountries.eu/data/hrv.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"CRO"} +{"name":"Cuba","topLevelDomain":[".cu"],"alpha2Code":"CU","alpha3Code":"CUB","callingCodes":["53"],"capital":"Havana","altSpellings":["CU","Republic of Cuba","República de Cuba"],"region":"Americas","subregion":"Caribbean","population":11239004,"latlng":[21.5,-80.0],"demonym":"Cuban","area":109884.0,"gini":null,"timezones":["UTC-05:00"],"borders":[],"nativeName":"Cuba","numericCode":"192","currencies":[{"code":"CUC","name":"Cuban convertible peso","symbol":"$"},{"code":"CUP","name":"Cuban peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Kuba","es":"Cuba","fr":"Cuba","ja":"キューバ","it":"Cuba","br":"Cuba","pt":"Cuba","nl":"Cuba","hr":"Kuba","fa":"کوبا"},"flag":"https://restcountries.eu/data/cub.svg","regionalBlocs":[],"cioc":"CUB"} +{"name":"Curaçao","topLevelDomain":[".cw"],"alpha2Code":"CW","alpha3Code":"CUW","callingCodes":["599"],"capital":"Willemstad","altSpellings":["CW","Curacao","Kòrsou","Country of Curaçao","Land Curaçao","Pais Kòrsou"],"region":"Americas","subregion":"Caribbean","population":154843,"latlng":[12.116667,-68.933333],"demonym":"Dutch","area":444.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Curaçao","numericCode":"531","currencies":[{"code":"ANG","name":"Netherlands Antillean guilder","symbol":"ƒ"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"},{"iso639_1":"pa","iso639_2":"pan","name":"(Eastern) Punjabi","nativeName":"ਪੰਜਾਬੀ"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Curaçao","es":null,"fr":"Curaçao","ja":null,"it":"Curaçao","br":"Curaçao","pt":"Curaçao","nl":"Curaçao","hr":null,"fa":"کوراسائو"},"flag":"https://restcountries.eu/data/cuw.svg","regionalBlocs":[],"cioc":""} +{"name":"Cyprus","topLevelDomain":[".cy"],"alpha2Code":"CY","alpha3Code":"CYP","callingCodes":["357"],"capital":"Nicosia","altSpellings":["CY","Kýpros","Kıbrıs","Republic of Cyprus","Κυπριακή Δημοκρατία","Kıbrıs Cumhuriyeti"],"region":"Europe","subregion":"Southern Europe","population":847000,"latlng":[35.0,33.0],"demonym":"Cypriot","area":9251.0,"gini":null,"timezones":["UTC+02:00"],"borders":["GBR"],"nativeName":"Κύπρος","numericCode":"196","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"el","iso639_2":"ell","name":"Greek (modern)","nativeName":"ελληνικά"},{"iso639_1":"tr","iso639_2":"tur","name":"Turkish","nativeName":"Türkçe"},{"iso639_1":"hy","iso639_2":"hye","name":"Armenian","nativeName":"Հայերեն"}],"translations":{"de":"Zypern","es":"Chipre","fr":"Chypre","ja":"キプロス","it":"Cipro","br":"Chipre","pt":"Chipre","nl":"Cyprus","hr":"Cipar","fa":"قبرس"},"flag":"https://restcountries.eu/data/cyp.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"CYP"} +{"name":"Czech Republic","topLevelDomain":[".cz"],"alpha2Code":"CZ","alpha3Code":"CZE","callingCodes":["420"],"capital":"Prague","altSpellings":["CZ","Česká republika","Česko"],"region":"Europe","subregion":"Eastern Europe","population":10558524,"latlng":[49.75,15.5],"demonym":"Czech","area":78865.0,"gini":26.0,"timezones":["UTC+01:00"],"borders":["AUT","DEU","POL","SVK"],"nativeName":"Česká republika","numericCode":"203","currencies":[{"code":"CZK","name":"Czech koruna","symbol":"Kč"}],"languages":[{"iso639_1":"cs","iso639_2":"ces","name":"Czech","nativeName":"čeština"},{"iso639_1":"sk","iso639_2":"slk","name":"Slovak","nativeName":"slovenčina"}],"translations":{"de":"Tschechische Republik","es":"República Checa","fr":"République tchèque","ja":"チェコ","it":"Repubblica Ceca","br":"República Tcheca","pt":"República Checa","nl":"Tsjechië","hr":"Češka","fa":"جمهوری چک"},"flag":"https://restcountries.eu/data/cze.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"CZE"} +{"name":"Denmark","topLevelDomain":[".dk"],"alpha2Code":"DK","alpha3Code":"DNK","callingCodes":["45"],"capital":"Copenhagen","altSpellings":["DK","Danmark","Kingdom of Denmark","Kongeriget Danmark"],"region":"Europe","subregion":"Northern Europe","population":5717014,"latlng":[56.0,10.0],"demonym":"Danish","area":43094.0,"gini":24.0,"timezones":["UTC-04:00","UTC-03:00","UTC-01:00","UTC","UTC+01:00"],"borders":["DEU"],"nativeName":"Danmark","numericCode":"208","currencies":[{"code":"DKK","name":"Danish krone","symbol":"kr"}],"languages":[{"iso639_1":"da","iso639_2":"dan","name":"Danish","nativeName":"dansk"}],"translations":{"de":"Dänemark","es":"Dinamarca","fr":"Danemark","ja":"デンマーク","it":"Danimarca","br":"Dinamarca","pt":"Dinamarca","nl":"Denemarken","hr":"Danska","fa":"دانمارک"},"flag":"https://restcountries.eu/data/dnk.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"DEN"} +{"name":"Djibouti","topLevelDomain":[".dj"],"alpha2Code":"DJ","alpha3Code":"DJI","callingCodes":["253"],"capital":"Djibouti","altSpellings":["DJ","Jabuuti","Gabuuti","Republic of Djibouti","République de Djibouti","Gabuutih Ummuuno","Jamhuuriyadda Jabuuti"],"region":"Africa","subregion":"Eastern Africa","population":900000,"latlng":[11.5,43.0],"demonym":"Djibouti","area":23200.0,"gini":40.0,"timezones":["UTC+03:00"],"borders":["ERI","ETH","SOM"],"nativeName":"Djibouti","numericCode":"262","currencies":[{"code":"DJF","name":"Djiboutian franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Dschibuti","es":"Yibuti","fr":"Djibouti","ja":"ジブチ","it":"Gibuti","br":"Djibuti","pt":"Djibuti","nl":"Djibouti","hr":"Džibuti","fa":"جیبوتی"},"flag":"https://restcountries.eu/data/dji.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"DJI"} +{"name":"Dominica","topLevelDomain":[".dm"],"alpha2Code":"DM","alpha3Code":"DMA","callingCodes":["1767"],"capital":"Roseau","altSpellings":["DM","Dominique","Wai‘tu kubuli","Commonwealth of Dominica"],"region":"Americas","subregion":"Caribbean","population":71293,"latlng":[15.41666666,-61.33333333],"demonym":"Dominican","area":751.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Dominica","numericCode":"212","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Dominica","es":"Dominica","fr":"Dominique","ja":"ドミニカ国","it":"Dominica","br":"Dominica","pt":"Dominica","nl":"Dominica","hr":"Dominika","fa":"دومینیکا"},"flag":"https://restcountries.eu/data/dma.svg","regionalBlocs":[],"cioc":"DMA"} +{"name":"Dominican Republic","topLevelDomain":[".do"],"alpha2Code":"DO","alpha3Code":"DOM","callingCodes":["1809","1829","1849"],"capital":"Santo Domingo","altSpellings":["DO"],"region":"Americas","subregion":"Caribbean","population":10075045,"latlng":[19.0,-70.66666666],"demonym":"Dominican","area":48671.0,"gini":47.2,"timezones":["UTC-04:00"],"borders":["HTI"],"nativeName":"República Dominicana","numericCode":"214","currencies":[{"code":"DOP","name":"Dominican peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Dominikanische Republik","es":"República Dominicana","fr":"République dominicaine","ja":"ドミニカ共和国","it":"Repubblica Dominicana","br":"República Dominicana","pt":"República Dominicana","nl":"Dominicaanse Republiek","hr":"Dominikanska Republika","fa":"جمهوری دومینیکن"},"flag":"https://restcountries.eu/data/dom.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]},{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"DOM"} +{"name":"Ecuador","topLevelDomain":[".ec"],"alpha2Code":"EC","alpha3Code":"ECU","callingCodes":["593"],"capital":"Quito","altSpellings":["EC","Republic of Ecuador","República del Ecuador"],"region":"Americas","subregion":"South America","population":16545799,"latlng":[-2.0,-77.5],"demonym":"Ecuadorean","area":276841.0,"gini":49.3,"timezones":["UTC-06:00","UTC-05:00"],"borders":["COL","PER"],"nativeName":"Ecuador","numericCode":"218","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Ecuador","es":"Ecuador","fr":"Équateur","ja":"エクアドル","it":"Ecuador","br":"Equador","pt":"Equador","nl":"Ecuador","hr":"Ekvador","fa":"اکوادور"},"flag":"https://restcountries.eu/data/ecu.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"ECU"} +{"name":"Egypt","topLevelDomain":[".eg"],"alpha2Code":"EG","alpha3Code":"EGY","callingCodes":["20"],"capital":"Cairo","altSpellings":["EG","Arab Republic of Egypt"],"region":"Africa","subregion":"Northern Africa","population":91290000,"latlng":[27.0,30.0],"demonym":"Egyptian","area":1002450.0,"gini":30.8,"timezones":["UTC+02:00"],"borders":["ISR","LBY","SDN"],"nativeName":"مصر‎","numericCode":"818","currencies":[{"code":"EGP","name":"Egyptian pound","symbol":"£"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Ägypten","es":"Egipto","fr":"Égypte","ja":"エジプト","it":"Egitto","br":"Egito","pt":"Egipto","nl":"Egypte","hr":"Egipat","fa":"مصر"},"flag":"https://restcountries.eu/data/egy.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"EGY"} +{"name":"El Salvador","topLevelDomain":[".sv"],"alpha2Code":"SV","alpha3Code":"SLV","callingCodes":["503"],"capital":"San Salvador","altSpellings":["SV","Republic of El Salvador","República de El Salvador"],"region":"Americas","subregion":"Central America","population":6520675,"latlng":[13.83333333,-88.91666666],"demonym":"Salvadoran","area":21041.0,"gini":48.3,"timezones":["UTC-06:00"],"borders":["GTM","HND"],"nativeName":"El Salvador","numericCode":"222","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"El Salvador","es":"El Salvador","fr":"Salvador","ja":"エルサルバドル","it":"El Salvador","br":"El Salvador","pt":"El Salvador","nl":"El Salvador","hr":"Salvador","fa":"السالوادور"},"flag":"https://restcountries.eu/data/slv.svg","regionalBlocs":[{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"ESA"} +{"name":"Equatorial Guinea","topLevelDomain":[".gq"],"alpha2Code":"GQ","alpha3Code":"GNQ","callingCodes":["240"],"capital":"Malabo","altSpellings":["GQ","Republic of Equatorial Guinea","República de Guinea Ecuatorial","République de Guinée équatoriale","República da Guiné Equatorial"],"region":"Africa","subregion":"Middle Africa","population":1222442,"latlng":[2.0,10.0],"demonym":"Equatorial Guinean","area":28051.0,"gini":null,"timezones":["UTC+01:00"],"borders":["CMR","GAB"],"nativeName":"Guinea Ecuatorial","numericCode":"226","currencies":[{"code":"XAF","name":"Central African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Äquatorial-Guinea","es":"Guinea Ecuatorial","fr":"Guinée-Équatoriale","ja":"赤道ギニア","it":"Guinea Equatoriale","br":"Guiné Equatorial","pt":"Guiné Equatorial","nl":"Equatoriaal-Guinea","hr":"Ekvatorijalna Gvineja","fa":"گینه استوایی"},"flag":"https://restcountries.eu/data/gnq.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"GEQ"} +{"name":"Eritrea","topLevelDomain":[".er"],"alpha2Code":"ER","alpha3Code":"ERI","callingCodes":["291"],"capital":"Asmara","altSpellings":["ER","State of Eritrea","ሃገረ ኤርትራ","Dawlat Iritriyá","ʾErtrā","Iritriyā",""],"region":"Africa","subregion":"Eastern Africa","population":5352000,"latlng":[15.0,39.0],"demonym":"Eritrean","area":117600.0,"gini":null,"timezones":["UTC+03:00"],"borders":["DJI","ETH","SDN"],"nativeName":"ኤርትራ","numericCode":"232","currencies":[{"code":"ERN","name":"Eritrean nakfa","symbol":"Nfk"}],"languages":[{"iso639_1":"ti","iso639_2":"tir","name":"Tigrinya","nativeName":"ትግርኛ"},{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Eritrea","es":"Eritrea","fr":"Érythrée","ja":"エリトリア","it":"Eritrea","br":"Eritreia","pt":"Eritreia","nl":"Eritrea","hr":"Eritreja","fa":"اریتره"},"flag":"https://restcountries.eu/data/eri.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"ERI"} +{"name":"Estonia","topLevelDomain":[".ee"],"alpha2Code":"EE","alpha3Code":"EST","callingCodes":["372"],"capital":"Tallinn","altSpellings":["EE","Eesti","Republic of Estonia","Eesti Vabariik"],"region":"Europe","subregion":"Northern Europe","population":1315944,"latlng":[59.0,26.0],"demonym":"Estonian","area":45227.0,"gini":36.0,"timezones":["UTC+02:00"],"borders":["LVA","RUS"],"nativeName":"Eesti","numericCode":"233","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"et","iso639_2":"est","name":"Estonian","nativeName":"eesti"}],"translations":{"de":"Estland","es":"Estonia","fr":"Estonie","ja":"エストニア","it":"Estonia","br":"Estônia","pt":"Estónia","nl":"Estland","hr":"Estonija","fa":"استونی"},"flag":"https://restcountries.eu/data/est.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"EST"} +{"name":"Ethiopia","topLevelDomain":[".et"],"alpha2Code":"ET","alpha3Code":"ETH","callingCodes":["251"],"capital":"Addis Ababa","altSpellings":["ET","ʾĪtyōṗṗyā","Federal Democratic Republic of Ethiopia","የኢትዮጵያ ፌዴራላዊ ዲሞክራሲያዊ ሪፐብሊክ"],"region":"Africa","subregion":"Eastern Africa","population":92206005,"latlng":[8.0,38.0],"demonym":"Ethiopian","area":1104300.0,"gini":29.8,"timezones":["UTC+03:00"],"borders":["DJI","ERI","KEN","SOM","SSD","SDN"],"nativeName":"ኢትዮጵያ","numericCode":"231","currencies":[{"code":"ETB","name":"Ethiopian birr","symbol":"Br"}],"languages":[{"iso639_1":"am","iso639_2":"amh","name":"Amharic","nativeName":"አማርኛ"}],"translations":{"de":"Äthiopien","es":"Etiopía","fr":"Éthiopie","ja":"エチオピア","it":"Etiopia","br":"Etiópia","pt":"Etiópia","nl":"Ethiopië","hr":"Etiopija","fa":"اتیوپی"},"flag":"https://restcountries.eu/data/eth.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"ETH"} +{"name":"Falkland Islands (Malvinas)","topLevelDomain":[".fk"],"alpha2Code":"FK","alpha3Code":"FLK","callingCodes":["500"],"capital":"Stanley","altSpellings":["FK","Islas Malvinas"],"region":"Americas","subregion":"South America","population":2563,"latlng":[-51.75,-59.0],"demonym":"Falkland Islander","area":12173.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Falkland Islands","numericCode":"238","currencies":[{"code":"FKP","name":"Falkland Islands pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Falklandinseln","es":"Islas Malvinas","fr":"Îles Malouines","ja":"フォークランド(マルビナス)諸島","it":"Isole Falkland o Isole Malvine","br":"Ilhas Malvinas","pt":"Ilhas Falkland","nl":"Falklandeilanden [Islas Malvinas]","hr":"Falklandski Otoci","fa":"جزایر فالکلند"},"flag":"https://restcountries.eu/data/flk.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":""} +{"name":"Faroe Islands","topLevelDomain":[".fo"],"alpha2Code":"FO","alpha3Code":"FRO","callingCodes":["298"],"capital":"Tórshavn","altSpellings":["FO","Føroyar","Færøerne"],"region":"Europe","subregion":"Northern Europe","population":49376,"latlng":[62.0,-7.0],"demonym":"Faroese","area":1393.0,"gini":null,"timezones":["UTC+00:00"],"borders":[],"nativeName":"Føroyar","numericCode":"234","currencies":[{"code":"DKK","name":"Danish krone","symbol":"kr"},{"code":"(none)","name":"Faroese króna","symbol":"kr"}],"languages":[{"iso639_1":"fo","iso639_2":"fao","name":"Faroese","nativeName":"føroyskt"}],"translations":{"de":"Färöer-Inseln","es":"Islas Faroe","fr":"Îles Féroé","ja":"フェロー諸島","it":"Isole Far Oer","br":"Ilhas Faroé","pt":"Ilhas Faroé","nl":"Faeröer","hr":"Farski Otoci","fa":"جزایر فارو"},"flag":"https://restcountries.eu/data/fro.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":""} +{"name":"Fiji","topLevelDomain":[".fj"],"alpha2Code":"FJ","alpha3Code":"FJI","callingCodes":["679"],"capital":"Suva","altSpellings":["FJ","Viti","Republic of Fiji","Matanitu ko Viti","Fijī Gaṇarājya"],"region":"Oceania","subregion":"Melanesia","population":867000,"latlng":[-18.0,175.0],"demonym":"Fijian","area":18272.0,"gini":42.8,"timezones":["UTC+12:00"],"borders":[],"nativeName":"Fiji","numericCode":"242","currencies":[{"code":"FJD","name":"Fijian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fj","iso639_2":"fij","name":"Fijian","nativeName":"vosa Vakaviti"},{"iso639_1":"hi","iso639_2":"hin","name":"Hindi","nativeName":"हिन्दी"},{"iso639_1":"ur","iso639_2":"urd","name":"Urdu","nativeName":"اردو"}],"translations":{"de":"Fidschi","es":"Fiyi","fr":"Fidji","ja":"フィジー","it":"Figi","br":"Fiji","pt":"Fiji","nl":"Fiji","hr":"Fiđi","fa":"فیجی"},"flag":"https://restcountries.eu/data/fji.svg","regionalBlocs":[],"cioc":"FIJ"} +{"name":"Finland","topLevelDomain":[".fi"],"alpha2Code":"FI","alpha3Code":"FIN","callingCodes":["358"],"capital":"Helsinki","altSpellings":["FI","Suomi","Republic of Finland","Suomen tasavalta","Republiken Finland"],"region":"Europe","subregion":"Northern Europe","population":5491817,"latlng":[64.0,26.0],"demonym":"Finnish","area":338424.0,"gini":26.9,"timezones":["UTC+02:00"],"borders":["NOR","SWE","RUS"],"nativeName":"Suomi","numericCode":"246","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fi","iso639_2":"fin","name":"Finnish","nativeName":"suomi"},{"iso639_1":"sv","iso639_2":"swe","name":"Swedish","nativeName":"svenska"}],"translations":{"de":"Finnland","es":"Finlandia","fr":"Finlande","ja":"フィンランド","it":"Finlandia","br":"Finlândia","pt":"Finlândia","nl":"Finland","hr":"Finska","fa":"فنلاند"},"flag":"https://restcountries.eu/data/fin.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"FIN"} +{"name":"France","topLevelDomain":[".fr"],"alpha2Code":"FR","alpha3Code":"FRA","callingCodes":["33"],"capital":"Paris","altSpellings":["FR","French Republic","République française"],"region":"Europe","subregion":"Western Europe","population":66710000,"latlng":[46.0,2.0],"demonym":"French","area":640679.0,"gini":32.7,"timezones":["UTC-10:00","UTC-09:30","UTC-09:00","UTC-08:00","UTC-04:00","UTC-03:00","UTC+01:00","UTC+03:00","UTC+04:00","UTC+05:00","UTC+11:00","UTC+12:00"],"borders":["AND","BEL","DEU","ITA","LUX","MCO","ESP","CHE"],"nativeName":"France","numericCode":"250","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Frankreich","es":"Francia","fr":"France","ja":"フランス","it":"Francia","br":"França","pt":"França","nl":"Frankrijk","hr":"Francuska","fa":"فرانسه"},"flag":"https://restcountries.eu/data/fra.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"FRA"} +{"name":"French Guiana","topLevelDomain":[".gf"],"alpha2Code":"GF","alpha3Code":"GUF","callingCodes":["594"],"capital":"Cayenne","altSpellings":["GF","Guiana","Guyane"],"region":"Americas","subregion":"South America","population":254541,"latlng":[4.0,-53.0],"demonym":"","area":null,"gini":null,"timezones":["UTC-03:00"],"borders":["BRA","SUR"],"nativeName":"Guyane française","numericCode":"254","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Französisch Guyana","es":"Guayana Francesa","fr":"Guayane","ja":"フランス領ギアナ","it":"Guyana francese","br":"Guiana Francesa","pt":"Guiana Francesa","nl":"Frans-Guyana","hr":"Francuska Gvajana","fa":"گویان فرانسه"},"flag":"https://restcountries.eu/data/guf.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]},{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":""} +{"name":"French Polynesia","topLevelDomain":[".pf"],"alpha2Code":"PF","alpha3Code":"PYF","callingCodes":["689"],"capital":"Papeetē","altSpellings":["PF","Polynésie française","French Polynesia","Pōrīnetia Farāni"],"region":"Oceania","subregion":"Polynesia","population":271800,"latlng":[-15.0,-140.0],"demonym":"French Polynesian","area":4167.0,"gini":null,"timezones":["UTC-10:00","UTC-09:30","UTC-09:00"],"borders":[],"nativeName":"Polynésie française","numericCode":"258","currencies":[{"code":"XPF","name":"CFP franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Französisch-Polynesien","es":"Polinesia Francesa","fr":"Polynésie française","ja":"フランス領ポリネシア","it":"Polinesia Francese","br":"Polinésia Francesa","pt":"Polinésia Francesa","nl":"Frans-Polynesië","hr":"Francuska Polinezija","fa":"پلی‌نزی فرانسه"},"flag":"https://restcountries.eu/data/pyf.svg","regionalBlocs":[],"cioc":""} +{"name":"French Southern Territories","topLevelDomain":[".tf"],"alpha2Code":"TF","alpha3Code":"ATF","callingCodes":[""],"capital":"Port-aux-Français","altSpellings":["TF"],"region":"Africa","subregion":"Southern Africa","population":140,"latlng":[-49.25,69.167],"demonym":"French","area":7747.0,"gini":null,"timezones":["UTC+05:00"],"borders":[],"nativeName":"Territoire des Terres australes et antarctiques françaises","numericCode":"260","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Französische Süd- und Antarktisgebiete","es":"Tierras Australes y Antárticas Francesas","fr":"Terres australes et antarctiques françaises","ja":"フランス領南方・南極地域","it":"Territori Francesi del Sud","br":"Terras Austrais e Antárticas Francesas","pt":"Terras Austrais e Antárticas Francesas","nl":"Franse Gebieden in de zuidelijke Indische Oceaan","hr":"Francuski južni i antarktički teritoriji","fa":"سرزمین‌های جنوبی و جنوبگانی فرانسه"},"flag":"https://restcountries.eu/data/atf.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":""} +{"name":"Gabon","topLevelDomain":[".ga"],"alpha2Code":"GA","alpha3Code":"GAB","callingCodes":["241"],"capital":"Libreville","altSpellings":["GA","Gabonese Republic","République Gabonaise"],"region":"Africa","subregion":"Middle Africa","population":1802278,"latlng":[-1.0,11.75],"demonym":"Gabonese","area":267668.0,"gini":41.5,"timezones":["UTC+01:00"],"borders":["CMR","COG","GNQ"],"nativeName":"Gabon","numericCode":"266","currencies":[{"code":"XAF","name":"Central African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Gabun","es":"Gabón","fr":"Gabon","ja":"ガボン","it":"Gabon","br":"Gabão","pt":"Gabão","nl":"Gabon","hr":"Gabon","fa":"گابن"},"flag":"https://restcountries.eu/data/gab.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"GAB"} +{"name":"Gambia","topLevelDomain":[".gm"],"alpha2Code":"GM","alpha3Code":"GMB","callingCodes":["220"],"capital":"Banjul","altSpellings":["GM","Republic of the Gambia"],"region":"Africa","subregion":"Western Africa","population":1882450,"latlng":[13.46666666,-16.56666666],"demonym":"Gambian","area":11295.0,"gini":null,"timezones":["UTC+00:00"],"borders":["SEN"],"nativeName":"Gambia","numericCode":"270","currencies":[{"code":"GMD","name":"Gambian dalasi","symbol":"D"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Gambia","es":"Gambia","fr":"Gambie","ja":"ガンビア","it":"Gambia","br":"Gâmbia","pt":"Gâmbia","nl":"Gambia","hr":"Gambija","fa":"گامبیا"},"flag":"https://restcountries.eu/data/gmb.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"GAM"} +{"name":"Georgia","topLevelDomain":[".ge"],"alpha2Code":"GE","alpha3Code":"GEO","callingCodes":["995"],"capital":"Tbilisi","altSpellings":["GE","Sakartvelo"],"region":"Asia","subregion":"Western Asia","population":3720400,"latlng":[42.0,43.5],"demonym":"Georgian","area":69700.0,"gini":41.3,"timezones":["UTC-05:00"],"borders":["ARM","AZE","RUS","TUR"],"nativeName":"საქართველო","numericCode":"268","currencies":[{"code":"GEL","name":"Georgian Lari","symbol":"ლ"}],"languages":[{"iso639_1":"ka","iso639_2":"kat","name":"Georgian","nativeName":"ქართული"}],"translations":{"de":"Georgien","es":"Georgia","fr":"Géorgie","ja":"グルジア","it":"Georgia","br":"Geórgia","pt":"Geórgia","nl":"Georgië","hr":"Gruzija","fa":"گرجستان"},"flag":"https://restcountries.eu/data/geo.svg","regionalBlocs":[],"cioc":"GEO"} +{"name":"Germany","topLevelDomain":[".de"],"alpha2Code":"DE","alpha3Code":"DEU","callingCodes":["49"],"capital":"Berlin","altSpellings":["DE","Federal Republic of Germany","Bundesrepublik Deutschland"],"region":"Europe","subregion":"Western Europe","population":81770900,"latlng":[51.0,9.0],"demonym":"German","area":357114.0,"gini":28.3,"timezones":["UTC+01:00"],"borders":["AUT","BEL","CZE","DNK","FRA","LUX","NLD","POL","CHE"],"nativeName":"Deutschland","numericCode":"276","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"}],"translations":{"de":"Deutschland","es":"Alemania","fr":"Allemagne","ja":"ドイツ","it":"Germania","br":"Alemanha","pt":"Alemanha","nl":"Duitsland","hr":"Njemačka","fa":"آلمان"},"flag":"https://restcountries.eu/data/deu.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"GER"} +{"name":"Ghana","topLevelDomain":[".gh"],"alpha2Code":"GH","alpha3Code":"GHA","callingCodes":["233"],"capital":"Accra","altSpellings":["GH"],"region":"Africa","subregion":"Western Africa","population":27670174,"latlng":[8.0,-2.0],"demonym":"Ghanaian","area":238533.0,"gini":42.8,"timezones":["UTC"],"borders":["BFA","CIV","TGO"],"nativeName":"Ghana","numericCode":"288","currencies":[{"code":"GHS","name":"Ghanaian cedi","symbol":"₵"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Ghana","es":"Ghana","fr":"Ghana","ja":"ガーナ","it":"Ghana","br":"Gana","pt":"Gana","nl":"Ghana","hr":"Gana","fa":"غنا"},"flag":"https://restcountries.eu/data/gha.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"GHA"} +{"name":"Gibraltar","topLevelDomain":[".gi"],"alpha2Code":"GI","alpha3Code":"GIB","callingCodes":["350"],"capital":"Gibraltar","altSpellings":["GI"],"region":"Europe","subregion":"Southern Europe","population":33140,"latlng":[36.13333333,-5.35],"demonym":"Gibraltar","area":6.0,"gini":null,"timezones":["UTC+01:00"],"borders":["ESP"],"nativeName":"Gibraltar","numericCode":"292","currencies":[{"code":"GIP","name":"Gibraltar pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Gibraltar","es":"Gibraltar","fr":"Gibraltar","ja":"ジブラルタル","it":"Gibilterra","br":"Gibraltar","pt":"Gibraltar","nl":"Gibraltar","hr":"Gibraltar","fa":"جبل‌طارق"},"flag":"https://restcountries.eu/data/gib.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":""} +{"name":"Greece","topLevelDomain":[".gr"],"alpha2Code":"GR","alpha3Code":"GRC","callingCodes":["30"],"capital":"Athens","altSpellings":["GR","Elláda","Hellenic Republic","Ελληνική Δημοκρατία"],"region":"Europe","subregion":"Southern Europe","population":10858018,"latlng":[39.0,22.0],"demonym":"Greek","area":131990.0,"gini":34.3,"timezones":["UTC+02:00"],"borders":["ALB","BGR","TUR","MKD"],"nativeName":"Ελλάδα","numericCode":"300","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"el","iso639_2":"ell","name":"Greek (modern)","nativeName":"ελληνικά"}],"translations":{"de":"Griechenland","es":"Grecia","fr":"Grèce","ja":"ギリシャ","it":"Grecia","br":"Grécia","pt":"Grécia","nl":"Griekenland","hr":"Grčka","fa":"یونان"},"flag":"https://restcountries.eu/data/grc.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"GRE"} +{"name":"Greenland","topLevelDomain":[".gl"],"alpha2Code":"GL","alpha3Code":"GRL","callingCodes":["299"],"capital":"Nuuk","altSpellings":["GL","Grønland"],"region":"Americas","subregion":"Northern America","population":55847,"latlng":[72.0,-40.0],"demonym":"Greenlandic","area":2166086.0,"gini":null,"timezones":["UTC-04:00","UTC-03:00","UTC-01:00","UTC+00:00"],"borders":[],"nativeName":"Kalaallit Nunaat","numericCode":"304","currencies":[{"code":"DKK","name":"Danish krone","symbol":"kr"}],"languages":[{"iso639_1":"kl","iso639_2":"kal","name":"Kalaallisut","nativeName":"kalaallisut"}],"translations":{"de":"Grönland","es":"Groenlandia","fr":"Groenland","ja":"グリーンランド","it":"Groenlandia","br":"Groelândia","pt":"Gronelândia","nl":"Groenland","hr":"Grenland","fa":"گرینلند"},"flag":"https://restcountries.eu/data/grl.svg","regionalBlocs":[],"cioc":""} +{"name":"Grenada","topLevelDomain":[".gd"],"alpha2Code":"GD","alpha3Code":"GRD","callingCodes":["1473"],"capital":"St. George's","altSpellings":["GD"],"region":"Americas","subregion":"Caribbean","population":103328,"latlng":[12.11666666,-61.66666666],"demonym":"Grenadian","area":344.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Grenada","numericCode":"308","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Grenada","es":"Grenada","fr":"Grenade","ja":"グレナダ","it":"Grenada","br":"Granada","pt":"Granada","nl":"Grenada","hr":"Grenada","fa":"گرنادا"},"flag":"https://restcountries.eu/data/grd.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"GRN"} +{"name":"Guadeloupe","topLevelDomain":[".gp"],"alpha2Code":"GP","alpha3Code":"GLP","callingCodes":["590"],"capital":"Basse-Terre","altSpellings":["GP","Gwadloup"],"region":"Americas","subregion":"Caribbean","population":400132,"latlng":[16.25,-61.583333],"demonym":"Guadeloupian","area":null,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Guadeloupe","numericCode":"312","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Guadeloupe","es":"Guadalupe","fr":"Guadeloupe","ja":"グアドループ","it":"Guadeloupa","br":"Guadalupe","pt":"Guadalupe","nl":"Guadeloupe","hr":"Gvadalupa","fa":"جزیره گوادلوپ"},"flag":"https://restcountries.eu/data/glp.svg","regionalBlocs":[],"cioc":""} +{"name":"Guam","topLevelDomain":[".gu"],"alpha2Code":"GU","alpha3Code":"GUM","callingCodes":["1671"],"capital":"Hagåtña","altSpellings":["GU","Guåhån"],"region":"Oceania","subregion":"Micronesia","population":184200,"latlng":[13.46666666,144.78333333],"demonym":"Guamanian","area":549.0,"gini":null,"timezones":["UTC+10:00"],"borders":[],"nativeName":"Guam","numericCode":"316","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ch","iso639_2":"cha","name":"Chamorro","nativeName":"Chamoru"},{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Guam","es":"Guam","fr":"Guam","ja":"グアム","it":"Guam","br":"Guam","pt":"Guame","nl":"Guam","hr":"Guam","fa":"گوام"},"flag":"https://restcountries.eu/data/gum.svg","regionalBlocs":[],"cioc":"GUM"} +{"name":"Guatemala","topLevelDomain":[".gt"],"alpha2Code":"GT","alpha3Code":"GTM","callingCodes":["502"],"capital":"Guatemala City","altSpellings":["GT"],"region":"Americas","subregion":"Central America","population":16176133,"latlng":[15.5,-90.25],"demonym":"Guatemalan","area":108889.0,"gini":55.9,"timezones":["UTC-06:00"],"borders":["BLZ","SLV","HND","MEX"],"nativeName":"Guatemala","numericCode":"320","currencies":[{"code":"GTQ","name":"Guatemalan quetzal","symbol":"Q"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Guatemala","es":"Guatemala","fr":"Guatemala","ja":"グアテマラ","it":"Guatemala","br":"Guatemala","pt":"Guatemala","nl":"Guatemala","hr":"Gvatemala","fa":"گواتمالا"},"flag":"https://restcountries.eu/data/gtm.svg","regionalBlocs":[{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"GUA"} +{"name":"Guernsey","topLevelDomain":[".gg"],"alpha2Code":"GG","alpha3Code":"GGY","callingCodes":["44"],"capital":"St. Peter Port","altSpellings":["GG","Bailiwick of Guernsey","Bailliage de Guernesey"],"region":"Europe","subregion":"Northern Europe","population":62999,"latlng":[49.46666666,-2.58333333],"demonym":"Channel Islander","area":78.0,"gini":null,"timezones":["UTC+00:00"],"borders":[],"nativeName":"Guernsey","numericCode":"831","currencies":[{"code":"GBP","name":"British pound","symbol":"£"},{"code":"(none)","name":"Guernsey pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Guernsey","es":"Guernsey","fr":"Guernesey","ja":"ガーンジー","it":"Guernsey","br":"Guernsey","pt":"Guernsey","nl":"Guernsey","hr":"Guernsey","fa":"گرنزی"},"flag":"https://restcountries.eu/data/ggy.svg","regionalBlocs":[],"cioc":""} +{"name":"Guinea","topLevelDomain":[".gn"],"alpha2Code":"GN","alpha3Code":"GIN","callingCodes":["224"],"capital":"Conakry","altSpellings":["GN","Republic of Guinea","République de Guinée"],"region":"Africa","subregion":"Western Africa","population":12947000,"latlng":[11.0,-10.0],"demonym":"Guinean","area":245857.0,"gini":39.4,"timezones":["UTC"],"borders":["CIV","GNB","LBR","MLI","SEN","SLE"],"nativeName":"Guinée","numericCode":"324","currencies":[{"code":"GNF","name":"Guinean franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ff","iso639_2":"ful","name":"Fula","nativeName":"Fulfulde"}],"translations":{"de":"Guinea","es":"Guinea","fr":"Guinée","ja":"ギニア","it":"Guinea","br":"Guiné","pt":"Guiné","nl":"Guinee","hr":"Gvineja","fa":"گینه"},"flag":"https://restcountries.eu/data/gin.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"GUI"} +{"name":"Guinea-Bissau","topLevelDomain":[".gw"],"alpha2Code":"GW","alpha3Code":"GNB","callingCodes":["245"],"capital":"Bissau","altSpellings":["GW","Republic of Guinea-Bissau","República da Guiné-Bissau"],"region":"Africa","subregion":"Western Africa","population":1547777,"latlng":[12.0,-15.0],"demonym":"Guinea-Bissauan","area":36125.0,"gini":35.5,"timezones":["UTC"],"borders":["GIN","SEN"],"nativeName":"Guiné-Bissau","numericCode":"624","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Guinea-Bissau","es":"Guinea-Bisáu","fr":"Guinée-Bissau","ja":"ギニアビサウ","it":"Guinea-Bissau","br":"Guiné-Bissau","pt":"Guiné-Bissau","nl":"Guinee-Bissau","hr":"Gvineja Bisau","fa":"گینه بیسائو"},"flag":"https://restcountries.eu/data/gnb.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"GBS"} +{"name":"Guyana","topLevelDomain":[".gy"],"alpha2Code":"GY","alpha3Code":"GUY","callingCodes":["592"],"capital":"Georgetown","altSpellings":["GY","Co-operative Republic of Guyana"],"region":"Americas","subregion":"South America","population":746900,"latlng":[5.0,-59.0],"demonym":"Guyanese","area":214969.0,"gini":44.5,"timezones":["UTC-04:00"],"borders":["BRA","SUR","VEN"],"nativeName":"Guyana","numericCode":"328","currencies":[{"code":"GYD","name":"Guyanese dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Guyana","es":"Guyana","fr":"Guyane","ja":"ガイアナ","it":"Guyana","br":"Guiana","pt":"Guiana","nl":"Guyana","hr":"Gvajana","fa":"گویان"},"flag":"https://restcountries.eu/data/guy.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]},{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"GUY"} +{"name":"Haiti","topLevelDomain":[".ht"],"alpha2Code":"HT","alpha3Code":"HTI","callingCodes":["509"],"capital":"Port-au-Prince","altSpellings":["HT","Republic of Haiti","République d'Haïti","Repiblik Ayiti"],"region":"Americas","subregion":"Caribbean","population":11078033,"latlng":[19.0,-72.41666666],"demonym":"Haitian","area":27750.0,"gini":59.2,"timezones":["UTC-05:00"],"borders":["DOM"],"nativeName":"Haïti","numericCode":"332","currencies":[{"code":"HTG","name":"Haitian gourde","symbol":"G"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"ht","iso639_2":"hat","name":"Haitian","nativeName":"Kreyòl ayisyen"}],"translations":{"de":"Haiti","es":"Haiti","fr":"Haïti","ja":"ハイチ","it":"Haiti","br":"Haiti","pt":"Haiti","nl":"Haïti","hr":"Haiti","fa":"هائیتی"},"flag":"https://restcountries.eu/data/hti.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"HAI"} +{"name":"Heard Island and McDonald Islands","topLevelDomain":[".hm",".aq"],"alpha2Code":"HM","alpha3Code":"HMD","callingCodes":[""],"capital":"","altSpellings":["HM"],"region":"","subregion":"","population":0,"latlng":[-53.1,72.51666666],"demonym":"Heard and McDonald Islander","area":412.0,"gini":null,"timezones":["UTC+05:00"],"borders":[],"nativeName":"Heard Island and McDonald Islands","numericCode":"334","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Heard und die McDonaldinseln","es":"Islas Heard y McDonald","fr":"Îles Heard-et-MacDonald","ja":"ハード島とマクドナルド諸島","it":"Isole Heard e McDonald","br":"Ilha Heard e Ilhas McDonald","pt":"Ilha Heard e Ilhas McDonald","nl":"Heard- en McDonaldeilanden","hr":"Otok Heard i otočje McDonald","fa":"جزیره هرد و جزایر مک‌دونالد"},"flag":"https://restcountries.eu/data/hmd.svg","regionalBlocs":[],"cioc":""} +{"name":"Holy See","topLevelDomain":[".va"],"alpha2Code":"VA","alpha3Code":"VAT","callingCodes":["379"],"capital":"Rome","altSpellings":["Sancta Sedes","Vatican","The Vatican"],"region":"Europe","subregion":"Southern Europe","population":451,"latlng":[41.9,12.45],"demonym":"","area":0.44,"gini":null,"timezones":["UTC+01:00"],"borders":["ITA"],"nativeName":"Sancta Sedes","numericCode":"336","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"la","iso639_2":"lat","name":"Latin","nativeName":"latine"},{"iso639_1":"it","iso639_2":"ita","name":"Italian","nativeName":"Italiano"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"}],"translations":{"de":"Heiliger Stuhl","es":"Santa Sede","fr":"voir Saint","ja":"聖座","it":"Santa Sede","br":"Vaticano","pt":"Vaticano","nl":"Heilige Stoel","hr":"Sveta Stolica","fa":"سریر مقدس"},"flag":"https://restcountries.eu/data/vat.svg","regionalBlocs":[],"cioc":""} +{"name":"Honduras","topLevelDomain":[".hn"],"alpha2Code":"HN","alpha3Code":"HND","callingCodes":["504"],"capital":"Tegucigalpa","altSpellings":["HN","Republic of Honduras","República de Honduras"],"region":"Americas","subregion":"Central America","population":8576532,"latlng":[15.0,-86.5],"demonym":"Honduran","area":112492.0,"gini":57.0,"timezones":["UTC-06:00"],"borders":["GTM","SLV","NIC"],"nativeName":"Honduras","numericCode":"340","currencies":[{"code":"HNL","name":"Honduran lempira","symbol":"L"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Honduras","es":"Honduras","fr":"Honduras","ja":"ホンジュラス","it":"Honduras","br":"Honduras","pt":"Honduras","nl":"Honduras","hr":"Honduras","fa":"هندوراس"},"flag":"https://restcountries.eu/data/hnd.svg","regionalBlocs":[{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"HON"} +{"name":"Hong Kong","topLevelDomain":[".hk"],"alpha2Code":"HK","alpha3Code":"HKG","callingCodes":["852"],"capital":"City of Victoria","altSpellings":["HK","香港"],"region":"Asia","subregion":"Eastern Asia","population":7324300,"latlng":[22.25,114.16666666],"demonym":"Chinese","area":1104.0,"gini":53.3,"timezones":["UTC+08:00"],"borders":["CHN"],"nativeName":"香港","numericCode":"344","currencies":[{"code":"HKD","name":"Hong Kong dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"zh","iso639_2":"zho","name":"Chinese","nativeName":"中文 (Zhōngwén)"}],"translations":{"de":"Hong Kong","es":"Hong Kong","fr":"Hong Kong","ja":"香港","it":"Hong Kong","br":"Hong Kong","pt":"Hong Kong","nl":"Hongkong","hr":"Hong Kong","fa":"هنگ‌کنگ"},"flag":"https://restcountries.eu/data/hkg.svg","regionalBlocs":[],"cioc":"HKG"} +{"name":"Hungary","topLevelDomain":[".hu"],"alpha2Code":"HU","alpha3Code":"HUN","callingCodes":["36"],"capital":"Budapest","altSpellings":["HU"],"region":"Europe","subregion":"Eastern Europe","population":9823000,"latlng":[47.0,20.0],"demonym":"Hungarian","area":93028.0,"gini":31.2,"timezones":["UTC+01:00"],"borders":["AUT","HRV","ROU","SRB","SVK","SVN","UKR"],"nativeName":"Magyarország","numericCode":"348","currencies":[{"code":"HUF","name":"Hungarian forint","symbol":"Ft"}],"languages":[{"iso639_1":"hu","iso639_2":"hun","name":"Hungarian","nativeName":"magyar"}],"translations":{"de":"Ungarn","es":"Hungría","fr":"Hongrie","ja":"ハンガリー","it":"Ungheria","br":"Hungria","pt":"Hungria","nl":"Hongarije","hr":"Mađarska","fa":"مجارستان"},"flag":"https://restcountries.eu/data/hun.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"HUN"} +{"name":"Iceland","topLevelDomain":[".is"],"alpha2Code":"IS","alpha3Code":"ISL","callingCodes":["354"],"capital":"Reykjavík","altSpellings":["IS","Island","Republic of Iceland","Lýðveldið Ísland"],"region":"Europe","subregion":"Northern Europe","population":334300,"latlng":[65.0,-18.0],"demonym":"Icelander","area":103000.0,"gini":null,"timezones":["UTC"],"borders":[],"nativeName":"Ísland","numericCode":"352","currencies":[{"code":"ISK","name":"Icelandic króna","symbol":"kr"}],"languages":[{"iso639_1":"is","iso639_2":"isl","name":"Icelandic","nativeName":"Íslenska"}],"translations":{"de":"Island","es":"Islandia","fr":"Islande","ja":"アイスランド","it":"Islanda","br":"Islândia","pt":"Islândia","nl":"IJsland","hr":"Island","fa":"ایسلند"},"flag":"https://restcountries.eu/data/isl.svg","regionalBlocs":[{"acronym":"EFTA","name":"European Free Trade Association","otherAcronyms":[],"otherNames":[]}],"cioc":"ISL"} +{"name":"India","topLevelDomain":[".in"],"alpha2Code":"IN","alpha3Code":"IND","callingCodes":["91"],"capital":"New Delhi","altSpellings":["IN","Bhārat","Republic of India","Bharat Ganrajya"],"region":"Asia","subregion":"Southern Asia","population":1295210000,"latlng":[20.0,77.0],"demonym":"Indian","area":3287590.0,"gini":33.4,"timezones":["UTC+05:30"],"borders":["AFG","BGD","BTN","MMR","CHN","NPL","PAK","LKA"],"nativeName":"भारत","numericCode":"356","currencies":[{"code":"INR","name":"Indian rupee","symbol":"₹"}],"languages":[{"iso639_1":"hi","iso639_2":"hin","name":"Hindi","nativeName":"हिन्दी"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Indien","es":"India","fr":"Inde","ja":"インド","it":"India","br":"Índia","pt":"Índia","nl":"India","hr":"Indija","fa":"هند"},"flag":"https://restcountries.eu/data/ind.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"IND"} +{"name":"Indonesia","topLevelDomain":[".id"],"alpha2Code":"ID","alpha3Code":"IDN","callingCodes":["62"],"capital":"Jakarta","altSpellings":["ID","Republic of Indonesia","Republik Indonesia"],"region":"Asia","subregion":"South-Eastern Asia","population":258705000,"latlng":[-5.0,120.0],"demonym":"Indonesian","area":1904569.0,"gini":34.0,"timezones":["UTC+07:00","UTC+08:00","UTC+09:00"],"borders":["TLS","MYS","PNG"],"nativeName":"Indonesia","numericCode":"360","currencies":[{"code":"IDR","name":"Indonesian rupiah","symbol":"Rp"}],"languages":[{"iso639_1":"id","iso639_2":"ind","name":"Indonesian","nativeName":"Bahasa Indonesia"}],"translations":{"de":"Indonesien","es":"Indonesia","fr":"Indonésie","ja":"インドネシア","it":"Indonesia","br":"Indonésia","pt":"Indonésia","nl":"Indonesië","hr":"Indonezija","fa":"اندونزی"},"flag":"https://restcountries.eu/data/idn.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"INA"} +{"name":"Côte d'Ivoire","topLevelDomain":[".ci"],"alpha2Code":"CI","alpha3Code":"CIV","callingCodes":["225"],"capital":"Yamoussoukro","altSpellings":["CI","Ivory Coast","Republic of Côte d'Ivoire","République de Côte d'Ivoire"],"region":"Africa","subregion":"Western Africa","population":22671331,"latlng":[8.0,-5.0],"demonym":"Ivorian","area":322463.0,"gini":41.5,"timezones":["UTC"],"borders":["BFA","GHA","GIN","LBR","MLI"],"nativeName":"Côte d'Ivoire","numericCode":"384","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Elfenbeinküste","es":"Costa de Marfil","fr":"Côte d'Ivoire","ja":"コートジボワール","it":"Costa D'Avorio","br":"Costa do Marfim","pt":"Costa do Marfim","nl":"Ivoorkust","hr":"Obala Bjelokosti","fa":"ساحل عاج"},"flag":"https://restcountries.eu/data/civ.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"CIV"} +{"name":"Iran (Islamic Republic of)","topLevelDomain":[".ir"],"alpha2Code":"IR","alpha3Code":"IRN","callingCodes":["98"],"capital":"Tehran","altSpellings":["IR","Islamic Republic of Iran","Jomhuri-ye Eslāmi-ye Irān"],"region":"Asia","subregion":"Southern Asia","population":79369900,"latlng":[32.0,53.0],"demonym":"Iranian","area":1648195.0,"gini":38.3,"timezones":["UTC+03:30"],"borders":["AFG","ARM","AZE","IRQ","PAK","TUR","TKM"],"nativeName":"ایران","numericCode":"364","currencies":[{"code":"IRR","name":"Iranian rial","symbol":"﷼"}],"languages":[{"iso639_1":"fa","iso639_2":"fas","name":"Persian (Farsi)","nativeName":"فارسی"}],"translations":{"de":"Iran","es":"Iran","fr":"Iran","ja":"イラン・イスラム共和国","it":null,"br":"Irã","pt":"Irão","nl":"Iran","hr":"Iran","fa":"ایران"},"flag":"https://restcountries.eu/data/irn.svg","regionalBlocs":[],"cioc":"IRI"} +{"name":"Iraq","topLevelDomain":[".iq"],"alpha2Code":"IQ","alpha3Code":"IRQ","callingCodes":["964"],"capital":"Baghdad","altSpellings":["IQ","Republic of Iraq","Jumhūriyyat al-‘Irāq"],"region":"Asia","subregion":"Western Asia","population":37883543,"latlng":[33.0,44.0],"demonym":"Iraqi","area":438317.0,"gini":30.9,"timezones":["UTC+03:00"],"borders":["IRN","JOR","KWT","SAU","SYR","TUR"],"nativeName":"العراق","numericCode":"368","currencies":[{"code":"IQD","name":"Iraqi dinar","symbol":"ع.د"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"},{"iso639_1":"ku","iso639_2":"kur","name":"Kurdish","nativeName":"Kurdî"}],"translations":{"de":"Irak","es":"Irak","fr":"Irak","ja":"イラク","it":"Iraq","br":"Iraque","pt":"Iraque","nl":"Irak","hr":"Irak","fa":"عراق"},"flag":"https://restcountries.eu/data/irq.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"IRQ"} +{"name":"Ireland","topLevelDomain":[".ie"],"alpha2Code":"IE","alpha3Code":"IRL","callingCodes":["353"],"capital":"Dublin","altSpellings":["IE","Éire","Republic of Ireland","Poblacht na hÉireann"],"region":"Europe","subregion":"Northern Europe","population":6378000,"latlng":[53.0,-8.0],"demonym":"Irish","area":70273.0,"gini":34.3,"timezones":["UTC"],"borders":["GBR"],"nativeName":"Éire","numericCode":"372","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"ga","iso639_2":"gle","name":"Irish","nativeName":"Gaeilge"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Irland","es":"Irlanda","fr":"Irlande","ja":"アイルランド","it":"Irlanda","br":"Irlanda","pt":"Irlanda","nl":"Ierland","hr":"Irska","fa":"ایرلند"},"flag":"https://restcountries.eu/data/irl.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"IRL"} +{"name":"Isle of Man","topLevelDomain":[".im"],"alpha2Code":"IM","alpha3Code":"IMN","callingCodes":["44"],"capital":"Douglas","altSpellings":["IM","Ellan Vannin","Mann","Mannin"],"region":"Europe","subregion":"Northern Europe","population":84497,"latlng":[54.25,-4.5],"demonym":"Manx","area":572.0,"gini":null,"timezones":["UTC+00:00"],"borders":[],"nativeName":"Isle of Man","numericCode":"833","currencies":[{"code":"GBP","name":"British pound","symbol":"£"},{"code":"IMP[G]","name":"Manx pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"gv","iso639_2":"glv","name":"Manx","nativeName":"Gaelg"}],"translations":{"de":"Insel Man","es":"Isla de Man","fr":"Île de Man","ja":"マン島","it":"Isola di Man","br":"Ilha de Man","pt":"Ilha de Man","nl":"Isle of Man","hr":"Otok Man","fa":"جزیره من"},"flag":"https://restcountries.eu/data/imn.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":""} +{"name":"Israel","topLevelDomain":[".il"],"alpha2Code":"IL","alpha3Code":"ISR","callingCodes":["972"],"capital":"Jerusalem","altSpellings":["IL","State of Israel","Medīnat Yisrā'el"],"region":"Asia","subregion":"Western Asia","population":8527400,"latlng":[31.5,34.75],"demonym":"Israeli","area":20770.0,"gini":39.2,"timezones":["UTC+02:00"],"borders":["EGY","JOR","LBN","SYR"],"nativeName":"יִשְׂרָאֵל","numericCode":"376","currencies":[{"code":"ILS","name":"Israeli new shekel","symbol":"₪"}],"languages":[{"iso639_1":"he","iso639_2":"heb","name":"Hebrew (modern)","nativeName":"עברית"},{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Israel","es":"Israel","fr":"Israël","ja":"イスラエル","it":"Israele","br":"Israel","pt":"Israel","nl":"Israël","hr":"Izrael","fa":"اسرائیل"},"flag":"https://restcountries.eu/data/isr.svg","regionalBlocs":[],"cioc":"ISR"} +{"name":"Italy","topLevelDomain":[".it"],"alpha2Code":"IT","alpha3Code":"ITA","callingCodes":["39"],"capital":"Rome","altSpellings":["IT","Italian Republic","Repubblica italiana"],"region":"Europe","subregion":"Southern Europe","population":60665551,"latlng":[42.83333333,12.83333333],"demonym":"Italian","area":301336.0,"gini":36.0,"timezones":["UTC+01:00"],"borders":["AUT","FRA","SMR","SVN","CHE","VAT"],"nativeName":"Italia","numericCode":"380","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"it","iso639_2":"ita","name":"Italian","nativeName":"Italiano"}],"translations":{"de":"Italien","es":"Italia","fr":"Italie","ja":"イタリア","it":"Italia","br":"Itália","pt":"Itália","nl":"Italië","hr":"Italija","fa":"ایتالیا"},"flag":"https://restcountries.eu/data/ita.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"ITA"} +{"name":"Jamaica","topLevelDomain":[".jm"],"alpha2Code":"JM","alpha3Code":"JAM","callingCodes":["1876"],"capital":"Kingston","altSpellings":["JM"],"region":"Americas","subregion":"Caribbean","population":2723246,"latlng":[18.25,-77.5],"demonym":"Jamaican","area":10991.0,"gini":45.5,"timezones":["UTC-05:00"],"borders":[],"nativeName":"Jamaica","numericCode":"388","currencies":[{"code":"JMD","name":"Jamaican dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Jamaika","es":"Jamaica","fr":"Jamaïque","ja":"ジャマイカ","it":"Giamaica","br":"Jamaica","pt":"Jamaica","nl":"Jamaica","hr":"Jamajka","fa":"جامائیکا"},"flag":"https://restcountries.eu/data/jam.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"JAM"} +{"name":"Japan","topLevelDomain":[".jp"],"alpha2Code":"JP","alpha3Code":"JPN","callingCodes":["81"],"capital":"Tokyo","altSpellings":["JP","Nippon","Nihon"],"region":"Asia","subregion":"Eastern Asia","population":126960000,"latlng":[36.0,138.0],"demonym":"Japanese","area":377930.0,"gini":38.1,"timezones":["UTC+09:00"],"borders":[],"nativeName":"日本","numericCode":"392","currencies":[{"code":"JPY","name":"Japanese yen","symbol":"¥"}],"languages":[{"iso639_1":"ja","iso639_2":"jpn","name":"Japanese","nativeName":"日本語 (にほんご)"}],"translations":{"de":"Japan","es":"Japón","fr":"Japon","ja":"日本","it":"Giappone","br":"Japão","pt":"Japão","nl":"Japan","hr":"Japan","fa":"ژاپن"},"flag":"https://restcountries.eu/data/jpn.svg","regionalBlocs":[],"cioc":"JPN"} +{"name":"Jersey","topLevelDomain":[".je"],"alpha2Code":"JE","alpha3Code":"JEY","callingCodes":["44"],"capital":"Saint Helier","altSpellings":["JE","Bailiwick of Jersey","Bailliage de Jersey","Bailliage dé Jèrri"],"region":"Europe","subregion":"Northern Europe","population":100800,"latlng":[49.25,-2.16666666],"demonym":"Channel Islander","area":116.0,"gini":null,"timezones":["UTC+01:00"],"borders":[],"nativeName":"Jersey","numericCode":"832","currencies":[{"code":"GBP","name":"British pound","symbol":"£"},{"code":"JEP[G]","name":"Jersey pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Jersey","es":"Jersey","fr":"Jersey","ja":"ジャージー","it":"Isola di Jersey","br":"Jersey","pt":"Jersey","nl":"Jersey","hr":"Jersey","fa":"جرزی"},"flag":"https://restcountries.eu/data/jey.svg","regionalBlocs":[],"cioc":""} +{"name":"Jordan","topLevelDomain":[".jo"],"alpha2Code":"JO","alpha3Code":"JOR","callingCodes":["962"],"capital":"Amman","altSpellings":["JO","Hashemite Kingdom of Jordan","al-Mamlakah al-Urdunīyah al-Hāshimīyah"],"region":"Asia","subregion":"Western Asia","population":9531712,"latlng":[31.0,36.0],"demonym":"Jordanian","area":89342.0,"gini":35.4,"timezones":["UTC+03:00"],"borders":["IRQ","ISR","SAU","SYR"],"nativeName":"الأردن","numericCode":"400","currencies":[{"code":"JOD","name":"Jordanian dinar","symbol":"د.ا"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Jordanien","es":"Jordania","fr":"Jordanie","ja":"ヨルダン","it":"Giordania","br":"Jordânia","pt":"Jordânia","nl":"Jordanië","hr":"Jordan","fa":"اردن"},"flag":"https://restcountries.eu/data/jor.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"JOR"} +{"name":"Kazakhstan","topLevelDomain":[".kz",".қаз"],"alpha2Code":"KZ","alpha3Code":"KAZ","callingCodes":["76","77"],"capital":"Astana","altSpellings":["KZ","Qazaqstan","Казахстан","Republic of Kazakhstan","Қазақстан Республикасы","Qazaqstan Respublïkası","Республика Казахстан","Respublika Kazakhstan"],"region":"Asia","subregion":"Central Asia","population":17753200,"latlng":[48.0,68.0],"demonym":"Kazakhstani","area":2724900.0,"gini":29.0,"timezones":["UTC+05:00","UTC+06:00"],"borders":["CHN","KGZ","RUS","TKM","UZB"],"nativeName":"Қазақстан","numericCode":"398","currencies":[{"code":"KZT","name":"Kazakhstani tenge","symbol":null}],"languages":[{"iso639_1":"kk","iso639_2":"kaz","name":"Kazakh","nativeName":"қазақ тілі"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Kasachstan","es":"Kazajistán","fr":"Kazakhstan","ja":"カザフスタン","it":"Kazakistan","br":"Cazaquistão","pt":"Cazaquistão","nl":"Kazachstan","hr":"Kazahstan","fa":"قزاقستان"},"flag":"https://restcountries.eu/data/kaz.svg","regionalBlocs":[{"acronym":"EEU","name":"Eurasian Economic Union","otherAcronyms":["EAEU"],"otherNames":[]}],"cioc":"KAZ"} +{"name":"Kenya","topLevelDomain":[".ke"],"alpha2Code":"KE","alpha3Code":"KEN","callingCodes":["254"],"capital":"Nairobi","altSpellings":["KE","Republic of Kenya","Jamhuri ya Kenya"],"region":"Africa","subregion":"Eastern Africa","population":47251000,"latlng":[1.0,38.0],"demonym":"Kenyan","area":580367.0,"gini":47.7,"timezones":["UTC+03:00"],"borders":["ETH","SOM","SSD","TZA","UGA"],"nativeName":"Kenya","numericCode":"404","currencies":[{"code":"KES","name":"Kenyan shilling","symbol":"Sh"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"sw","iso639_2":"swa","name":"Swahili","nativeName":"Kiswahili"}],"translations":{"de":"Kenia","es":"Kenia","fr":"Kenya","ja":"ケニア","it":"Kenya","br":"Quênia","pt":"Quénia","nl":"Kenia","hr":"Kenija","fa":"کنیا"},"flag":"https://restcountries.eu/data/ken.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"KEN"} +{"name":"Kiribati","topLevelDomain":[".ki"],"alpha2Code":"KI","alpha3Code":"KIR","callingCodes":["686"],"capital":"South Tarawa","altSpellings":["KI","Republic of Kiribati","Ribaberiki Kiribati"],"region":"Oceania","subregion":"Micronesia","population":113400,"latlng":[1.41666666,173.0],"demonym":"I-Kiribati","area":811.0,"gini":null,"timezones":["UTC+12:00","UTC+13:00","UTC+14:00"],"borders":[],"nativeName":"Kiribati","numericCode":"296","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"},{"code":"(none)","name":"Kiribati dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Kiribati","es":"Kiribati","fr":"Kiribati","ja":"キリバス","it":"Kiribati","br":"Kiribati","pt":"Quiribáti","nl":"Kiribati","hr":"Kiribati","fa":"کیریباتی"},"flag":"https://restcountries.eu/data/kir.svg","regionalBlocs":[],"cioc":"KIR"} +{"name":"Kuwait","topLevelDomain":[".kw"],"alpha2Code":"KW","alpha3Code":"KWT","callingCodes":["965"],"capital":"Kuwait City","altSpellings":["KW","State of Kuwait","Dawlat al-Kuwait"],"region":"Asia","subregion":"Western Asia","population":4183658,"latlng":[29.5,45.75],"demonym":"Kuwaiti","area":17818.0,"gini":null,"timezones":["UTC+03:00"],"borders":["IRN","SAU"],"nativeName":"الكويت","numericCode":"414","currencies":[{"code":"KWD","name":"Kuwaiti dinar","symbol":"د.ك"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Kuwait","es":"Kuwait","fr":"Koweït","ja":"クウェート","it":"Kuwait","br":"Kuwait","pt":"Kuwait","nl":"Koeweit","hr":"Kuvajt","fa":"کویت"},"flag":"https://restcountries.eu/data/kwt.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"KUW"} +{"name":"Kyrgyzstan","topLevelDomain":[".kg"],"alpha2Code":"KG","alpha3Code":"KGZ","callingCodes":["996"],"capital":"Bishkek","altSpellings":["KG","Киргизия","Kyrgyz Republic","Кыргыз Республикасы","Kyrgyz Respublikasy"],"region":"Asia","subregion":"Central Asia","population":6047800,"latlng":[41.0,75.0],"demonym":"Kirghiz","area":199951.0,"gini":36.2,"timezones":["UTC+06:00"],"borders":["CHN","KAZ","TJK","UZB"],"nativeName":"Кыргызстан","numericCode":"417","currencies":[{"code":"KGS","name":"Kyrgyzstani som","symbol":"с"}],"languages":[{"iso639_1":"ky","iso639_2":"kir","name":"Kyrgyz","nativeName":"Кыргызча"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Kirgisistan","es":"Kirguizistán","fr":"Kirghizistan","ja":"キルギス","it":"Kirghizistan","br":"Quirguistão","pt":"Quirguizistão","nl":"Kirgizië","hr":"Kirgistan","fa":"قرقیزستان"},"flag":"https://restcountries.eu/data/kgz.svg","regionalBlocs":[{"acronym":"EEU","name":"Eurasian Economic Union","otherAcronyms":["EAEU"],"otherNames":[]}],"cioc":"KGZ"} +{"name":"Lao People's Democratic Republic","topLevelDomain":[".la"],"alpha2Code":"LA","alpha3Code":"LAO","callingCodes":["856"],"capital":"Vientiane","altSpellings":["LA","Lao","Laos","Lao People's Democratic Republic","Sathalanalat Paxathipatai Paxaxon Lao"],"region":"Asia","subregion":"South-Eastern Asia","population":6492400,"latlng":[18.0,105.0],"demonym":"Laotian","area":236800.0,"gini":36.7,"timezones":["UTC+07:00"],"borders":["MMR","KHM","CHN","THA","VNM"],"nativeName":"ສປປລາວ","numericCode":"418","currencies":[{"code":"LAK","name":"Lao kip","symbol":"₭"}],"languages":[{"iso639_1":"lo","iso639_2":"lao","name":"Lao","nativeName":"ພາສາລາວ"}],"translations":{"de":"Laos","es":"Laos","fr":"Laos","ja":"ラオス人民民主共和国","it":"Laos","br":"Laos","pt":"Laos","nl":"Laos","hr":"Laos","fa":"لائوس"},"flag":"https://restcountries.eu/data/lao.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"LAO"} +{"name":"Latvia","topLevelDomain":[".lv"],"alpha2Code":"LV","alpha3Code":"LVA","callingCodes":["371"],"capital":"Riga","altSpellings":["LV","Republic of Latvia","Latvijas Republika"],"region":"Europe","subregion":"Northern Europe","population":1961600,"latlng":[57.0,25.0],"demonym":"Latvian","area":64559.0,"gini":36.6,"timezones":["UTC+02:00"],"borders":["BLR","EST","LTU","RUS"],"nativeName":"Latvija","numericCode":"428","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"lv","iso639_2":"lav","name":"Latvian","nativeName":"latviešu valoda"}],"translations":{"de":"Lettland","es":"Letonia","fr":"Lettonie","ja":"ラトビア","it":"Lettonia","br":"Letônia","pt":"Letónia","nl":"Letland","hr":"Latvija","fa":"لتونی"},"flag":"https://restcountries.eu/data/lva.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"LAT"} +{"name":"Lebanon","topLevelDomain":[".lb"],"alpha2Code":"LB","alpha3Code":"LBN","callingCodes":["961"],"capital":"Beirut","altSpellings":["LB","Lebanese Republic","Al-Jumhūrīyah Al-Libnānīyah"],"region":"Asia","subregion":"Western Asia","population":5988000,"latlng":[33.83333333,35.83333333],"demonym":"Lebanese","area":10452.0,"gini":null,"timezones":["UTC+02:00"],"borders":["ISR","SYR"],"nativeName":"لبنان","numericCode":"422","currencies":[{"code":"LBP","name":"Lebanese pound","symbol":"ل.ل"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Libanon","es":"Líbano","fr":"Liban","ja":"レバノン","it":"Libano","br":"Líbano","pt":"Líbano","nl":"Libanon","hr":"Libanon","fa":"لبنان"},"flag":"https://restcountries.eu/data/lbn.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"LIB"} +{"name":"Lesotho","topLevelDomain":[".ls"],"alpha2Code":"LS","alpha3Code":"LSO","callingCodes":["266"],"capital":"Maseru","altSpellings":["LS","Kingdom of Lesotho","Muso oa Lesotho"],"region":"Africa","subregion":"Southern Africa","population":1894194,"latlng":[-29.5,28.5],"demonym":"Mosotho","area":30355.0,"gini":52.5,"timezones":["UTC+02:00"],"borders":["ZAF"],"nativeName":"Lesotho","numericCode":"426","currencies":[{"code":"LSL","name":"Lesotho loti","symbol":"L"},{"code":"ZAR","name":"South African rand","symbol":"R"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"st","iso639_2":"sot","name":"Southern Sotho","nativeName":"Sesotho"}],"translations":{"de":"Lesotho","es":"Lesotho","fr":"Lesotho","ja":"レソト","it":"Lesotho","br":"Lesoto","pt":"Lesoto","nl":"Lesotho","hr":"Lesoto","fa":"لسوتو"},"flag":"https://restcountries.eu/data/lso.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"LES"} +{"name":"Liberia","topLevelDomain":[".lr"],"alpha2Code":"LR","alpha3Code":"LBR","callingCodes":["231"],"capital":"Monrovia","altSpellings":["LR","Republic of Liberia"],"region":"Africa","subregion":"Western Africa","population":4615000,"latlng":[6.5,-9.5],"demonym":"Liberian","area":111369.0,"gini":38.2,"timezones":["UTC"],"borders":["GIN","CIV","SLE"],"nativeName":"Liberia","numericCode":"430","currencies":[{"code":"LRD","name":"Liberian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Liberia","es":"Liberia","fr":"Liberia","ja":"リベリア","it":"Liberia","br":"Libéria","pt":"Libéria","nl":"Liberia","hr":"Liberija","fa":"لیبریا"},"flag":"https://restcountries.eu/data/lbr.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"LBR"} +{"name":"Libya","topLevelDomain":[".ly"],"alpha2Code":"LY","alpha3Code":"LBY","callingCodes":["218"],"capital":"Tripoli","altSpellings":["LY","State of Libya","Dawlat Libya"],"region":"Africa","subregion":"Northern Africa","population":6385000,"latlng":[25.0,17.0],"demonym":"Libyan","area":1759540.0,"gini":null,"timezones":["UTC+01:00"],"borders":["DZA","TCD","EGY","NER","SDN","TUN"],"nativeName":"‏ليبيا","numericCode":"434","currencies":[{"code":"LYD","name":"Libyan dinar","symbol":"ل.د"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Libyen","es":"Libia","fr":"Libye","ja":"リビア","it":"Libia","br":"Líbia","pt":"Líbia","nl":"Libië","hr":"Libija","fa":"لیبی"},"flag":"https://restcountries.eu/data/lby.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"LBA"} +{"name":"Liechtenstein","topLevelDomain":[".li"],"alpha2Code":"LI","alpha3Code":"LIE","callingCodes":["423"],"capital":"Vaduz","altSpellings":["LI","Principality of Liechtenstein","Fürstentum Liechtenstein"],"region":"Europe","subregion":"Western Europe","population":37623,"latlng":[47.26666666,9.53333333],"demonym":"Liechtensteiner","area":160.0,"gini":null,"timezones":["UTC+01:00"],"borders":["AUT","CHE"],"nativeName":"Liechtenstein","numericCode":"438","currencies":[{"code":"CHF","name":"Swiss franc","symbol":"Fr"}],"languages":[{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"}],"translations":{"de":"Liechtenstein","es":"Liechtenstein","fr":"Liechtenstein","ja":"リヒテンシュタイン","it":"Liechtenstein","br":"Liechtenstein","pt":"Listenstaine","nl":"Liechtenstein","hr":"Lihtenštajn","fa":"لیختن‌اشتاین"},"flag":"https://restcountries.eu/data/lie.svg","regionalBlocs":[{"acronym":"EFTA","name":"European Free Trade Association","otherAcronyms":[],"otherNames":[]}],"cioc":"LIE"} +{"name":"Lithuania","topLevelDomain":[".lt"],"alpha2Code":"LT","alpha3Code":"LTU","callingCodes":["370"],"capital":"Vilnius","altSpellings":["LT","Republic of Lithuania","Lietuvos Respublika"],"region":"Europe","subregion":"Northern Europe","population":2872294,"latlng":[56.0,24.0],"demonym":"Lithuanian","area":65300.0,"gini":37.6,"timezones":["UTC+02:00"],"borders":["BLR","LVA","POL","RUS"],"nativeName":"Lietuva","numericCode":"440","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"lt","iso639_2":"lit","name":"Lithuanian","nativeName":"lietuvių kalba"}],"translations":{"de":"Litauen","es":"Lituania","fr":"Lituanie","ja":"リトアニア","it":"Lituania","br":"Lituânia","pt":"Lituânia","nl":"Litouwen","hr":"Litva","fa":"لیتوانی"},"flag":"https://restcountries.eu/data/ltu.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"LTU"} +{"name":"Luxembourg","topLevelDomain":[".lu"],"alpha2Code":"LU","alpha3Code":"LUX","callingCodes":["352"],"capital":"Luxembourg","altSpellings":["LU","Grand Duchy of Luxembourg","Grand-Duché de Luxembourg","Großherzogtum Luxemburg","Groussherzogtum Lëtzebuerg"],"region":"Europe","subregion":"Western Europe","population":576200,"latlng":[49.75,6.16666666],"demonym":"Luxembourger","area":2586.0,"gini":30.8,"timezones":["UTC+01:00"],"borders":["BEL","FRA","DEU"],"nativeName":"Luxembourg","numericCode":"442","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"},{"iso639_1":"lb","iso639_2":"ltz","name":"Luxembourgish","nativeName":"Lëtzebuergesch"}],"translations":{"de":"Luxemburg","es":"Luxemburgo","fr":"Luxembourg","ja":"ルクセンブルク","it":"Lussemburgo","br":"Luxemburgo","pt":"Luxemburgo","nl":"Luxemburg","hr":"Luksemburg","fa":"لوکزامبورگ"},"flag":"https://restcountries.eu/data/lux.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"LUX"} +{"name":"Macao","topLevelDomain":[".mo"],"alpha2Code":"MO","alpha3Code":"MAC","callingCodes":["853"],"capital":"","altSpellings":["MO","澳门","Macao Special Administrative Region of the People's Republic of China","中華人民共和國澳門特別行政區","Região Administrativa Especial de Macau da República Popular da China"],"region":"Asia","subregion":"Eastern Asia","population":649100,"latlng":[22.16666666,113.55],"demonym":"Chinese","area":30.0,"gini":null,"timezones":["UTC+08:00"],"borders":["CHN"],"nativeName":"澳門","numericCode":"446","currencies":[{"code":"MOP","name":"Macanese pataca","symbol":"P"}],"languages":[{"iso639_1":"zh","iso639_2":"zho","name":"Chinese","nativeName":"中文 (Zhōngwén)"},{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Macao","es":"Macao","fr":"Macao","ja":"マカオ","it":"Macao","br":"Macau","pt":"Macau","nl":"Macao","hr":"Makao","fa":"مکائو"},"flag":"https://restcountries.eu/data/mac.svg","regionalBlocs":[],"cioc":""} +{"name":"Macedonia (the former Yugoslav Republic of)","topLevelDomain":[".mk"],"alpha2Code":"MK","alpha3Code":"MKD","callingCodes":["389"],"capital":"Skopje","altSpellings":["MK","Republic of Macedonia","Република Македонија"],"region":"Europe","subregion":"Southern Europe","population":2058539,"latlng":[41.83333333,22.0],"demonym":"Macedonian","area":25713.0,"gini":43.2,"timezones":["UTC+01:00"],"borders":["ALB","BGR","GRC","KOS","SRB"],"nativeName":"Македонија","numericCode":"807","currencies":[{"code":"MKD","name":"Macedonian denar","symbol":"ден"}],"languages":[{"iso639_1":"mk","iso639_2":"mkd","name":"Macedonian","nativeName":"македонски јазик"}],"translations":{"de":"Mazedonien","es":"Macedonia","fr":"Macédoine","ja":"マケドニア旧ユーゴスラビア共和国","it":"Macedonia","br":"Macedônia","pt":"Macedónia","nl":"Macedonië","hr":"Makedonija","fa":""},"flag":"https://restcountries.eu/data/mkd.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":"MKD"} +{"name":"Madagascar","topLevelDomain":[".mg"],"alpha2Code":"MG","alpha3Code":"MDG","callingCodes":["261"],"capital":"Antananarivo","altSpellings":["MG","Republic of Madagascar","Repoblikan'i Madagasikara","République de Madagascar"],"region":"Africa","subregion":"Eastern Africa","population":22434363,"latlng":[-20.0,47.0],"demonym":"Malagasy","area":587041.0,"gini":44.1,"timezones":["UTC+03:00"],"borders":[],"nativeName":"Madagasikara","numericCode":"450","currencies":[{"code":"MGA","name":"Malagasy ariary","symbol":"Ar"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"mg","iso639_2":"mlg","name":"Malagasy","nativeName":"fiteny malagasy"}],"translations":{"de":"Madagaskar","es":"Madagascar","fr":"Madagascar","ja":"マダガスカル","it":"Madagascar","br":"Madagascar","pt":"Madagáscar","nl":"Madagaskar","hr":"Madagaskar","fa":"ماداگاسکار"},"flag":"https://restcountries.eu/data/mdg.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"MAD"} +{"name":"Malawi","topLevelDomain":[".mw"],"alpha2Code":"MW","alpha3Code":"MWI","callingCodes":["265"],"capital":"Lilongwe","altSpellings":["MW","Republic of Malawi"],"region":"Africa","subregion":"Eastern Africa","population":16832910,"latlng":[-13.5,34.0],"demonym":"Malawian","area":118484.0,"gini":39.0,"timezones":["UTC+02:00"],"borders":["MOZ","TZA","ZMB"],"nativeName":"Malawi","numericCode":"454","currencies":[{"code":"MWK","name":"Malawian kwacha","symbol":"MK"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ny","iso639_2":"nya","name":"Chichewa","nativeName":"chiCheŵa"}],"translations":{"de":"Malawi","es":"Malawi","fr":"Malawi","ja":"マラウイ","it":"Malawi","br":"Malawi","pt":"Malávi","nl":"Malawi","hr":"Malavi","fa":"مالاوی"},"flag":"https://restcountries.eu/data/mwi.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"MAW"} +{"name":"Malaysia","topLevelDomain":[".my"],"alpha2Code":"MY","alpha3Code":"MYS","callingCodes":["60"],"capital":"Kuala Lumpur","altSpellings":["MY"],"region":"Asia","subregion":"South-Eastern Asia","population":31405416,"latlng":[2.5,112.5],"demonym":"Malaysian","area":330803.0,"gini":46.2,"timezones":["UTC+08:00"],"borders":["BRN","IDN","THA"],"nativeName":"Malaysia","numericCode":"458","currencies":[{"code":"MYR","name":"Malaysian ringgit","symbol":"RM"}],"languages":[{"iso639_1":null,"iso639_2":"zsm","name":"Malaysian","nativeName":"بهاس مليسيا"}],"translations":{"de":"Malaysia","es":"Malasia","fr":"Malaisie","ja":"マレーシア","it":"Malesia","br":"Malásia","pt":"Malásia","nl":"Maleisië","hr":"Malezija","fa":"مالزی"},"flag":"https://restcountries.eu/data/mys.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"MAS"} +{"name":"Maldives","topLevelDomain":[".mv"],"alpha2Code":"MV","alpha3Code":"MDV","callingCodes":["960"],"capital":"Malé","altSpellings":["MV","Maldive Islands","Republic of the Maldives","Dhivehi Raajjeyge Jumhooriyya"],"region":"Asia","subregion":"Southern Asia","population":344023,"latlng":[3.25,73.0],"demonym":"Maldivan","area":300.0,"gini":37.4,"timezones":["UTC+05:00"],"borders":[],"nativeName":"Maldives","numericCode":"462","currencies":[{"code":"MVR","name":"Maldivian rufiyaa","symbol":".ރ"}],"languages":[{"iso639_1":"dv","iso639_2":"div","name":"Divehi","nativeName":"ދިވެހި"}],"translations":{"de":"Malediven","es":"Maldivas","fr":"Maldives","ja":"モルディブ","it":"Maldive","br":"Maldivas","pt":"Maldivas","nl":"Maldiven","hr":"Maldivi","fa":"مالدیو"},"flag":"https://restcountries.eu/data/mdv.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"MDV"} +{"name":"Mali","topLevelDomain":[".ml"],"alpha2Code":"ML","alpha3Code":"MLI","callingCodes":["223"],"capital":"Bamako","altSpellings":["ML","Republic of Mali","République du Mali"],"region":"Africa","subregion":"Western Africa","population":18135000,"latlng":[17.0,-4.0],"demonym":"Malian","area":1240192.0,"gini":33.0,"timezones":["UTC"],"borders":["DZA","BFA","GIN","CIV","MRT","NER","SEN"],"nativeName":"Mali","numericCode":"466","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Mali","es":"Mali","fr":"Mali","ja":"マリ","it":"Mali","br":"Mali","pt":"Mali","nl":"Mali","hr":"Mali","fa":"مالی"},"flag":"https://restcountries.eu/data/mli.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"MLI"} +{"name":"Malta","topLevelDomain":[".mt"],"alpha2Code":"MT","alpha3Code":"MLT","callingCodes":["356"],"capital":"Valletta","altSpellings":["MT","Republic of Malta","Repubblika ta' Malta"],"region":"Europe","subregion":"Southern Europe","population":425384,"latlng":[35.83333333,14.58333333],"demonym":"Maltese","area":316.0,"gini":null,"timezones":["UTC+01:00"],"borders":[],"nativeName":"Malta","numericCode":"470","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"mt","iso639_2":"mlt","name":"Maltese","nativeName":"Malti"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Malta","es":"Malta","fr":"Malte","ja":"マルタ","it":"Malta","br":"Malta","pt":"Malta","nl":"Malta","hr":"Malta","fa":"مالت"},"flag":"https://restcountries.eu/data/mlt.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"MLT"} +{"name":"Marshall Islands","topLevelDomain":[".mh"],"alpha2Code":"MH","alpha3Code":"MHL","callingCodes":["692"],"capital":"Majuro","altSpellings":["MH","Republic of the Marshall Islands","Aolepān Aorōkin M̧ajeļ"],"region":"Oceania","subregion":"Micronesia","population":54880,"latlng":[9.0,168.0],"demonym":"Marshallese","area":181.0,"gini":null,"timezones":["UTC+12:00"],"borders":[],"nativeName":"M̧ajeļ","numericCode":"584","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"mh","iso639_2":"mah","name":"Marshallese","nativeName":"Kajin M̧ajeļ"}],"translations":{"de":"Marshallinseln","es":"Islas Marshall","fr":"Îles Marshall","ja":"マーシャル諸島","it":"Isole Marshall","br":"Ilhas Marshall","pt":"Ilhas Marshall","nl":"Marshalleilanden","hr":"Maršalovi Otoci","fa":"جزایر مارشال"},"flag":"https://restcountries.eu/data/mhl.svg","regionalBlocs":[],"cioc":"MHL"} +{"name":"Martinique","topLevelDomain":[".mq"],"alpha2Code":"MQ","alpha3Code":"MTQ","callingCodes":["596"],"capital":"Fort-de-France","altSpellings":["MQ"],"region":"Americas","subregion":"Caribbean","population":378243,"latlng":[14.666667,-61.0],"demonym":"French","area":null,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Martinique","numericCode":"474","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Martinique","es":"Martinica","fr":"Martinique","ja":"マルティニーク","it":"Martinica","br":"Martinica","pt":"Martinica","nl":"Martinique","hr":"Martinique","fa":"مونتسرات"},"flag":"https://restcountries.eu/data/mtq.svg","regionalBlocs":[],"cioc":""} +{"name":"Mauritania","topLevelDomain":[".mr"],"alpha2Code":"MR","alpha3Code":"MRT","callingCodes":["222"],"capital":"Nouakchott","altSpellings":["MR","Islamic Republic of Mauritania","al-Jumhūriyyah al-ʾIslāmiyyah al-Mūrītāniyyah"],"region":"Africa","subregion":"Western Africa","population":3718678,"latlng":[20.0,-12.0],"demonym":"Mauritanian","area":1030700.0,"gini":40.5,"timezones":["UTC"],"borders":["DZA","MLI","SEN","ESH"],"nativeName":"موريتانيا","numericCode":"478","currencies":[{"code":"MRO","name":"Mauritanian ouguiya","symbol":"UM"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Mauretanien","es":"Mauritania","fr":"Mauritanie","ja":"モーリタニア","it":"Mauritania","br":"Mauritânia","pt":"Mauritânia","nl":"Mauritanië","hr":"Mauritanija","fa":"موریتانی"},"flag":"https://restcountries.eu/data/mrt.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"MTN"} +{"name":"Mauritius","topLevelDomain":[".mu"],"alpha2Code":"MU","alpha3Code":"MUS","callingCodes":["230"],"capital":"Port Louis","altSpellings":["MU","Republic of Mauritius","République de Maurice"],"region":"Africa","subregion":"Eastern Africa","population":1262879,"latlng":[-20.28333333,57.55],"demonym":"Mauritian","area":2040.0,"gini":null,"timezones":["UTC+04:00"],"borders":[],"nativeName":"Maurice","numericCode":"480","currencies":[{"code":"MUR","name":"Mauritian rupee","symbol":"₨"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Mauritius","es":"Mauricio","fr":"Île Maurice","ja":"モーリシャス","it":"Mauritius","br":"Maurício","pt":"Maurícia","nl":"Mauritius","hr":"Mauricijus","fa":"موریس"},"flag":"https://restcountries.eu/data/mus.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"MRI"} +{"name":"Mayotte","topLevelDomain":[".yt"],"alpha2Code":"YT","alpha3Code":"MYT","callingCodes":["262"],"capital":"Mamoudzou","altSpellings":["YT","Department of Mayotte","Département de Mayotte"],"region":"Africa","subregion":"Eastern Africa","population":226915,"latlng":[-12.83333333,45.16666666],"demonym":"French","area":null,"gini":null,"timezones":["UTC+03:00"],"borders":[],"nativeName":"Mayotte","numericCode":"175","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Mayotte","es":"Mayotte","fr":"Mayotte","ja":"マヨット","it":"Mayotte","br":"Mayotte","pt":"Mayotte","nl":"Mayotte","hr":"Mayotte","fa":"مایوت"},"flag":"https://restcountries.eu/data/myt.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":""} +{"name":"Mexico","topLevelDomain":[".mx"],"alpha2Code":"MX","alpha3Code":"MEX","callingCodes":["52"],"capital":"Mexico City","altSpellings":["MX","Mexicanos","United Mexican States","Estados Unidos Mexicanos"],"region":"Americas","subregion":"Central America","population":122273473,"latlng":[23.0,-102.0],"demonym":"Mexican","area":1964375.0,"gini":47.0,"timezones":["UTC-08:00","UTC-07:00","UTC-06:00"],"borders":["BLZ","GTM","USA"],"nativeName":"México","numericCode":"484","currencies":[{"code":"MXN","name":"Mexican peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Mexiko","es":"México","fr":"Mexique","ja":"メキシコ","it":"Messico","br":"México","pt":"México","nl":"Mexico","hr":"Meksiko","fa":"مکزیک"},"flag":"https://restcountries.eu/data/mex.svg","regionalBlocs":[{"acronym":"PA","name":"Pacific Alliance","otherAcronyms":[],"otherNames":["Alianza del Pacífico"]},{"acronym":"NAFTA","name":"North American Free Trade Agreement","otherAcronyms":[],"otherNames":["Tratado de Libre Comercio de América del Norte","Accord de Libre-échange Nord-Américain"]}],"cioc":"MEX"} +{"name":"Micronesia (Federated States of)","topLevelDomain":[".fm"],"alpha2Code":"FM","alpha3Code":"FSM","callingCodes":["691"],"capital":"Palikir","altSpellings":["FM","Federated States of Micronesia"],"region":"Oceania","subregion":"Micronesia","population":102800,"latlng":[6.91666666,158.25],"demonym":"Micronesian","area":702.0,"gini":null,"timezones":["UTC+10:00","UTC+11"],"borders":[],"nativeName":"Micronesia","numericCode":"583","currencies":[{"code":null,"name":"[D]","symbol":"$"},{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Mikronesien","es":"Micronesia","fr":"Micronésie","ja":"ミクロネシア連邦","it":"Micronesia","br":"Micronésia","pt":"Micronésia","nl":"Micronesië","hr":"Mikronezija","fa":"ایالات فدرال میکرونزی"},"flag":"https://restcountries.eu/data/fsm.svg","regionalBlocs":[],"cioc":"FSM"} +{"name":"Moldova (Republic of)","topLevelDomain":[".md"],"alpha2Code":"MD","alpha3Code":"MDA","callingCodes":["373"],"capital":"Chișinău","altSpellings":["MD","Republic of Moldova","Republica Moldova"],"region":"Europe","subregion":"Eastern Europe","population":3553100,"latlng":[47.0,29.0],"demonym":"Moldovan","area":33846.0,"gini":33.0,"timezones":["UTC+02:00"],"borders":["ROU","UKR"],"nativeName":"Moldova","numericCode":"498","currencies":[{"code":"MDL","name":"Moldovan leu","symbol":"L"}],"languages":[{"iso639_1":"ro","iso639_2":"ron","name":"Romanian","nativeName":"Română"}],"translations":{"de":"Moldawie","es":"Moldavia","fr":"Moldavie","ja":"モルドバ共和国","it":"Moldavia","br":"Moldávia","pt":"Moldávia","nl":"Moldavië","hr":"Moldova","fa":"مولداوی"},"flag":"https://restcountries.eu/data/mda.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":"MDA"} +{"name":"Monaco","topLevelDomain":[".mc"],"alpha2Code":"MC","alpha3Code":"MCO","callingCodes":["377"],"capital":"Monaco","altSpellings":["MC","Principality of Monaco","Principauté de Monaco"],"region":"Europe","subregion":"Western Europe","population":38400,"latlng":[43.73333333,7.4],"demonym":"Monegasque","area":2.02,"gini":null,"timezones":["UTC+01:00"],"borders":["FRA"],"nativeName":"Monaco","numericCode":"492","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Monaco","es":"Mónaco","fr":"Monaco","ja":"モナコ","it":"Principato di Monaco","br":"Mônaco","pt":"Mónaco","nl":"Monaco","hr":"Monako","fa":"موناکو"},"flag":"https://restcountries.eu/data/mco.svg","regionalBlocs":[],"cioc":"MON"} +{"name":"Mongolia","topLevelDomain":[".mn"],"alpha2Code":"MN","alpha3Code":"MNG","callingCodes":["976"],"capital":"Ulan Bator","altSpellings":["MN"],"region":"Asia","subregion":"Eastern Asia","population":3093100,"latlng":[46.0,105.0],"demonym":"Mongolian","area":1564110.0,"gini":36.5,"timezones":["UTC+07:00","UTC+08:00"],"borders":["CHN","RUS"],"nativeName":"Монгол улс","numericCode":"496","currencies":[{"code":"MNT","name":"Mongolian tögrög","symbol":"₮"}],"languages":[{"iso639_1":"mn","iso639_2":"mon","name":"Mongolian","nativeName":"Монгол хэл"}],"translations":{"de":"Mongolei","es":"Mongolia","fr":"Mongolie","ja":"モンゴル","it":"Mongolia","br":"Mongólia","pt":"Mongólia","nl":"Mongolië","hr":"Mongolija","fa":"مغولستان"},"flag":"https://restcountries.eu/data/mng.svg","regionalBlocs":[],"cioc":"MGL"} +{"name":"Montenegro","topLevelDomain":[".me"],"alpha2Code":"ME","alpha3Code":"MNE","callingCodes":["382"],"capital":"Podgorica","altSpellings":["ME","Crna Gora"],"region":"Europe","subregion":"Southern Europe","population":621810,"latlng":[42.5,19.3],"demonym":"Montenegrin","area":13812.0,"gini":30.0,"timezones":["UTC+01:00"],"borders":["ALB","BIH","HRV","KOS","SRB"],"nativeName":"Црна Гора","numericCode":"499","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"sr","iso639_2":"srp","name":"Serbian","nativeName":"српски језик"},{"iso639_1":"bs","iso639_2":"bos","name":"Bosnian","nativeName":"bosanski jezik"},{"iso639_1":"sq","iso639_2":"sqi","name":"Albanian","nativeName":"Shqip"},{"iso639_1":"hr","iso639_2":"hrv","name":"Croatian","nativeName":"hrvatski jezik"}],"translations":{"de":"Montenegro","es":"Montenegro","fr":"Monténégro","ja":"モンテネグロ","it":"Montenegro","br":"Montenegro","pt":"Montenegro","nl":"Montenegro","hr":"Crna Gora","fa":"مونته‌نگرو"},"flag":"https://restcountries.eu/data/mne.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":"MNE"} +{"name":"Montserrat","topLevelDomain":[".ms"],"alpha2Code":"MS","alpha3Code":"MSR","callingCodes":["1664"],"capital":"Plymouth","altSpellings":["MS"],"region":"Americas","subregion":"Caribbean","population":4922,"latlng":[16.75,-62.2],"demonym":"Montserratian","area":102.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Montserrat","numericCode":"500","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Montserrat","es":"Montserrat","fr":"Montserrat","ja":"モントセラト","it":"Montserrat","br":"Montserrat","pt":"Monserrate","nl":"Montserrat","hr":"Montserrat","fa":"مایوت"},"flag":"https://restcountries.eu/data/msr.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":""} +{"name":"Morocco","topLevelDomain":[".ma"],"alpha2Code":"MA","alpha3Code":"MAR","callingCodes":["212"],"capital":"Rabat","altSpellings":["MA","Kingdom of Morocco","Al-Mamlakah al-Maġribiyah"],"region":"Africa","subregion":"Northern Africa","population":33337529,"latlng":[32.0,-5.0],"demonym":"Moroccan","area":446550.0,"gini":40.9,"timezones":["UTC"],"borders":["DZA","ESH","ESP"],"nativeName":"المغرب","numericCode":"504","currencies":[{"code":"MAD","name":"Moroccan dirham","symbol":"د.م."}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Marokko","es":"Marruecos","fr":"Maroc","ja":"モロッコ","it":"Marocco","br":"Marrocos","pt":"Marrocos","nl":"Marokko","hr":"Maroko","fa":"مراکش"},"flag":"https://restcountries.eu/data/mar.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"MAR"} +{"name":"Mozambique","topLevelDomain":[".mz"],"alpha2Code":"MZ","alpha3Code":"MOZ","callingCodes":["258"],"capital":"Maputo","altSpellings":["MZ","Republic of Mozambique","República de Moçambique"],"region":"Africa","subregion":"Eastern Africa","population":26423700,"latlng":[-18.25,35.0],"demonym":"Mozambican","area":801590.0,"gini":45.7,"timezones":["UTC+02:00"],"borders":["MWI","ZAF","SWZ","TZA","ZMB","ZWE"],"nativeName":"Moçambique","numericCode":"508","currencies":[{"code":"MZN","name":"Mozambican metical","symbol":"MT"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Mosambik","es":"Mozambique","fr":"Mozambique","ja":"モザンビーク","it":"Mozambico","br":"Moçambique","pt":"Moçambique","nl":"Mozambique","hr":"Mozambik","fa":"موزامبیک"},"flag":"https://restcountries.eu/data/moz.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"MOZ"} +{"name":"Myanmar","topLevelDomain":[".mm"],"alpha2Code":"MM","alpha3Code":"MMR","callingCodes":["95"],"capital":"Naypyidaw","altSpellings":["MM","Burma","Republic of the Union of Myanmar","Pyidaunzu Thanmăda Myăma Nainngandaw"],"region":"Asia","subregion":"South-Eastern Asia","population":51419420,"latlng":[22.0,98.0],"demonym":"Burmese","area":676578.0,"gini":null,"timezones":["UTC+06:30"],"borders":["BGD","CHN","IND","LAO","THA"],"nativeName":"Myanma","numericCode":"104","currencies":[{"code":"MMK","name":"Burmese kyat","symbol":"Ks"}],"languages":[{"iso639_1":"my","iso639_2":"mya","name":"Burmese","nativeName":"ဗမာစာ"}],"translations":{"de":"Myanmar","es":"Myanmar","fr":"Myanmar","ja":"ミャンマー","it":"Birmania","br":"Myanmar","pt":"Myanmar","nl":"Myanmar","hr":"Mijanmar","fa":"میانمار"},"flag":"https://restcountries.eu/data/mmr.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"MYA"} +{"name":"Namibia","topLevelDomain":[".na"],"alpha2Code":"NA","alpha3Code":"NAM","callingCodes":["264"],"capital":"Windhoek","altSpellings":["NA","Namibië","Republic of Namibia"],"region":"Africa","subregion":"Southern Africa","population":2324388,"latlng":[-22.0,17.0],"demonym":"Namibian","area":825615.0,"gini":63.9,"timezones":["UTC+01:00"],"borders":["AGO","BWA","ZAF","ZMB"],"nativeName":"Namibia","numericCode":"516","currencies":[{"code":"NAD","name":"Namibian dollar","symbol":"$"},{"code":"ZAR","name":"South African rand","symbol":"R"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"af","iso639_2":"afr","name":"Afrikaans","nativeName":"Afrikaans"}],"translations":{"de":"Namibia","es":"Namibia","fr":"Namibie","ja":"ナミビア","it":"Namibia","br":"Namíbia","pt":"Namíbia","nl":"Namibië","hr":"Namibija","fa":"نامیبیا"},"flag":"https://restcountries.eu/data/nam.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"NAM"} +{"name":"Nauru","topLevelDomain":[".nr"],"alpha2Code":"NR","alpha3Code":"NRU","callingCodes":["674"],"capital":"Yaren","altSpellings":["NR","Naoero","Pleasant Island","Republic of Nauru","Ripublik Naoero"],"region":"Oceania","subregion":"Micronesia","population":10084,"latlng":[-0.53333333,166.91666666],"demonym":"Nauruan","area":21.0,"gini":null,"timezones":["UTC+12:00"],"borders":[],"nativeName":"Nauru","numericCode":"520","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"},{"code":"(none)","name":null,"symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"na","iso639_2":"nau","name":"Nauruan","nativeName":"Dorerin Naoero"}],"translations":{"de":"Nauru","es":"Nauru","fr":"Nauru","ja":"ナウル","it":"Nauru","br":"Nauru","pt":"Nauru","nl":"Nauru","hr":"Nauru","fa":"نائورو"},"flag":"https://restcountries.eu/data/nru.svg","regionalBlocs":[],"cioc":"NRU"} +{"name":"Nepal","topLevelDomain":[".np"],"alpha2Code":"NP","alpha3Code":"NPL","callingCodes":["977"],"capital":"Kathmandu","altSpellings":["NP","Federal Democratic Republic of Nepal","Loktāntrik Ganatantra Nepāl"],"region":"Asia","subregion":"Southern Asia","population":28431500,"latlng":[28.0,84.0],"demonym":"Nepalese","area":147181.0,"gini":32.8,"timezones":["UTC+05:45"],"borders":["CHN","IND"],"nativeName":"नेपाल","numericCode":"524","currencies":[{"code":"NPR","name":"Nepalese rupee","symbol":"₨"}],"languages":[{"iso639_1":"ne","iso639_2":"nep","name":"Nepali","nativeName":"नेपाली"}],"translations":{"de":"Népal","es":"Nepal","fr":"Népal","ja":"ネパール","it":"Nepal","br":"Nepal","pt":"Nepal","nl":"Nepal","hr":"Nepal","fa":"نپال"},"flag":"https://restcountries.eu/data/npl.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"NEP"} +{"name":"Netherlands","topLevelDomain":[".nl"],"alpha2Code":"NL","alpha3Code":"NLD","callingCodes":["31"],"capital":"Amsterdam","altSpellings":["NL","Holland","Nederland"],"region":"Europe","subregion":"Western Europe","population":17019800,"latlng":[52.5,5.75],"demonym":"Dutch","area":41850.0,"gini":30.9,"timezones":["UTC-04:00","UTC+01:00"],"borders":["BEL","DEU"],"nativeName":"Nederland","numericCode":"528","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"}],"translations":{"de":"Niederlande","es":"Países Bajos","fr":"Pays-Bas","ja":"オランダ","it":"Paesi Bassi","br":"Holanda","pt":"Países Baixos","nl":"Nederland","hr":"Nizozemska","fa":"پادشاهی هلند"},"flag":"https://restcountries.eu/data/nld.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"NED"} +{"name":"New Caledonia","topLevelDomain":[".nc"],"alpha2Code":"NC","alpha3Code":"NCL","callingCodes":["687"],"capital":"Nouméa","altSpellings":["NC"],"region":"Oceania","subregion":"Melanesia","population":268767,"latlng":[-21.5,165.5],"demonym":"New Caledonian","area":18575.0,"gini":null,"timezones":["UTC+11:00"],"borders":[],"nativeName":"Nouvelle-Calédonie","numericCode":"540","currencies":[{"code":"XPF","name":"CFP franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Neukaledonien","es":"Nueva Caledonia","fr":"Nouvelle-Calédonie","ja":"ニューカレドニア","it":"Nuova Caledonia","br":"Nova Caledônia","pt":"Nova Caledónia","nl":"Nieuw-Caledonië","hr":"Nova Kaledonija","fa":"کالدونیای جدید"},"flag":"https://restcountries.eu/data/ncl.svg","regionalBlocs":[],"cioc":""} +{"name":"New Zealand","topLevelDomain":[".nz"],"alpha2Code":"NZ","alpha3Code":"NZL","callingCodes":["64"],"capital":"Wellington","altSpellings":["NZ","Aotearoa"],"region":"Oceania","subregion":"Australia and New Zealand","population":4697854,"latlng":[-41.0,174.0],"demonym":"New Zealander","area":270467.0,"gini":36.2,"timezones":["UTC-11:00","UTC-10:00","UTC+12:00","UTC+12:45","UTC+13:00"],"borders":[],"nativeName":"New Zealand","numericCode":"554","currencies":[{"code":"NZD","name":"New Zealand dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"mi","iso639_2":"mri","name":"Māori","nativeName":"te reo Māori"}],"translations":{"de":"Neuseeland","es":"Nueva Zelanda","fr":"Nouvelle-Zélande","ja":"ニュージーランド","it":"Nuova Zelanda","br":"Nova Zelândia","pt":"Nova Zelândia","nl":"Nieuw-Zeeland","hr":"Novi Zeland","fa":"نیوزیلند"},"flag":"https://restcountries.eu/data/nzl.svg","regionalBlocs":[],"cioc":"NZL"} +{"name":"Nicaragua","topLevelDomain":[".ni"],"alpha2Code":"NI","alpha3Code":"NIC","callingCodes":["505"],"capital":"Managua","altSpellings":["NI","Republic of Nicaragua","República de Nicaragua"],"region":"Americas","subregion":"Central America","population":6262703,"latlng":[13.0,-85.0],"demonym":"Nicaraguan","area":130373.0,"gini":40.5,"timezones":["UTC-06:00"],"borders":["CRI","HND"],"nativeName":"Nicaragua","numericCode":"558","currencies":[{"code":"NIO","name":"Nicaraguan córdoba","symbol":"C$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Nicaragua","es":"Nicaragua","fr":"Nicaragua","ja":"ニカラグア","it":"Nicaragua","br":"Nicarágua","pt":"Nicarágua","nl":"Nicaragua","hr":"Nikaragva","fa":"نیکاراگوئه"},"flag":"https://restcountries.eu/data/nic.svg","regionalBlocs":[{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"NCA"} +{"name":"Niger","topLevelDomain":[".ne"],"alpha2Code":"NE","alpha3Code":"NER","callingCodes":["227"],"capital":"Niamey","altSpellings":["NE","Nijar","Republic of Niger","République du Niger"],"region":"Africa","subregion":"Western Africa","population":20715000,"latlng":[16.0,8.0],"demonym":"Nigerien","area":1267000.0,"gini":34.6,"timezones":["UTC+01:00"],"borders":["DZA","BEN","BFA","TCD","LBY","MLI","NGA"],"nativeName":"Niger","numericCode":"562","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Niger","es":"Níger","fr":"Niger","ja":"ニジェール","it":"Niger","br":"Níger","pt":"Níger","nl":"Niger","hr":"Niger","fa":"نیجر"},"flag":"https://restcountries.eu/data/ner.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"NIG"} +{"name":"Nigeria","topLevelDomain":[".ng"],"alpha2Code":"NG","alpha3Code":"NGA","callingCodes":["234"],"capital":"Abuja","altSpellings":["NG","Nijeriya","Naíjíríà","Federal Republic of Nigeria"],"region":"Africa","subregion":"Western Africa","population":186988000,"latlng":[10.0,8.0],"demonym":"Nigerian","area":923768.0,"gini":48.8,"timezones":["UTC+01:00"],"borders":["BEN","CMR","TCD","NER"],"nativeName":"Nigeria","numericCode":"566","currencies":[{"code":"NGN","name":"Nigerian naira","symbol":"₦"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Nigeria","es":"Nigeria","fr":"Nigéria","ja":"ナイジェリア","it":"Nigeria","br":"Nigéria","pt":"Nigéria","nl":"Nigeria","hr":"Nigerija","fa":"نیجریه"},"flag":"https://restcountries.eu/data/nga.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"NGR"} +{"name":"Niue","topLevelDomain":[".nu"],"alpha2Code":"NU","alpha3Code":"NIU","callingCodes":["683"],"capital":"Alofi","altSpellings":["NU"],"region":"Oceania","subregion":"Polynesia","population":1470,"latlng":[-19.03333333,-169.86666666],"demonym":"Niuean","area":260.0,"gini":null,"timezones":["UTC-11:00"],"borders":[],"nativeName":"Niuē","numericCode":"570","currencies":[{"code":"NZD","name":"New Zealand dollar","symbol":"$"},{"code":"(none)","name":"Niue dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Niue","es":"Niue","fr":"Niue","ja":"ニウエ","it":"Niue","br":"Niue","pt":"Niue","nl":"Niue","hr":"Niue","fa":"نیووی"},"flag":"https://restcountries.eu/data/niu.svg","regionalBlocs":[],"cioc":""} +{"name":"Norfolk Island","topLevelDomain":[".nf"],"alpha2Code":"NF","alpha3Code":"NFK","callingCodes":["672"],"capital":"Kingston","altSpellings":["NF","Territory of Norfolk Island","Teratri of Norf'k Ailen"],"region":"Oceania","subregion":"Australia and New Zealand","population":2302,"latlng":[-29.03333333,167.95],"demonym":"Norfolk Islander","area":36.0,"gini":null,"timezones":["UTC+11:30"],"borders":[],"nativeName":"Norfolk Island","numericCode":"574","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Norfolkinsel","es":"Isla de Norfolk","fr":"Île de Norfolk","ja":"ノーフォーク島","it":"Isola Norfolk","br":"Ilha Norfolk","pt":"Ilha Norfolk","nl":"Norfolkeiland","hr":"Otok Norfolk","fa":"جزیره نورفک"},"flag":"https://restcountries.eu/data/nfk.svg","regionalBlocs":[],"cioc":""} +{"name":"Korea (Democratic People's Republic of)","topLevelDomain":[".kp"],"alpha2Code":"KP","alpha3Code":"PRK","callingCodes":["850"],"capital":"Pyongyang","altSpellings":["KP","Democratic People's Republic of Korea","조선민주주의인민공화국","Chosŏn Minjujuŭi Inmin Konghwaguk"],"region":"Asia","subregion":"Eastern Asia","population":25281000,"latlng":[40.0,127.0],"demonym":"North Korean","area":120538.0,"gini":null,"timezones":["UTC+09:00"],"borders":["CHN","KOR","RUS"],"nativeName":"북한","numericCode":"408","currencies":[{"code":"KPW","name":"North Korean won","symbol":"₩"}],"languages":[{"iso639_1":"ko","iso639_2":"kor","name":"Korean","nativeName":"한국어"}],"translations":{"de":"Nordkorea","es":"Corea del Norte","fr":"Corée du Nord","ja":"朝鮮民主主義人民共和国","it":"Corea del Nord","br":"Coreia do Norte","pt":"Coreia do Norte","nl":"Noord-Korea","hr":"Sjeverna Koreja","fa":"کره جنوبی"},"flag":"https://restcountries.eu/data/prk.svg","regionalBlocs":[],"cioc":"PRK"} +{"name":"Northern Mariana Islands","topLevelDomain":[".mp"],"alpha2Code":"MP","alpha3Code":"MNP","callingCodes":["1670"],"capital":"Saipan","altSpellings":["MP","Commonwealth of the Northern Mariana Islands","Sankattan Siha Na Islas Mariånas"],"region":"Oceania","subregion":"Micronesia","population":56940,"latlng":[15.2,145.75],"demonym":"American","area":464.0,"gini":null,"timezones":["UTC+10:00"],"borders":[],"nativeName":"Northern Mariana Islands","numericCode":"580","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ch","iso639_2":"cha","name":"Chamorro","nativeName":"Chamoru"}],"translations":{"de":"Nördliche Marianen","es":"Islas Marianas del Norte","fr":"Îles Mariannes du Nord","ja":"北マリアナ諸島","it":"Isole Marianne Settentrionali","br":"Ilhas Marianas","pt":"Ilhas Marianas","nl":"Noordelijke Marianeneilanden","hr":"Sjevernomarijanski otoci","fa":"جزایر ماریانای شمالی"},"flag":"https://restcountries.eu/data/mnp.svg","regionalBlocs":[],"cioc":""} +{"name":"Norway","topLevelDomain":[".no"],"alpha2Code":"NO","alpha3Code":"NOR","callingCodes":["47"],"capital":"Oslo","altSpellings":["NO","Norge","Noreg","Kingdom of Norway","Kongeriket Norge","Kongeriket Noreg"],"region":"Europe","subregion":"Northern Europe","population":5223256,"latlng":[62.0,10.0],"demonym":"Norwegian","area":323802.0,"gini":25.8,"timezones":["UTC+01:00"],"borders":["FIN","SWE","RUS"],"nativeName":"Norge","numericCode":"578","currencies":[{"code":"NOK","name":"Norwegian krone","symbol":"kr"}],"languages":[{"iso639_1":"no","iso639_2":"nor","name":"Norwegian","nativeName":"Norsk"},{"iso639_1":"nb","iso639_2":"nob","name":"Norwegian Bokmål","nativeName":"Norsk bokmål"},{"iso639_1":"nn","iso639_2":"nno","name":"Norwegian Nynorsk","nativeName":"Norsk nynorsk"}],"translations":{"de":"Norwegen","es":"Noruega","fr":"Norvège","ja":"ノルウェー","it":"Norvegia","br":"Noruega","pt":"Noruega","nl":"Noorwegen","hr":"Norveška","fa":"نروژ"},"flag":"https://restcountries.eu/data/nor.svg","regionalBlocs":[{"acronym":"EFTA","name":"European Free Trade Association","otherAcronyms":[],"otherNames":[]}],"cioc":"NOR"} +{"name":"Oman","topLevelDomain":[".om"],"alpha2Code":"OM","alpha3Code":"OMN","callingCodes":["968"],"capital":"Muscat","altSpellings":["OM","Sultanate of Oman","Salṭanat ʻUmān"],"region":"Asia","subregion":"Western Asia","population":4420133,"latlng":[21.0,57.0],"demonym":"Omani","area":309500.0,"gini":null,"timezones":["UTC+04:00"],"borders":["SAU","ARE","YEM"],"nativeName":"عمان","numericCode":"512","currencies":[{"code":"OMR","name":"Omani rial","symbol":"ر.ع."}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Oman","es":"Omán","fr":"Oman","ja":"オマーン","it":"oman","br":"Omã","pt":"Omã","nl":"Oman","hr":"Oman","fa":"عمان"},"flag":"https://restcountries.eu/data/omn.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"OMA"} +{"name":"Pakistan","topLevelDomain":[".pk"],"alpha2Code":"PK","alpha3Code":"PAK","callingCodes":["92"],"capital":"Islamabad","altSpellings":["PK","Pākistān","Islamic Republic of Pakistan","Islāmī Jumhūriya'eh Pākistān"],"region":"Asia","subregion":"Southern Asia","population":194125062,"latlng":[30.0,70.0],"demonym":"Pakistani","area":881912.0,"gini":30.0,"timezones":["UTC+05:00"],"borders":["AFG","CHN","IND","IRN"],"nativeName":"Pakistan","numericCode":"586","currencies":[{"code":"PKR","name":"Pakistani rupee","symbol":"₨"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ur","iso639_2":"urd","name":"Urdu","nativeName":"اردو"}],"translations":{"de":"Pakistan","es":"Pakistán","fr":"Pakistan","ja":"パキスタン","it":"Pakistan","br":"Paquistão","pt":"Paquistão","nl":"Pakistan","hr":"Pakistan","fa":"پاکستان"},"flag":"https://restcountries.eu/data/pak.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"PAK"} +{"name":"Palau","topLevelDomain":[".pw"],"alpha2Code":"PW","alpha3Code":"PLW","callingCodes":["680"],"capital":"Ngerulmud","altSpellings":["PW","Republic of Palau","Beluu er a Belau"],"region":"Oceania","subregion":"Micronesia","population":17950,"latlng":[7.5,134.5],"demonym":"Palauan","area":459.0,"gini":null,"timezones":["UTC+09:00"],"borders":[],"nativeName":"Palau","numericCode":"585","currencies":[{"code":"(none)","name":"[E]","symbol":"$"},{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Palau","es":"Palau","fr":"Palaos","ja":"パラオ","it":"Palau","br":"Palau","pt":"Palau","nl":"Palau","hr":"Palau","fa":"پالائو"},"flag":"https://restcountries.eu/data/plw.svg","regionalBlocs":[],"cioc":"PLW"} +{"name":"Palestine, State of","topLevelDomain":[".ps"],"alpha2Code":"PS","alpha3Code":"PSE","callingCodes":["970"],"capital":"Ramallah","altSpellings":["PS","State of Palestine","Dawlat Filasṭin"],"region":"Asia","subregion":"Western Asia","population":4682467,"latlng":[31.9,35.2],"demonym":"Palestinian","area":null,"gini":35.5,"timezones":["UTC+02:00"],"borders":["ISR","EGY","JOR"],"nativeName":"فلسطين","numericCode":"275","currencies":[{"code":"ILS","name":"Israeli new sheqel","symbol":"₪"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Palästina","es":"Palestina","fr":"Palestine","ja":"パレスチナ","it":"Palestina","br":"Palestina","pt":"Palestina","nl":"Palestijnse gebieden","hr":"Palestina","fa":"فلسطین"},"flag":"https://restcountries.eu/data/pse.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"PLE"} +{"name":"Panama","topLevelDomain":[".pa"],"alpha2Code":"PA","alpha3Code":"PAN","callingCodes":["507"],"capital":"Panama City","altSpellings":["PA","Republic of Panama","República de Panamá"],"region":"Americas","subregion":"Central America","population":3814672,"latlng":[9.0,-80.0],"demonym":"Panamanian","area":75417.0,"gini":51.9,"timezones":["UTC-05:00"],"borders":["COL","CRI"],"nativeName":"Panamá","numericCode":"591","currencies":[{"code":"PAB","name":"Panamanian balboa","symbol":"B/."},{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Panama","es":"Panamá","fr":"Panama","ja":"パナマ","it":"Panama","br":"Panamá","pt":"Panamá","nl":"Panama","hr":"Panama","fa":"پاناما"},"flag":"https://restcountries.eu/data/pan.svg","regionalBlocs":[{"acronym":"CAIS","name":"Central American Integration System","otherAcronyms":["SICA"],"otherNames":["Sistema de la Integración Centroamericana,"]}],"cioc":"PAN"} +{"name":"Papua New Guinea","topLevelDomain":[".pg"],"alpha2Code":"PG","alpha3Code":"PNG","callingCodes":["675"],"capital":"Port Moresby","altSpellings":["PG","Independent State of Papua New Guinea","Independen Stet bilong Papua Niugini"],"region":"Oceania","subregion":"Melanesia","population":8083700,"latlng":[-6.0,147.0],"demonym":"Papua New Guinean","area":462840.0,"gini":50.9,"timezones":["UTC+10:00"],"borders":["IDN"],"nativeName":"Papua Niugini","numericCode":"598","currencies":[{"code":"PGK","name":"Papua New Guinean kina","symbol":"K"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Papua-Neuguinea","es":"Papúa Nueva Guinea","fr":"Papouasie-Nouvelle-Guinée","ja":"パプアニューギニア","it":"Papua Nuova Guinea","br":"Papua Nova Guiné","pt":"Papua Nova Guiné","nl":"Papoea-Nieuw-Guinea","hr":"Papua Nova Gvineja","fa":"پاپوآ گینه نو"},"flag":"https://restcountries.eu/data/png.svg","regionalBlocs":[],"cioc":"PNG"} +{"name":"Paraguay","topLevelDomain":[".py"],"alpha2Code":"PY","alpha3Code":"PRY","callingCodes":["595"],"capital":"Asunción","altSpellings":["PY","Republic of Paraguay","República del Paraguay","Tetã Paraguái"],"region":"Americas","subregion":"South America","population":6854536,"latlng":[-23.0,-58.0],"demonym":"Paraguayan","area":406752.0,"gini":52.4,"timezones":["UTC-04:00"],"borders":["ARG","BOL","BRA"],"nativeName":"Paraguay","numericCode":"600","currencies":[{"code":"PYG","name":"Paraguayan guaraní","symbol":"₲"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"},{"iso639_1":"gn","iso639_2":"grn","name":"Guaraní","nativeName":"Avañe'ẽ"}],"translations":{"de":"Paraguay","es":"Paraguay","fr":"Paraguay","ja":"パラグアイ","it":"Paraguay","br":"Paraguai","pt":"Paraguai","nl":"Paraguay","hr":"Paragvaj","fa":"پاراگوئه"},"flag":"https://restcountries.eu/data/pry.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"PAR"} +{"name":"Peru","topLevelDomain":[".pe"],"alpha2Code":"PE","alpha3Code":"PER","callingCodes":["51"],"capital":"Lima","altSpellings":["PE","Republic of Peru"," República del Perú"],"region":"Americas","subregion":"South America","population":31488700,"latlng":[-10.0,-76.0],"demonym":"Peruvian","area":1285216.0,"gini":48.1,"timezones":["UTC-05:00"],"borders":["BOL","BRA","CHL","COL","ECU"],"nativeName":"Perú","numericCode":"604","currencies":[{"code":"PEN","name":"Peruvian sol","symbol":"S/."}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Peru","es":"Perú","fr":"Pérou","ja":"ペルー","it":"Perù","br":"Peru","pt":"Peru","nl":"Peru","hr":"Peru","fa":"پرو"},"flag":"https://restcountries.eu/data/per.svg","regionalBlocs":[{"acronym":"PA","name":"Pacific Alliance","otherAcronyms":[],"otherNames":["Alianza del Pacífico"]},{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"PER"} +{"name":"Philippines","topLevelDomain":[".ph"],"alpha2Code":"PH","alpha3Code":"PHL","callingCodes":["63"],"capital":"Manila","altSpellings":["PH","Republic of the Philippines","Repúblika ng Pilipinas"],"region":"Asia","subregion":"South-Eastern Asia","population":103279800,"latlng":[13.0,122.0],"demonym":"Filipino","area":342353.0,"gini":43.0,"timezones":["UTC+08:00"],"borders":[],"nativeName":"Pilipinas","numericCode":"608","currencies":[{"code":"PHP","name":"Philippine peso","symbol":"₱"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Philippinen","es":"Filipinas","fr":"Philippines","ja":"フィリピン","it":"Filippine","br":"Filipinas","pt":"Filipinas","nl":"Filipijnen","hr":"Filipini","fa":"جزایر الندفیلیپین"},"flag":"https://restcountries.eu/data/phl.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"PHI"} +{"name":"Pitcairn","topLevelDomain":[".pn"],"alpha2Code":"PN","alpha3Code":"PCN","callingCodes":["64"],"capital":"Adamstown","altSpellings":["PN","Pitcairn Henderson Ducie and Oeno Islands"],"region":"Oceania","subregion":"Polynesia","population":56,"latlng":[-25.06666666,-130.1],"demonym":"Pitcairn Islander","area":47.0,"gini":null,"timezones":["UTC-08:00"],"borders":[],"nativeName":"Pitcairn Islands","numericCode":"612","currencies":[{"code":"NZD","name":"New Zealand dollar","symbol":"$"},{"code":null,"name":"Pitcairn Islands dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Pitcairn","es":"Islas Pitcairn","fr":"Îles Pitcairn","ja":"ピトケアン","it":"Isole Pitcairn","br":"Ilhas Pitcairn","pt":"Ilhas Picárnia","nl":"Pitcairneilanden","hr":"Pitcairnovo otočje","fa":"پیتکرن"},"flag":"https://restcountries.eu/data/pcn.svg","regionalBlocs":[],"cioc":""} +{"name":"Poland","topLevelDomain":[".pl"],"alpha2Code":"PL","alpha3Code":"POL","callingCodes":["48"],"capital":"Warsaw","altSpellings":["PL","Republic of Poland","Rzeczpospolita Polska"],"region":"Europe","subregion":"Eastern Europe","population":38437239,"latlng":[52.0,20.0],"demonym":"Polish","area":312679.0,"gini":34.1,"timezones":["UTC+01:00"],"borders":["BLR","CZE","DEU","LTU","RUS","SVK","UKR"],"nativeName":"Polska","numericCode":"616","currencies":[{"code":"PLN","name":"Polish złoty","symbol":"zł"}],"languages":[{"iso639_1":"pl","iso639_2":"pol","name":"Polish","nativeName":"język polski"}],"translations":{"de":"Polen","es":"Polonia","fr":"Pologne","ja":"ポーランド","it":"Polonia","br":"Polônia","pt":"Polónia","nl":"Polen","hr":"Poljska","fa":"لهستان"},"flag":"https://restcountries.eu/data/pol.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"POL"} +{"name":"Portugal","topLevelDomain":[".pt"],"alpha2Code":"PT","alpha3Code":"PRT","callingCodes":["351"],"capital":"Lisbon","altSpellings":["PT","Portuguesa","Portuguese Republic","República Portuguesa"],"region":"Europe","subregion":"Southern Europe","population":10374822,"latlng":[39.5,-8.0],"demonym":"Portuguese","area":92090.0,"gini":38.5,"timezones":["UTC-01:00","UTC"],"borders":["ESP"],"nativeName":"Portugal","numericCode":"620","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Portugal","es":"Portugal","fr":"Portugal","ja":"ポルトガル","it":"Portogallo","br":"Portugal","pt":"Portugal","nl":"Portugal","hr":"Portugal","fa":"پرتغال"},"flag":"https://restcountries.eu/data/prt.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"POR"} +{"name":"Puerto Rico","topLevelDomain":[".pr"],"alpha2Code":"PR","alpha3Code":"PRI","callingCodes":["1787","1939"],"capital":"San Juan","altSpellings":["PR","Commonwealth of Puerto Rico","Estado Libre Asociado de Puerto Rico"],"region":"Americas","subregion":"Caribbean","population":3474182,"latlng":[18.25,-66.5],"demonym":"Puerto Rican","area":8870.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Puerto Rico","numericCode":"630","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Puerto Rico","es":"Puerto Rico","fr":"Porto Rico","ja":"プエルトリコ","it":"Porto Rico","br":"Porto Rico","pt":"Porto Rico","nl":"Puerto Rico","hr":"Portoriko","fa":"پورتو ریکو"},"flag":"https://restcountries.eu/data/pri.svg","regionalBlocs":[],"cioc":"PUR"} +{"name":"Qatar","topLevelDomain":[".qa"],"alpha2Code":"QA","alpha3Code":"QAT","callingCodes":["974"],"capital":"Doha","altSpellings":["QA","State of Qatar","Dawlat Qaṭar"],"region":"Asia","subregion":"Western Asia","population":2587564,"latlng":[25.5,51.25],"demonym":"Qatari","area":11586.0,"gini":41.1,"timezones":["UTC+03:00"],"borders":["SAU"],"nativeName":"قطر","numericCode":"634","currencies":[{"code":"QAR","name":"Qatari riyal","symbol":"ر.ق"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Katar","es":"Catar","fr":"Qatar","ja":"カタール","it":"Qatar","br":"Catar","pt":"Catar","nl":"Qatar","hr":"Katar","fa":"قطر"},"flag":"https://restcountries.eu/data/qat.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"QAT"} +{"name":"Republic of Kosovo","topLevelDomain":[""],"alpha2Code":"XK","alpha3Code":"KOS","callingCodes":["383"],"capital":"Pristina","altSpellings":["XK","Република Косово"],"region":"Europe","subregion":"Eastern Europe","population":1733842,"latlng":[42.666667,21.166667],"demonym":"Kosovar","area":10908.0,"gini":null,"timezones":["UTC+01:00"],"borders":["ALB","MKD","MNE","SRB"],"nativeName":"Republika e Kosovës","numericCode":null,"currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"sq","iso639_2":"sqi","name":"Albanian","nativeName":"Shqip"},{"iso639_1":"sr","iso639_2":"srp","name":"Serbian","nativeName":"српски језик"}],"translations":{"de":null,"es":"Kosovo","fr":null,"ja":null,"it":null,"br":"Kosovo","pt":"Kosovo","nl":null,"hr":"Kosovo","fa":"کوزوو"},"flag":"https://restcountries.eu/data/kos.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":null} +{"name":"Réunion","topLevelDomain":[".re"],"alpha2Code":"RE","alpha3Code":"REU","callingCodes":["262"],"capital":"Saint-Denis","altSpellings":["RE","Reunion"],"region":"Africa","subregion":"Eastern Africa","population":840974,"latlng":[-21.15,55.5],"demonym":"French","area":null,"gini":null,"timezones":["UTC+04:00"],"borders":[],"nativeName":"La Réunion","numericCode":"638","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Réunion","es":"Reunión","fr":"Réunion","ja":"レユニオン","it":"Riunione","br":"Reunião","pt":"Reunião","nl":"Réunion","hr":"Réunion","fa":"رئونیون"},"flag":"https://restcountries.eu/data/reu.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":""} +{"name":"Romania","topLevelDomain":[".ro"],"alpha2Code":"RO","alpha3Code":"ROU","callingCodes":["40"],"capital":"Bucharest","altSpellings":["RO","Rumania","Roumania","România"],"region":"Europe","subregion":"Eastern Europe","population":19861408,"latlng":[46.0,25.0],"demonym":"Romanian","area":238391.0,"gini":30.0,"timezones":["UTC+02:00"],"borders":["BGR","HUN","MDA","SRB","UKR"],"nativeName":"România","numericCode":"642","currencies":[{"code":"RON","name":"Romanian leu","symbol":"lei"}],"languages":[{"iso639_1":"ro","iso639_2":"ron","name":"Romanian","nativeName":"Română"}],"translations":{"de":"Rumänien","es":"Rumania","fr":"Roumanie","ja":"ルーマニア","it":"Romania","br":"Romênia","pt":"Roménia","nl":"Roemenië","hr":"Rumunjska","fa":"رومانی"},"flag":"https://restcountries.eu/data/rou.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"ROU"} +{"name":"Russian Federation","topLevelDomain":[".ru"],"alpha2Code":"RU","alpha3Code":"RUS","callingCodes":["7"],"capital":"Moscow","altSpellings":["RU","Rossiya","Russian Federation","Российская Федерация","Rossiyskaya Federatsiya"],"region":"Europe","subregion":"Eastern Europe","population":146599183,"latlng":[60.0,100.0],"demonym":"Russian","area":1.7124442E7,"gini":40.1,"timezones":["UTC+03:00","UTC+04:00","UTC+06:00","UTC+07:00","UTC+08:00","UTC+09:00","UTC+10:00","UTC+11:00","UTC+12:00"],"borders":["AZE","BLR","CHN","EST","FIN","GEO","KAZ","PRK","LVA","LTU","MNG","NOR","POL","UKR"],"nativeName":"Россия","numericCode":"643","currencies":[{"code":"RUB","name":"Russian ruble","symbol":"₽"}],"languages":[{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Russland","es":"Rusia","fr":"Russie","ja":"ロシア連邦","it":"Russia","br":"Rússia","pt":"Rússia","nl":"Rusland","hr":"Rusija","fa":"روسیه"},"flag":"https://restcountries.eu/data/rus.svg","regionalBlocs":[{"acronym":"EEU","name":"Eurasian Economic Union","otherAcronyms":["EAEU"],"otherNames":[]}],"cioc":"RUS"} +{"name":"Rwanda","topLevelDomain":[".rw"],"alpha2Code":"RW","alpha3Code":"RWA","callingCodes":["250"],"capital":"Kigali","altSpellings":["RW","Republic of Rwanda","Repubulika y'u Rwanda","République du Rwanda"],"region":"Africa","subregion":"Eastern Africa","population":11553188,"latlng":[-2.0,30.0],"demonym":"Rwandan","area":26338.0,"gini":50.8,"timezones":["UTC+02:00"],"borders":["BDI","COD","TZA","UGA"],"nativeName":"Rwanda","numericCode":"646","currencies":[{"code":"RWF","name":"Rwandan franc","symbol":"Fr"}],"languages":[{"iso639_1":"rw","iso639_2":"kin","name":"Kinyarwanda","nativeName":"Ikinyarwanda"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Ruanda","es":"Ruanda","fr":"Rwanda","ja":"ルワンダ","it":"Ruanda","br":"Ruanda","pt":"Ruanda","nl":"Rwanda","hr":"Ruanda","fa":"رواندا"},"flag":"https://restcountries.eu/data/rwa.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"RWA"} +{"name":"Saint Barthélemy","topLevelDomain":[".bl"],"alpha2Code":"BL","alpha3Code":"BLM","callingCodes":["590"],"capital":"Gustavia","altSpellings":["BL","St. Barthelemy","Collectivity of Saint Barthélemy","Collectivité de Saint-Barthélemy"],"region":"Americas","subregion":"Caribbean","population":9417,"latlng":[18.5,-63.41666666],"demonym":"Saint Barthélemy Islander","area":21.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Saint-Barthélemy","numericCode":"652","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Saint-Barthélemy","es":"San Bartolomé","fr":"Saint-Barthélemy","ja":"サン・バルテルミー","it":"Antille Francesi","br":"São Bartolomeu","pt":"São Bartolomeu","nl":"Saint Barthélemy","hr":"Saint Barthélemy","fa":"سن-بارتلمی"},"flag":"https://restcountries.eu/data/blm.svg","regionalBlocs":[],"cioc":""} +{"name":"Saint Helena, Ascension and Tristan da Cunha","topLevelDomain":[".sh"],"alpha2Code":"SH","alpha3Code":"SHN","callingCodes":["290"],"capital":"Jamestown","altSpellings":["SH"],"region":"Africa","subregion":"Western Africa","population":4255,"latlng":[-15.95,-5.7],"demonym":"Saint Helenian","area":null,"gini":null,"timezones":["UTC+00:00"],"borders":[],"nativeName":"Saint Helena","numericCode":"654","currencies":[{"code":"SHP","name":"Saint Helena pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Sankt Helena","es":"Santa Helena","fr":"Sainte-Hélène","ja":"セントヘレナ・アセンションおよびトリスタンダクーニャ","it":"Sant'Elena","br":"Santa Helena","pt":"Santa Helena","nl":"Sint-Helena","hr":"Sveta Helena","fa":"سنت هلنا، اسنشن و تریستان دا کونا"},"flag":"https://restcountries.eu/data/shn.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":null} +{"name":"Saint Kitts and Nevis","topLevelDomain":[".kn"],"alpha2Code":"KN","alpha3Code":"KNA","callingCodes":["1869"],"capital":"Basseterre","altSpellings":["KN","Federation of Saint Christopher and Nevis"],"region":"Americas","subregion":"Caribbean","population":46204,"latlng":[17.33333333,-62.75],"demonym":"Kittian and Nevisian","area":261.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Saint Kitts and Nevis","numericCode":"659","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"St. Kitts und Nevis","es":"San Cristóbal y Nieves","fr":"Saint-Christophe-et-Niévès","ja":"セントクリストファー・ネイビス","it":"Saint Kitts e Nevis","br":"São Cristóvão e Neves","pt":"São Cristóvão e Neves","nl":"Saint Kitts en Nevis","hr":"Sveti Kristof i Nevis","fa":"سنت کیتس و نویس"},"flag":"https://restcountries.eu/data/kna.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"SKN"} +{"name":"Saint Lucia","topLevelDomain":[".lc"],"alpha2Code":"LC","alpha3Code":"LCA","callingCodes":["1758"],"capital":"Castries","altSpellings":["LC"],"region":"Americas","subregion":"Caribbean","population":186000,"latlng":[13.88333333,-60.96666666],"demonym":"Saint Lucian","area":616.0,"gini":42.6,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Saint Lucia","numericCode":"662","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Saint Lucia","es":"Santa Lucía","fr":"Saint-Lucie","ja":"セントルシア","it":"Santa Lucia","br":"Santa Lúcia","pt":"Santa Lúcia","nl":"Saint Lucia","hr":"Sveta Lucija","fa":"سنت لوسیا"},"flag":"https://restcountries.eu/data/lca.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"LCA"} +{"name":"Saint Martin (French part)","topLevelDomain":[".mf",".fr",".gp"],"alpha2Code":"MF","alpha3Code":"MAF","callingCodes":["590"],"capital":"Marigot","altSpellings":["MF","Collectivity of Saint Martin","Collectivité de Saint-Martin"],"region":"Americas","subregion":"Caribbean","population":36979,"latlng":[18.08333333,-63.95],"demonym":"Saint Martin Islander","area":53.0,"gini":null,"timezones":["UTC-04:00"],"borders":["SXM","NLD"],"nativeName":"Saint-Martin","numericCode":"663","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"}],"translations":{"de":"Saint Martin","es":"Saint Martin","fr":"Saint-Martin","ja":"サン・マルタン(フランス領)","it":"Saint Martin","br":"Saint Martin","pt":"Ilha São Martinho","nl":"Saint-Martin","hr":"Sveti Martin","fa":"سینت مارتن"},"flag":"https://restcountries.eu/data/maf.svg","regionalBlocs":[],"cioc":""} +{"name":"Saint Pierre and Miquelon","topLevelDomain":[".pm"],"alpha2Code":"PM","alpha3Code":"SPM","callingCodes":["508"],"capital":"Saint-Pierre","altSpellings":["PM","Collectivité territoriale de Saint-Pierre-et-Miquelon"],"region":"Americas","subregion":"Northern America","population":6069,"latlng":[46.83333333,-56.33333333],"demonym":"French","area":242.0,"gini":null,"timezones":["UTC-03:00"],"borders":[],"nativeName":"Saint-Pierre-et-Miquelon","numericCode":"666","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Saint-Pierre und Miquelon","es":"San Pedro y Miquelón","fr":"Saint-Pierre-et-Miquelon","ja":"サンピエール島・ミクロン島","it":"Saint-Pierre e Miquelon","br":"Saint-Pierre e Miquelon","pt":"São Pedro e Miquelon","nl":"Saint Pierre en Miquelon","hr":"Sveti Petar i Mikelon","fa":"سن پیر و میکلن"},"flag":"https://restcountries.eu/data/spm.svg","regionalBlocs":[],"cioc":""} +{"name":"Saint Vincent and the Grenadines","topLevelDomain":[".vc"],"alpha2Code":"VC","alpha3Code":"VCT","callingCodes":["1784"],"capital":"Kingstown","altSpellings":["VC"],"region":"Americas","subregion":"Caribbean","population":109991,"latlng":[13.25,-61.2],"demonym":"Saint Vincentian","area":389.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Saint Vincent and the Grenadines","numericCode":"670","currencies":[{"code":"XCD","name":"East Caribbean dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Saint Vincent und die Grenadinen","es":"San Vicente y Granadinas","fr":"Saint-Vincent-et-les-Grenadines","ja":"セントビンセントおよびグレナディーン諸島","it":"Saint Vincent e Grenadine","br":"São Vicente e Granadinas","pt":"São Vicente e Granadinas","nl":"Saint Vincent en de Grenadines","hr":"Sveti Vincent i Grenadini","fa":"سنت وینسنت و گرنادین‌ها"},"flag":"https://restcountries.eu/data/vct.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"VIN"} +{"name":"Samoa","topLevelDomain":[".ws"],"alpha2Code":"WS","alpha3Code":"WSM","callingCodes":["685"],"capital":"Apia","altSpellings":["WS","Independent State of Samoa","Malo Saʻoloto Tutoʻatasi o Sāmoa"],"region":"Oceania","subregion":"Polynesia","population":194899,"latlng":[-13.58333333,-172.33333333],"demonym":"Samoan","area":2842.0,"gini":null,"timezones":["UTC+13:00"],"borders":[],"nativeName":"Samoa","numericCode":"882","currencies":[{"code":"WST","name":"Samoan tālā","symbol":"T"}],"languages":[{"iso639_1":"sm","iso639_2":"smo","name":"Samoan","nativeName":"gagana fa'a Samoa"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Samoa","es":"Samoa","fr":"Samoa","ja":"サモア","it":"Samoa","br":"Samoa","pt":"Samoa","nl":"Samoa","hr":"Samoa","fa":"ساموآ"},"flag":"https://restcountries.eu/data/wsm.svg","regionalBlocs":[],"cioc":"SAM"} +{"name":"San Marino","topLevelDomain":[".sm"],"alpha2Code":"SM","alpha3Code":"SMR","callingCodes":["378"],"capital":"City of San Marino","altSpellings":["SM","Republic of San Marino","Repubblica di San Marino"],"region":"Europe","subregion":"Southern Europe","population":33005,"latlng":[43.76666666,12.41666666],"demonym":"Sammarinese","area":61.0,"gini":null,"timezones":["UTC+01:00"],"borders":["ITA"],"nativeName":"San Marino","numericCode":"674","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"it","iso639_2":"ita","name":"Italian","nativeName":"Italiano"}],"translations":{"de":"San Marino","es":"San Marino","fr":"Saint-Marin","ja":"サンマリノ","it":"San Marino","br":"San Marino","pt":"São Marinho","nl":"San Marino","hr":"San Marino","fa":"سان مارینو"},"flag":"https://restcountries.eu/data/smr.svg","regionalBlocs":[],"cioc":"SMR"} +{"name":"Sao Tome and Principe","topLevelDomain":[".st"],"alpha2Code":"ST","alpha3Code":"STP","callingCodes":["239"],"capital":"São Tomé","altSpellings":["ST","Democratic Republic of São Tomé and Príncipe","República Democrática de São Tomé e Príncipe"],"region":"Africa","subregion":"Middle Africa","population":187356,"latlng":[1.0,7.0],"demonym":"Sao Tomean","area":964.0,"gini":50.8,"timezones":["UTC"],"borders":[],"nativeName":"São Tomé e Príncipe","numericCode":"678","currencies":[{"code":"STD","name":"São Tomé and Príncipe dobra","symbol":"Db"}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"São Tomé und Príncipe","es":"Santo Tomé y Príncipe","fr":"Sao Tomé-et-Principe","ja":"サントメ・プリンシペ","it":"São Tomé e Príncipe","br":"São Tomé e Príncipe","pt":"São Tomé e Príncipe","nl":"Sao Tomé en Principe","hr":"Sveti Toma i Princip","fa":"کواترو دو فرویرو"},"flag":"https://restcountries.eu/data/stp.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"STP"} +{"name":"Saudi Arabia","topLevelDomain":[".sa"],"alpha2Code":"SA","alpha3Code":"SAU","callingCodes":["966"],"capital":"Riyadh","altSpellings":["SA","Kingdom of Saudi Arabia","Al-Mamlakah al-‘Arabiyyah as-Su‘ūdiyyah"],"region":"Asia","subregion":"Western Asia","population":32248200,"latlng":[25.0,45.0],"demonym":"Saudi Arabian","area":2149690.0,"gini":null,"timezones":["UTC+03:00"],"borders":["IRQ","JOR","KWT","OMN","QAT","ARE","YEM"],"nativeName":"العربية السعودية","numericCode":"682","currencies":[{"code":"SAR","name":"Saudi riyal","symbol":"ر.س"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Saudi-Arabien","es":"Arabia Saudí","fr":"Arabie Saoudite","ja":"サウジアラビア","it":"Arabia Saudita","br":"Arábia Saudita","pt":"Arábia Saudita","nl":"Saoedi-Arabië","hr":"Saudijska Arabija","fa":"عربستان سعودی"},"flag":"https://restcountries.eu/data/sau.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"KSA"} +{"name":"Senegal","topLevelDomain":[".sn"],"alpha2Code":"SN","alpha3Code":"SEN","callingCodes":["221"],"capital":"Dakar","altSpellings":["SN","Republic of Senegal","République du Sénégal"],"region":"Africa","subregion":"Western Africa","population":14799859,"latlng":[14.0,-14.0],"demonym":"Senegalese","area":196722.0,"gini":39.2,"timezones":["UTC"],"borders":["GMB","GIN","GNB","MLI","MRT"],"nativeName":"Sénégal","numericCode":"686","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Senegal","es":"Senegal","fr":"Sénégal","ja":"セネガル","it":"Senegal","br":"Senegal","pt":"Senegal","nl":"Senegal","hr":"Senegal","fa":"سنگال"},"flag":"https://restcountries.eu/data/sen.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"SEN"} +{"name":"Serbia","topLevelDomain":[".rs"],"alpha2Code":"RS","alpha3Code":"SRB","callingCodes":["381"],"capital":"Belgrade","altSpellings":["RS","Srbija","Republic of Serbia","Република Србија","Republika Srbija"],"region":"Europe","subregion":"Southern Europe","population":7076372,"latlng":[44.0,21.0],"demonym":"Serbian","area":88361.0,"gini":27.8,"timezones":["UTC+01:00"],"borders":["BIH","BGR","HRV","HUN","KOS","MKD","MNE","ROU"],"nativeName":"Србија","numericCode":"688","currencies":[{"code":"RSD","name":"Serbian dinar","symbol":"дин."}],"languages":[{"iso639_1":"sr","iso639_2":"srp","name":"Serbian","nativeName":"српски језик"}],"translations":{"de":"Serbien","es":"Serbia","fr":"Serbie","ja":"セルビア","it":"Serbia","br":"Sérvia","pt":"Sérvia","nl":"Servië","hr":"Srbija","fa":"صربستان"},"flag":"https://restcountries.eu/data/srb.svg","regionalBlocs":[{"acronym":"CEFTA","name":"Central European Free Trade Agreement","otherAcronyms":[],"otherNames":[]}],"cioc":"SRB"} +{"name":"Seychelles","topLevelDomain":[".sc"],"alpha2Code":"SC","alpha3Code":"SYC","callingCodes":["248"],"capital":"Victoria","altSpellings":["SC","Republic of Seychelles","Repiblik Sesel","République des Seychelles"],"region":"Africa","subregion":"Eastern Africa","population":91400,"latlng":[-4.58333333,55.66666666],"demonym":"Seychellois","area":452.0,"gini":65.8,"timezones":["UTC+04:00"],"borders":[],"nativeName":"Seychelles","numericCode":"690","currencies":[{"code":"SCR","name":"Seychellois rupee","symbol":"₨"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Seychellen","es":"Seychelles","fr":"Seychelles","ja":"セーシェル","it":"Seychelles","br":"Seicheles","pt":"Seicheles","nl":"Seychellen","hr":"Sejšeli","fa":"سیشل"},"flag":"https://restcountries.eu/data/syc.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"SEY"} +{"name":"Sierra Leone","topLevelDomain":[".sl"],"alpha2Code":"SL","alpha3Code":"SLE","callingCodes":["232"],"capital":"Freetown","altSpellings":["SL","Republic of Sierra Leone"],"region":"Africa","subregion":"Western Africa","population":7075641,"latlng":[8.5,-11.5],"demonym":"Sierra Leonean","area":71740.0,"gini":42.5,"timezones":["UTC"],"borders":["GIN","LBR"],"nativeName":"Sierra Leone","numericCode":"694","currencies":[{"code":"SLL","name":"Sierra Leonean leone","symbol":"Le"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Sierra Leone","es":"Sierra Leone","fr":"Sierra Leone","ja":"シエラレオネ","it":"Sierra Leone","br":"Serra Leoa","pt":"Serra Leoa","nl":"Sierra Leone","hr":"Sijera Leone","fa":"سیرالئون"},"flag":"https://restcountries.eu/data/sle.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"SLE"} +{"name":"Singapore","topLevelDomain":[".sg"],"alpha2Code":"SG","alpha3Code":"SGP","callingCodes":["65"],"capital":"Singapore","altSpellings":["SG","Singapura","Republik Singapura","新加坡共和国"],"region":"Asia","subregion":"South-Eastern Asia","population":5535000,"latlng":[1.36666666,103.8],"demonym":"Singaporean","area":710.0,"gini":48.1,"timezones":["UTC+08:00"],"borders":[],"nativeName":"Singapore","numericCode":"702","currencies":[{"code":"BND","name":"Brunei dollar","symbol":"$"},{"code":"SGD","name":"Singapore dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ms","iso639_2":"msa","name":"Malay","nativeName":"bahasa Melayu"},{"iso639_1":"ta","iso639_2":"tam","name":"Tamil","nativeName":"தமிழ்"},{"iso639_1":"zh","iso639_2":"zho","name":"Chinese","nativeName":"中文 (Zhōngwén)"}],"translations":{"de":"Singapur","es":"Singapur","fr":"Singapour","ja":"シンガポール","it":"Singapore","br":"Singapura","pt":"Singapura","nl":"Singapore","hr":"Singapur","fa":"سنگاپور"},"flag":"https://restcountries.eu/data/sgp.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"SIN"} +{"name":"Sint Maarten (Dutch part)","topLevelDomain":[".sx"],"alpha2Code":"SX","alpha3Code":"SXM","callingCodes":["1721"],"capital":"Philipsburg","altSpellings":["SX"],"region":"Americas","subregion":"Caribbean","population":38247,"latlng":[18.033333,-63.05],"demonym":"Dutch","area":34.0,"gini":null,"timezones":["UTC-04:00"],"borders":["MAF"],"nativeName":"Sint Maarten","numericCode":"534","currencies":[{"code":"ANG","name":"Netherlands Antillean guilder","symbol":"ƒ"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Sint Maarten (niederl. Teil)","es":null,"fr":"Saint Martin (partie néerlandaise)","ja":null,"it":"Saint Martin (parte olandese)","br":"Sint Maarten","pt":"São Martinho","nl":"Sint Maarten","hr":null,"fa":"سینت مارتن"},"flag":"https://restcountries.eu/data/sxm.svg","regionalBlocs":[],"cioc":""} +{"name":"Slovakia","topLevelDomain":[".sk"],"alpha2Code":"SK","alpha3Code":"SVK","callingCodes":["421"],"capital":"Bratislava","altSpellings":["SK","Slovak Republic","Slovenská republika"],"region":"Europe","subregion":"Eastern Europe","population":5426252,"latlng":[48.66666666,19.5],"demonym":"Slovak","area":49037.0,"gini":26.0,"timezones":["UTC+01:00"],"borders":["AUT","CZE","HUN","POL","UKR"],"nativeName":"Slovensko","numericCode":"703","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"sk","iso639_2":"slk","name":"Slovak","nativeName":"slovenčina"}],"translations":{"de":"Slowakei","es":"República Eslovaca","fr":"Slovaquie","ja":"スロバキア","it":"Slovacchia","br":"Eslováquia","pt":"Eslováquia","nl":"Slowakije","hr":"Slovačka","fa":"اسلواکی"},"flag":"https://restcountries.eu/data/svk.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"SVK"} +{"name":"Slovenia","topLevelDomain":[".si"],"alpha2Code":"SI","alpha3Code":"SVN","callingCodes":["386"],"capital":"Ljubljana","altSpellings":["SI","Republic of Slovenia","Republika Slovenija"],"region":"Europe","subregion":"Southern Europe","population":2064188,"latlng":[46.11666666,14.81666666],"demonym":"Slovene","area":20273.0,"gini":31.2,"timezones":["UTC+01:00"],"borders":["AUT","HRV","ITA","HUN"],"nativeName":"Slovenija","numericCode":"705","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"sl","iso639_2":"slv","name":"Slovene","nativeName":"slovenski jezik"}],"translations":{"de":"Slowenien","es":"Eslovenia","fr":"Slovénie","ja":"スロベニア","it":"Slovenia","br":"Eslovênia","pt":"Eslovénia","nl":"Slovenië","hr":"Slovenija","fa":"اسلوونی"},"flag":"https://restcountries.eu/data/svn.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"SLO"} +{"name":"Solomon Islands","topLevelDomain":[".sb"],"alpha2Code":"SB","alpha3Code":"SLB","callingCodes":["677"],"capital":"Honiara","altSpellings":["SB"],"region":"Oceania","subregion":"Melanesia","population":642000,"latlng":[-8.0,159.0],"demonym":"Solomon Islander","area":28896.0,"gini":null,"timezones":["UTC+11:00"],"borders":[],"nativeName":"Solomon Islands","numericCode":"090","currencies":[{"code":"SBD","name":"Solomon Islands dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Salomonen","es":"Islas Salomón","fr":"Îles Salomon","ja":"ソロモン諸島","it":"Isole Salomone","br":"Ilhas Salomão","pt":"Ilhas Salomão","nl":"Salomonseilanden","hr":"Solomonski Otoci","fa":"جزایر سلیمان"},"flag":"https://restcountries.eu/data/slb.svg","regionalBlocs":[],"cioc":"SOL"} +{"name":"Somalia","topLevelDomain":[".so"],"alpha2Code":"SO","alpha3Code":"SOM","callingCodes":["252"],"capital":"Mogadishu","altSpellings":["SO","aṣ-Ṣūmāl","Federal Republic of Somalia","Jamhuuriyadda Federaalka Soomaaliya","Jumhūriyyat aṣ-Ṣūmāl al-Fiderāliyya"],"region":"Africa","subregion":"Eastern Africa","population":11079000,"latlng":[10.0,49.0],"demonym":"Somali","area":637657.0,"gini":null,"timezones":["UTC+03:00"],"borders":["DJI","ETH","KEN"],"nativeName":"Soomaaliya","numericCode":"706","currencies":[{"code":"SOS","name":"Somali shilling","symbol":"Sh"}],"languages":[{"iso639_1":"so","iso639_2":"som","name":"Somali","nativeName":"Soomaaliga"},{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Somalia","es":"Somalia","fr":"Somalie","ja":"ソマリア","it":"Somalia","br":"Somália","pt":"Somália","nl":"Somalië","hr":"Somalija","fa":"سومالی"},"flag":"https://restcountries.eu/data/som.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"SOM"} +{"name":"South Africa","topLevelDomain":[".za"],"alpha2Code":"ZA","alpha3Code":"ZAF","callingCodes":["27"],"capital":"Pretoria","altSpellings":["ZA","RSA","Suid-Afrika","Republic of South Africa"],"region":"Africa","subregion":"Southern Africa","population":55653654,"latlng":[-29.0,24.0],"demonym":"South African","area":1221037.0,"gini":63.1,"timezones":["UTC+02:00"],"borders":["BWA","LSO","MOZ","NAM","SWZ","ZWE"],"nativeName":"South Africa","numericCode":"710","currencies":[{"code":"ZAR","name":"South African rand","symbol":"R"}],"languages":[{"iso639_1":"af","iso639_2":"afr","name":"Afrikaans","nativeName":"Afrikaans"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"nr","iso639_2":"nbl","name":"Southern Ndebele","nativeName":"isiNdebele"},{"iso639_1":"st","iso639_2":"sot","name":"Southern Sotho","nativeName":"Sesotho"},{"iso639_1":"ss","iso639_2":"ssw","name":"Swati","nativeName":"SiSwati"},{"iso639_1":"tn","iso639_2":"tsn","name":"Tswana","nativeName":"Setswana"},{"iso639_1":"ts","iso639_2":"tso","name":"Tsonga","nativeName":"Xitsonga"},{"iso639_1":"ve","iso639_2":"ven","name":"Venda","nativeName":"Tshivenḓa"},{"iso639_1":"xh","iso639_2":"xho","name":"Xhosa","nativeName":"isiXhosa"},{"iso639_1":"zu","iso639_2":"zul","name":"Zulu","nativeName":"isiZulu"}],"translations":{"de":"Republik Südafrika","es":"República de Sudáfrica","fr":"Afrique du Sud","ja":"南アフリカ","it":"Sud Africa","br":"República Sul-Africana","pt":"República Sul-Africana","nl":"Zuid-Afrika","hr":"Južnoafrička Republika","fa":"آفریقای جنوبی"},"flag":"https://restcountries.eu/data/zaf.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"RSA"} +{"name":"South Georgia and the South Sandwich Islands","topLevelDomain":[".gs"],"alpha2Code":"GS","alpha3Code":"SGS","callingCodes":["500"],"capital":"King Edward Point","altSpellings":["GS","South Georgia and the South Sandwich Islands"],"region":"Americas","subregion":"South America","population":30,"latlng":[-54.5,-37.0],"demonym":"South Georgia and the South Sandwich Islander","area":null,"gini":null,"timezones":["UTC-02:00"],"borders":[],"nativeName":"South Georgia","numericCode":"239","currencies":[{"code":"GBP","name":"British pound","symbol":"£"},{"code":"(none)","name":null,"symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Südgeorgien und die Südlichen Sandwichinseln","es":"Islas Georgias del Sur y Sandwich del Sur","fr":"Géorgie du Sud-et-les Îles Sandwich du Sud","ja":"サウスジョージア・サウスサンドウィッチ諸島","it":"Georgia del Sud e Isole Sandwich Meridionali","br":"Ilhas Geórgias do Sul e Sandwich do Sul","pt":"Ilhas Geórgia do Sul e Sanduíche do Sul","nl":"Zuid-Georgia en Zuidelijke Sandwicheilanden","hr":"Južna Georgija i otočje Južni Sandwich","fa":"جزایر جورجیای جنوبی و ساندویچ جنوبی"},"flag":"https://restcountries.eu/data/sgs.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":""} +{"name":"Korea (Republic of)","topLevelDomain":[".kr"],"alpha2Code":"KR","alpha3Code":"KOR","callingCodes":["82"],"capital":"Seoul","altSpellings":["KR","Republic of Korea"],"region":"Asia","subregion":"Eastern Asia","population":50801405,"latlng":[37.0,127.5],"demonym":"South Korean","area":100210.0,"gini":31.3,"timezones":["UTC+09:00"],"borders":["PRK"],"nativeName":"대한민국","numericCode":"410","currencies":[{"code":"KRW","name":"South Korean won","symbol":"₩"}],"languages":[{"iso639_1":"ko","iso639_2":"kor","name":"Korean","nativeName":"한국어"}],"translations":{"de":"Südkorea","es":"Corea del Sur","fr":"Corée du Sud","ja":"大韓民国","it":"Corea del Sud","br":"Coreia do Sul","pt":"Coreia do Sul","nl":"Zuid-Korea","hr":"Južna Koreja","fa":"کره شمالی"},"flag":"https://restcountries.eu/data/kor.svg","regionalBlocs":[],"cioc":"KOR"} +{"name":"South Sudan","topLevelDomain":[".ss"],"alpha2Code":"SS","alpha3Code":"SSD","callingCodes":["211"],"capital":"Juba","altSpellings":["SS"],"region":"Africa","subregion":"Middle Africa","population":12131000,"latlng":[7.0,30.0],"demonym":"South Sudanese","area":619745.0,"gini":45.5,"timezones":["UTC+03:00"],"borders":["CAF","COD","ETH","KEN","SDN","UGA"],"nativeName":"South Sudan","numericCode":"728","currencies":[{"code":"SSP","name":"South Sudanese pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Südsudan","es":"Sudán del Sur","fr":"Soudan du Sud","ja":"南スーダン","it":"Sudan del sud","br":"Sudão do Sul","pt":"Sudão do Sul","nl":"Zuid-Soedan","hr":"Južni Sudan","fa":"سودان جنوبی"},"flag":"https://restcountries.eu/data/ssd.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":""} +{"name":"Spain","topLevelDomain":[".es"],"alpha2Code":"ES","alpha3Code":"ESP","callingCodes":["34"],"capital":"Madrid","altSpellings":["ES","Kingdom of Spain","Reino de España"],"region":"Europe","subregion":"Southern Europe","population":46438422,"latlng":[40.0,-4.0],"demonym":"Spanish","area":505992.0,"gini":34.7,"timezones":["UTC","UTC+01:00"],"borders":["AND","FRA","GIB","PRT","MAR"],"nativeName":"España","numericCode":"724","currencies":[{"code":"EUR","name":"Euro","symbol":"€"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Spanien","es":"España","fr":"Espagne","ja":"スペイン","it":"Spagna","br":"Espanha","pt":"Espanha","nl":"Spanje","hr":"Španjolska","fa":"اسپانیا"},"flag":"https://restcountries.eu/data/esp.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"ESP"} +{"name":"Sri Lanka","topLevelDomain":[".lk"],"alpha2Code":"LK","alpha3Code":"LKA","callingCodes":["94"],"capital":"Colombo","altSpellings":["LK","ilaṅkai","Democratic Socialist Republic of Sri Lanka"],"region":"Asia","subregion":"Southern Asia","population":20966000,"latlng":[7.0,81.0],"demonym":"Sri Lankan","area":65610.0,"gini":40.3,"timezones":["UTC+05:30"],"borders":["IND"],"nativeName":"śrī laṃkāva","numericCode":"144","currencies":[{"code":"LKR","name":"Sri Lankan rupee","symbol":"Rs"}],"languages":[{"iso639_1":"si","iso639_2":"sin","name":"Sinhalese","nativeName":"සිංහල"},{"iso639_1":"ta","iso639_2":"tam","name":"Tamil","nativeName":"தமிழ்"}],"translations":{"de":"Sri Lanka","es":"Sri Lanka","fr":"Sri Lanka","ja":"スリランカ","it":"Sri Lanka","br":"Sri Lanka","pt":"Sri Lanka","nl":"Sri Lanka","hr":"Šri Lanka","fa":"سری‌لانکا"},"flag":"https://restcountries.eu/data/lka.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"SRI"} +{"name":"Sudan","topLevelDomain":[".sd"],"alpha2Code":"SD","alpha3Code":"SDN","callingCodes":["249"],"capital":"Khartoum","altSpellings":["SD","Republic of the Sudan","Jumhūrīyat as-Sūdān"],"region":"Africa","subregion":"Northern Africa","population":39598700,"latlng":[15.0,30.0],"demonym":"Sudanese","area":1886068.0,"gini":35.3,"timezones":["UTC+03:00"],"borders":["CAF","TCD","EGY","ERI","ETH","LBY","SSD"],"nativeName":"السودان","numericCode":"729","currencies":[{"code":"SDG","name":"Sudanese pound","symbol":"ج.س."}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Sudan","es":"Sudán","fr":"Soudan","ja":"スーダン","it":"Sudan","br":"Sudão","pt":"Sudão","nl":"Soedan","hr":"Sudan","fa":"سودان"},"flag":"https://restcountries.eu/data/sdn.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"SUD"} +{"name":"Suriname","topLevelDomain":[".sr"],"alpha2Code":"SR","alpha3Code":"SUR","callingCodes":["597"],"capital":"Paramaribo","altSpellings":["SR","Sarnam","Sranangron","Republic of Suriname","Republiek Suriname"],"region":"Americas","subregion":"South America","population":541638,"latlng":[4.0,-56.0],"demonym":"Surinamer","area":163820.0,"gini":52.9,"timezones":["UTC-03:00"],"borders":["BRA","GUF","FRA","GUY"],"nativeName":"Suriname","numericCode":"740","currencies":[{"code":"SRD","name":"Surinamese dollar","symbol":"$"}],"languages":[{"iso639_1":"nl","iso639_2":"nld","name":"Dutch","nativeName":"Nederlands"}],"translations":{"de":"Suriname","es":"Surinam","fr":"Surinam","ja":"スリナム","it":"Suriname","br":"Suriname","pt":"Suriname","nl":"Suriname","hr":"Surinam","fa":"سورینام"},"flag":"https://restcountries.eu/data/sur.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]},{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"SUR"} +{"name":"Svalbard and Jan Mayen","topLevelDomain":[".sj"],"alpha2Code":"SJ","alpha3Code":"SJM","callingCodes":["4779"],"capital":"Longyearbyen","altSpellings":["SJ","Svalbard and Jan Mayen Islands"],"region":"Europe","subregion":"Northern Europe","population":2562,"latlng":[78.0,20.0],"demonym":"Norwegian","area":null,"gini":null,"timezones":["UTC+01:00"],"borders":[],"nativeName":"Svalbard og Jan Mayen","numericCode":"744","currencies":[{"code":"NOK","name":"Norwegian krone","symbol":"kr"}],"languages":[{"iso639_1":"no","iso639_2":"nor","name":"Norwegian","nativeName":"Norsk"}],"translations":{"de":"Svalbard und Jan Mayen","es":"Islas Svalbard y Jan Mayen","fr":"Svalbard et Jan Mayen","ja":"スヴァールバル諸島およびヤンマイエン島","it":"Svalbard e Jan Mayen","br":"Svalbard","pt":"Svalbard","nl":"Svalbard en Jan Mayen","hr":"Svalbard i Jan Mayen","fa":"سوالبارد و یان ماین"},"flag":"https://restcountries.eu/data/sjm.svg","regionalBlocs":[],"cioc":""} +{"name":"Swaziland","topLevelDomain":[".sz"],"alpha2Code":"SZ","alpha3Code":"SWZ","callingCodes":["268"],"capital":"Lobamba","altSpellings":["SZ","weSwatini","Swatini","Ngwane","Kingdom of Swaziland","Umbuso waseSwatini"],"region":"Africa","subregion":"Southern Africa","population":1132657,"latlng":[-26.5,31.5],"demonym":"Swazi","area":17364.0,"gini":51.5,"timezones":["UTC+02:00"],"borders":["MOZ","ZAF"],"nativeName":"Swaziland","numericCode":"748","currencies":[{"code":"SZL","name":"Swazi lilangeni","symbol":"L"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"ss","iso639_2":"ssw","name":"Swati","nativeName":"SiSwati"}],"translations":{"de":"Swasiland","es":"Suazilandia","fr":"Swaziland","ja":"スワジランド","it":"Swaziland","br":"Suazilândia","pt":"Suazilândia","nl":"Swaziland","hr":"Svazi","fa":"سوازیلند"},"flag":"https://restcountries.eu/data/swz.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"SWZ"} +{"name":"Sweden","topLevelDomain":[".se"],"alpha2Code":"SE","alpha3Code":"SWE","callingCodes":["46"],"capital":"Stockholm","altSpellings":["SE","Kingdom of Sweden","Konungariket Sverige"],"region":"Europe","subregion":"Northern Europe","population":9894888,"latlng":[62.0,15.0],"demonym":"Swedish","area":450295.0,"gini":25.0,"timezones":["UTC+01:00"],"borders":["FIN","NOR"],"nativeName":"Sverige","numericCode":"752","currencies":[{"code":"SEK","name":"Swedish krona","symbol":"kr"}],"languages":[{"iso639_1":"sv","iso639_2":"swe","name":"Swedish","nativeName":"svenska"}],"translations":{"de":"Schweden","es":"Suecia","fr":"Suède","ja":"スウェーデン","it":"Svezia","br":"Suécia","pt":"Suécia","nl":"Zweden","hr":"Švedska","fa":"سوئد"},"flag":"https://restcountries.eu/data/swe.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"SWE"} +{"name":"Switzerland","topLevelDomain":[".ch"],"alpha2Code":"CH","alpha3Code":"CHE","callingCodes":["41"],"capital":"Bern","altSpellings":["CH","Swiss Confederation","Schweiz","Suisse","Svizzera","Svizra"],"region":"Europe","subregion":"Western Europe","population":8341600,"latlng":[47.0,8.0],"demonym":"Swiss","area":41284.0,"gini":33.7,"timezones":["UTC+01:00"],"borders":["AUT","FRA","ITA","LIE","DEU"],"nativeName":"Schweiz","numericCode":"756","currencies":[{"code":"CHF","name":"Swiss franc","symbol":"Fr"}],"languages":[{"iso639_1":"de","iso639_2":"deu","name":"German","nativeName":"Deutsch"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"},{"iso639_1":"it","iso639_2":"ita","name":"Italian","nativeName":"Italiano"}],"translations":{"de":"Schweiz","es":"Suiza","fr":"Suisse","ja":"スイス","it":"Svizzera","br":"Suíça","pt":"Suíça","nl":"Zwitserland","hr":"Švicarska","fa":"سوئیس"},"flag":"https://restcountries.eu/data/che.svg","regionalBlocs":[{"acronym":"EFTA","name":"European Free Trade Association","otherAcronyms":[],"otherNames":[]}],"cioc":"SUI"} +{"name":"Syrian Arab Republic","topLevelDomain":[".sy"],"alpha2Code":"SY","alpha3Code":"SYR","callingCodes":["963"],"capital":"Damascus","altSpellings":["SY","Syrian Arab Republic","Al-Jumhūrīyah Al-ʻArabīyah As-Sūrīyah"],"region":"Asia","subregion":"Western Asia","population":18564000,"latlng":[35.0,38.0],"demonym":"Syrian","area":185180.0,"gini":35.8,"timezones":["UTC+02:00"],"borders":["IRQ","ISR","JOR","LBN","TUR"],"nativeName":"سوريا","numericCode":"760","currencies":[{"code":"SYP","name":"Syrian pound","symbol":"£"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Syrien","es":"Siria","fr":"Syrie","ja":"シリア・アラブ共和国","it":"Siria","br":"Síria","pt":"Síria","nl":"Syrië","hr":"Sirija","fa":"سوریه"},"flag":"https://restcountries.eu/data/syr.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"SYR"} +{"name":"Taiwan","topLevelDomain":[".tw"],"alpha2Code":"TW","alpha3Code":"TWN","callingCodes":["886"],"capital":"Taipei","altSpellings":["TW","Táiwān","Republic of China","中華民國","Zhōnghuá Mínguó"],"region":"Asia","subregion":"Eastern Asia","population":23503349,"latlng":[23.5,121.0],"demonym":"Taiwanese","area":36193.0,"gini":null,"timezones":["UTC+08:00"],"borders":[],"nativeName":"臺灣","numericCode":"158","currencies":[{"code":"TWD","name":"New Taiwan dollar","symbol":"$"}],"languages":[{"iso639_1":"zh","iso639_2":"zho","name":"Chinese","nativeName":"中文 (Zhōngwén)"}],"translations":{"de":"Taiwan","es":"Taiwán","fr":"Taïwan","ja":"台湾(中華民国)","it":"Taiwan","br":"Taiwan","pt":"Taiwan","nl":"Taiwan","hr":"Tajvan","fa":"تایوان"},"flag":"https://restcountries.eu/data/twn.svg","regionalBlocs":[],"cioc":"TPE"} +{"name":"Tajikistan","topLevelDomain":[".tj"],"alpha2Code":"TJ","alpha3Code":"TJK","callingCodes":["992"],"capital":"Dushanbe","altSpellings":["TJ","Toçikiston","Republic of Tajikistan","Ҷумҳурии Тоҷикистон","Çumhuriyi Toçikiston"],"region":"Asia","subregion":"Central Asia","population":8593600,"latlng":[39.0,71.0],"demonym":"Tadzhik","area":143100.0,"gini":30.8,"timezones":["UTC+05:00"],"borders":["AFG","CHN","KGZ","UZB"],"nativeName":"Тоҷикистон","numericCode":"762","currencies":[{"code":"TJS","name":"Tajikistani somoni","symbol":"ЅМ"}],"languages":[{"iso639_1":"tg","iso639_2":"tgk","name":"Tajik","nativeName":"тоҷикӣ"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Tadschikistan","es":"Tayikistán","fr":"Tadjikistan","ja":"タジキスタン","it":"Tagikistan","br":"Tajiquistão","pt":"Tajiquistão","nl":"Tadzjikistan","hr":"Tađikistan","fa":"تاجیکستان"},"flag":"https://restcountries.eu/data/tjk.svg","regionalBlocs":[],"cioc":"TJK"} +{"name":"Tanzania, United Republic of","topLevelDomain":[".tz"],"alpha2Code":"TZ","alpha3Code":"TZA","callingCodes":["255"],"capital":"Dodoma","altSpellings":["TZ","United Republic of Tanzania","Jamhuri ya Muungano wa Tanzania"],"region":"Africa","subregion":"Eastern Africa","population":55155000,"latlng":[-6.0,35.0],"demonym":"Tanzanian","area":945087.0,"gini":37.6,"timezones":["UTC+03:00"],"borders":["BDI","COD","KEN","MWI","MOZ","RWA","UGA","ZMB"],"nativeName":"Tanzania","numericCode":"834","currencies":[{"code":"TZS","name":"Tanzanian shilling","symbol":"Sh"}],"languages":[{"iso639_1":"sw","iso639_2":"swa","name":"Swahili","nativeName":"Kiswahili"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Tansania","es":"Tanzania","fr":"Tanzanie","ja":"タンザニア","it":"Tanzania","br":"Tanzânia","pt":"Tanzânia","nl":"Tanzania","hr":"Tanzanija","fa":"تانزانیا"},"flag":"https://restcountries.eu/data/tza.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"TAN"} +{"name":"Thailand","topLevelDomain":[".th"],"alpha2Code":"TH","alpha3Code":"THA","callingCodes":["66"],"capital":"Bangkok","altSpellings":["TH","Prathet","Thai","Kingdom of Thailand","ราชอาณาจักรไทย","Ratcha Anachak Thai"],"region":"Asia","subregion":"South-Eastern Asia","population":65327652,"latlng":[15.0,100.0],"demonym":"Thai","area":513120.0,"gini":40.0,"timezones":["UTC+07:00"],"borders":["MMR","KHM","LAO","MYS"],"nativeName":"ประเทศไทย","numericCode":"764","currencies":[{"code":"THB","name":"Thai baht","symbol":"฿"}],"languages":[{"iso639_1":"th","iso639_2":"tha","name":"Thai","nativeName":"ไทย"}],"translations":{"de":"Thailand","es":"Tailandia","fr":"Thaïlande","ja":"タイ","it":"Tailandia","br":"Tailândia","pt":"Tailândia","nl":"Thailand","hr":"Tajland","fa":"تایلند"},"flag":"https://restcountries.eu/data/tha.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"THA"} +{"name":"Timor-Leste","topLevelDomain":[".tl"],"alpha2Code":"TL","alpha3Code":"TLS","callingCodes":["670"],"capital":"Dili","altSpellings":["TL","East Timor","Democratic Republic of Timor-Leste","República Democrática de Timor-Leste","Repúblika Demokrátika Timór-Leste"],"region":"Asia","subregion":"South-Eastern Asia","population":1167242,"latlng":[-8.83333333,125.91666666],"demonym":"East Timorese","area":14874.0,"gini":31.9,"timezones":["UTC+09:00"],"borders":["IDN"],"nativeName":"Timor-Leste","numericCode":"626","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"},{"code":null,"name":null,"symbol":null}],"languages":[{"iso639_1":"pt","iso639_2":"por","name":"Portuguese","nativeName":"Português"}],"translations":{"de":"Timor-Leste","es":"Timor Oriental","fr":"Timor oriental","ja":"東ティモール","it":"Timor Est","br":"Timor Leste","pt":"Timor Leste","nl":"Oost-Timor","hr":"Istočni Timor","fa":"تیمور شرقی"},"flag":"https://restcountries.eu/data/tls.svg","regionalBlocs":[],"cioc":"TLS"} +{"name":"Togo","topLevelDomain":[".tg"],"alpha2Code":"TG","alpha3Code":"TGO","callingCodes":["228"],"capital":"Lomé","altSpellings":["TG","Togolese","Togolese Republic","République Togolaise"],"region":"Africa","subregion":"Western Africa","population":7143000,"latlng":[8.0,1.16666666],"demonym":"Togolese","area":56785.0,"gini":34.4,"timezones":["UTC"],"borders":["BEN","BFA","GHA"],"nativeName":"Togo","numericCode":"768","currencies":[{"code":"XOF","name":"West African CFA franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Togo","es":"Togo","fr":"Togo","ja":"トーゴ","it":"Togo","br":"Togo","pt":"Togo","nl":"Togo","hr":"Togo","fa":"توگو"},"flag":"https://restcountries.eu/data/tgo.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"TOG"} +{"name":"Tokelau","topLevelDomain":[".tk"],"alpha2Code":"TK","alpha3Code":"TKL","callingCodes":["690"],"capital":"Fakaofo","altSpellings":["TK"],"region":"Oceania","subregion":"Polynesia","population":1411,"latlng":[-9.0,-172.0],"demonym":"Tokelauan","area":12.0,"gini":null,"timezones":["UTC+13:00"],"borders":[],"nativeName":"Tokelau","numericCode":"772","currencies":[{"code":"NZD","name":"New Zealand dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Tokelau","es":"Islas Tokelau","fr":"Tokelau","ja":"トケラウ","it":"Isole Tokelau","br":"Tokelau","pt":"Toquelau","nl":"Tokelau","hr":"Tokelau","fa":"توکلائو"},"flag":"https://restcountries.eu/data/tkl.svg","regionalBlocs":[],"cioc":""} +{"name":"Tonga","topLevelDomain":[".to"],"alpha2Code":"TO","alpha3Code":"TON","callingCodes":["676"],"capital":"Nuku'alofa","altSpellings":["TO"],"region":"Oceania","subregion":"Polynesia","population":103252,"latlng":[-20.0,-175.0],"demonym":"Tongan","area":747.0,"gini":null,"timezones":["UTC+13:00"],"borders":[],"nativeName":"Tonga","numericCode":"776","currencies":[{"code":"TOP","name":"Tongan paʻanga","symbol":"T$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"to","iso639_2":"ton","name":"Tonga (Tonga Islands)","nativeName":"faka Tonga"}],"translations":{"de":"Tonga","es":"Tonga","fr":"Tonga","ja":"トンガ","it":"Tonga","br":"Tonga","pt":"Tonga","nl":"Tonga","hr":"Tonga","fa":"تونگا"},"flag":"https://restcountries.eu/data/ton.svg","regionalBlocs":[],"cioc":"TGA"} +{"name":"Trinidad and Tobago","topLevelDomain":[".tt"],"alpha2Code":"TT","alpha3Code":"TTO","callingCodes":["1868"],"capital":"Port of Spain","altSpellings":["TT","Republic of Trinidad and Tobago"],"region":"Americas","subregion":"Caribbean","population":1349667,"latlng":[11.0,-61.0],"demonym":"Trinidadian","area":5130.0,"gini":40.3,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Trinidad and Tobago","numericCode":"780","currencies":[{"code":"TTD","name":"Trinidad and Tobago dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Trinidad und Tobago","es":"Trinidad y Tobago","fr":"Trinité et Tobago","ja":"トリニダード・トバゴ","it":"Trinidad e Tobago","br":"Trinidad e Tobago","pt":"Trindade e Tobago","nl":"Trinidad en Tobago","hr":"Trinidad i Tobago","fa":"ترینیداد و توباگو"},"flag":"https://restcountries.eu/data/tto.svg","regionalBlocs":[{"acronym":"CARICOM","name":"Caribbean Community","otherAcronyms":[],"otherNames":["Comunidad del Caribe","Communauté Caribéenne","Caribische Gemeenschap"]}],"cioc":"TTO"} +{"name":"Tunisia","topLevelDomain":[".tn"],"alpha2Code":"TN","alpha3Code":"TUN","callingCodes":["216"],"capital":"Tunis","altSpellings":["TN","Republic of Tunisia","al-Jumhūriyyah at-Tūnisiyyah"],"region":"Africa","subregion":"Northern Africa","population":11154400,"latlng":[34.0,9.0],"demonym":"Tunisian","area":163610.0,"gini":41.4,"timezones":["UTC+01:00"],"borders":["DZA","LBY"],"nativeName":"تونس","numericCode":"788","currencies":[{"code":"TND","name":"Tunisian dinar","symbol":"د.ت"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Tunesien","es":"Túnez","fr":"Tunisie","ja":"チュニジア","it":"Tunisia","br":"Tunísia","pt":"Tunísia","nl":"Tunesië","hr":"Tunis","fa":"تونس"},"flag":"https://restcountries.eu/data/tun.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]},{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"TUN"} +{"name":"Turkey","topLevelDomain":[".tr"],"alpha2Code":"TR","alpha3Code":"TUR","callingCodes":["90"],"capital":"Ankara","altSpellings":["TR","Turkiye","Republic of Turkey","Türkiye Cumhuriyeti"],"region":"Asia","subregion":"Western Asia","population":78741053,"latlng":[39.0,35.0],"demonym":"Turkish","area":783562.0,"gini":39.0,"timezones":["UTC+03:00"],"borders":["ARM","AZE","BGR","GEO","GRC","IRN","IRQ","SYR"],"nativeName":"Türkiye","numericCode":"792","currencies":[{"code":"TRY","name":"Turkish lira","symbol":null}],"languages":[{"iso639_1":"tr","iso639_2":"tur","name":"Turkish","nativeName":"Türkçe"}],"translations":{"de":"Türkei","es":"Turquía","fr":"Turquie","ja":"トルコ","it":"Turchia","br":"Turquia","pt":"Turquia","nl":"Turkije","hr":"Turska","fa":"ترکیه"},"flag":"https://restcountries.eu/data/tur.svg","regionalBlocs":[],"cioc":"TUR"} +{"name":"Turkmenistan","topLevelDomain":[".tm"],"alpha2Code":"TM","alpha3Code":"TKM","callingCodes":["993"],"capital":"Ashgabat","altSpellings":["TM"],"region":"Asia","subregion":"Central Asia","population":4751120,"latlng":[40.0,60.0],"demonym":"Turkmen","area":488100.0,"gini":40.8,"timezones":["UTC+05:00"],"borders":["AFG","IRN","KAZ","UZB"],"nativeName":"Türkmenistan","numericCode":"795","currencies":[{"code":"TMT","name":"Turkmenistan manat","symbol":"m"}],"languages":[{"iso639_1":"tk","iso639_2":"tuk","name":"Turkmen","nativeName":"Türkmen"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Turkmenistan","es":"Turkmenistán","fr":"Turkménistan","ja":"トルクメニスタン","it":"Turkmenistan","br":"Turcomenistão","pt":"Turquemenistão","nl":"Turkmenistan","hr":"Turkmenistan","fa":"ترکمنستان"},"flag":"https://restcountries.eu/data/tkm.svg","regionalBlocs":[],"cioc":"TKM"} +{"name":"Turks and Caicos Islands","topLevelDomain":[".tc"],"alpha2Code":"TC","alpha3Code":"TCA","callingCodes":["1649"],"capital":"Cockburn Town","altSpellings":["TC"],"region":"Americas","subregion":"Caribbean","population":31458,"latlng":[21.75,-71.58333333],"demonym":"Turks and Caicos Islander","area":948.0,"gini":null,"timezones":["UTC-04:00"],"borders":[],"nativeName":"Turks and Caicos Islands","numericCode":"796","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Turks- und Caicosinseln","es":"Islas Turks y Caicos","fr":"Îles Turques-et-Caïques","ja":"タークス・カイコス諸島","it":"Isole Turks e Caicos","br":"Ilhas Turcas e Caicos","pt":"Ilhas Turcas e Caicos","nl":"Turks- en Caicoseilanden","hr":"Otoci Turks i Caicos","fa":"جزایر تورکس و کایکوس"},"flag":"https://restcountries.eu/data/tca.svg","regionalBlocs":[],"cioc":""} +{"name":"Tuvalu","topLevelDomain":[".tv"],"alpha2Code":"TV","alpha3Code":"TUV","callingCodes":["688"],"capital":"Funafuti","altSpellings":["TV"],"region":"Oceania","subregion":"Polynesia","population":10640,"latlng":[-8.0,178.0],"demonym":"Tuvaluan","area":26.0,"gini":null,"timezones":["UTC+12:00"],"borders":[],"nativeName":"Tuvalu","numericCode":"798","currencies":[{"code":"AUD","name":"Australian dollar","symbol":"$"},{"code":"TVD[G]","name":"Tuvaluan dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Tuvalu","es":"Tuvalu","fr":"Tuvalu","ja":"ツバル","it":"Tuvalu","br":"Tuvalu","pt":"Tuvalu","nl":"Tuvalu","hr":"Tuvalu","fa":"تووالو"},"flag":"https://restcountries.eu/data/tuv.svg","regionalBlocs":[],"cioc":"TUV"} +{"name":"Uganda","topLevelDomain":[".ug"],"alpha2Code":"UG","alpha3Code":"UGA","callingCodes":["256"],"capital":"Kampala","altSpellings":["UG","Republic of Uganda","Jamhuri ya Uganda"],"region":"Africa","subregion":"Eastern Africa","population":33860700,"latlng":[1.0,32.0],"demonym":"Ugandan","area":241550.0,"gini":44.3,"timezones":["UTC+03:00"],"borders":["COD","KEN","RWA","SSD","TZA"],"nativeName":"Uganda","numericCode":"800","currencies":[{"code":"UGX","name":"Ugandan shilling","symbol":"Sh"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"sw","iso639_2":"swa","name":"Swahili","nativeName":"Kiswahili"}],"translations":{"de":"Uganda","es":"Uganda","fr":"Uganda","ja":"ウガンダ","it":"Uganda","br":"Uganda","pt":"Uganda","nl":"Oeganda","hr":"Uganda","fa":"اوگاندا"},"flag":"https://restcountries.eu/data/uga.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"UGA"} +{"name":"Ukraine","topLevelDomain":[".ua"],"alpha2Code":"UA","alpha3Code":"UKR","callingCodes":["380"],"capital":"Kiev","altSpellings":["UA","Ukrayina"],"region":"Europe","subregion":"Eastern Europe","population":42692393,"latlng":[49.0,32.0],"demonym":"Ukrainian","area":603700.0,"gini":26.4,"timezones":["UTC+02:00"],"borders":["BLR","HUN","MDA","POL","ROU","RUS","SVK"],"nativeName":"Україна","numericCode":"804","currencies":[{"code":"UAH","name":"Ukrainian hryvnia","symbol":"₴"}],"languages":[{"iso639_1":"uk","iso639_2":"ukr","name":"Ukrainian","nativeName":"Українська"}],"translations":{"de":"Ukraine","es":"Ucrania","fr":"Ukraine","ja":"ウクライナ","it":"Ucraina","br":"Ucrânia","pt":"Ucrânia","nl":"Oekraïne","hr":"Ukrajina","fa":"وکراین"},"flag":"https://restcountries.eu/data/ukr.svg","regionalBlocs":[],"cioc":"UKR"} +{"name":"United Arab Emirates","topLevelDomain":[".ae"],"alpha2Code":"AE","alpha3Code":"ARE","callingCodes":["971"],"capital":"Abu Dhabi","altSpellings":["AE","UAE"],"region":"Asia","subregion":"Western Asia","population":9856000,"latlng":[24.0,54.0],"demonym":"Emirati","area":83600.0,"gini":null,"timezones":["UTC+04"],"borders":["OMN","SAU"],"nativeName":"دولة الإمارات العربية المتحدة","numericCode":"784","currencies":[{"code":"AED","name":"United Arab Emirates dirham","symbol":"د.إ"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Vereinigte Arabische Emirate","es":"Emiratos Árabes Unidos","fr":"Émirats arabes unis","ja":"アラブ首長国連邦","it":"Emirati Arabi Uniti","br":"Emirados árabes Unidos","pt":"Emirados árabes Unidos","nl":"Verenigde Arabische Emiraten","hr":"Ujedinjeni Arapski Emirati","fa":"امارات متحده عربی"},"flag":"https://restcountries.eu/data/are.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"UAE"} +{"name":"United Kingdom of Great Britain and Northern Ireland","topLevelDomain":[".uk"],"alpha2Code":"GB","alpha3Code":"GBR","callingCodes":["44"],"capital":"London","altSpellings":["GB","UK","Great Britain"],"region":"Europe","subregion":"Northern Europe","population":65110000,"latlng":[54.0,-2.0],"demonym":"British","area":242900.0,"gini":34.0,"timezones":["UTC-08:00","UTC-05:00","UTC-04:00","UTC-03:00","UTC-02:00","UTC","UTC+01:00","UTC+02:00","UTC+06:00"],"borders":["IRL"],"nativeName":"United Kingdom","numericCode":"826","currencies":[{"code":"GBP","name":"British pound","symbol":"£"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Vereinigtes Königreich","es":"Reino Unido","fr":"Royaume-Uni","ja":"イギリス","it":"Regno Unito","br":"Reino Unido","pt":"Reino Unido","nl":"Verenigd Koninkrijk","hr":"Ujedinjeno Kraljevstvo","fa":"بریتانیای کبیر و ایرلند شمالی"},"flag":"https://restcountries.eu/data/gbr.svg","regionalBlocs":[{"acronym":"EU","name":"European Union","otherAcronyms":[],"otherNames":[]}],"cioc":"GBR"} +{"name":"United States of America","topLevelDomain":[".us"],"alpha2Code":"US","alpha3Code":"USA","callingCodes":["1"],"capital":"Washington, D.C.","altSpellings":["US","USA","United States of America"],"region":"Americas","subregion":"Northern America","population":323947000,"latlng":[38.0,-97.0],"demonym":"American","area":9629091.0,"gini":48.0,"timezones":["UTC-12:00","UTC-11:00","UTC-10:00","UTC-09:00","UTC-08:00","UTC-07:00","UTC-06:00","UTC-05:00","UTC-04:00","UTC+10:00","UTC+12:00"],"borders":["CAN","MEX"],"nativeName":"United States","numericCode":"840","currencies":[{"code":"USD","name":"United States dollar","symbol":"$"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Vereinigte Staaten von Amerika","es":"Estados Unidos","fr":"États-Unis","ja":"アメリカ合衆国","it":"Stati Uniti D'America","br":"Estados Unidos","pt":"Estados Unidos","nl":"Verenigde Staten","hr":"Sjedinjene Američke Države","fa":"ایالات متحده آمریکا"},"flag":"https://restcountries.eu/data/usa.svg","regionalBlocs":[{"acronym":"NAFTA","name":"North American Free Trade Agreement","otherAcronyms":[],"otherNames":["Tratado de Libre Comercio de América del Norte","Accord de Libre-échange Nord-Américain"]}],"cioc":"USA"} +{"name":"Uruguay","topLevelDomain":[".uy"],"alpha2Code":"UY","alpha3Code":"URY","callingCodes":["598"],"capital":"Montevideo","altSpellings":["UY","Oriental Republic of Uruguay","República Oriental del Uruguay"],"region":"Americas","subregion":"South America","population":3480222,"latlng":[-33.0,-56.0],"demonym":"Uruguayan","area":181034.0,"gini":39.7,"timezones":["UTC-03:00"],"borders":["ARG","BRA"],"nativeName":"Uruguay","numericCode":"858","currencies":[{"code":"UYU","name":"Uruguayan peso","symbol":"$"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Uruguay","es":"Uruguay","fr":"Uruguay","ja":"ウルグアイ","it":"Uruguay","br":"Uruguai","pt":"Uruguai","nl":"Uruguay","hr":"Urugvaj","fa":"اروگوئه"},"flag":"https://restcountries.eu/data/ury.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"URU"} +{"name":"Uzbekistan","topLevelDomain":[".uz"],"alpha2Code":"UZ","alpha3Code":"UZB","callingCodes":["998"],"capital":"Tashkent","altSpellings":["UZ","Republic of Uzbekistan","O‘zbekiston Respublikasi","Ўзбекистон Республикаси"],"region":"Asia","subregion":"Central Asia","population":31576400,"latlng":[41.0,64.0],"demonym":"Uzbekistani","area":447400.0,"gini":36.7,"timezones":["UTC+05:00"],"borders":["AFG","KAZ","KGZ","TJK","TKM"],"nativeName":"O‘zbekiston","numericCode":"860","currencies":[{"code":"UZS","name":"Uzbekistani so'm","symbol":null}],"languages":[{"iso639_1":"uz","iso639_2":"uzb","name":"Uzbek","nativeName":"Oʻzbek"},{"iso639_1":"ru","iso639_2":"rus","name":"Russian","nativeName":"Русский"}],"translations":{"de":"Usbekistan","es":"Uzbekistán","fr":"Ouzbékistan","ja":"ウズベキスタン","it":"Uzbekistan","br":"Uzbequistão","pt":"Usbequistão","nl":"Oezbekistan","hr":"Uzbekistan","fa":"ازبکستان"},"flag":"https://restcountries.eu/data/uzb.svg","regionalBlocs":[],"cioc":"UZB"} +{"name":"Vanuatu","topLevelDomain":[".vu"],"alpha2Code":"VU","alpha3Code":"VUT","callingCodes":["678"],"capital":"Port Vila","altSpellings":["VU","Republic of Vanuatu","Ripablik blong Vanuatu","République de Vanuatu"],"region":"Oceania","subregion":"Melanesia","population":277500,"latlng":[-16.0,167.0],"demonym":"Ni-Vanuatu","area":12189.0,"gini":null,"timezones":["UTC+11:00"],"borders":[],"nativeName":"Vanuatu","numericCode":"548","currencies":[{"code":"VUV","name":"Vanuatu vatu","symbol":"Vt"}],"languages":[{"iso639_1":"bi","iso639_2":"bis","name":"Bislama","nativeName":"Bislama"},{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Vanuatu","es":"Vanuatu","fr":"Vanuatu","ja":"バヌアツ","it":"Vanuatu","br":"Vanuatu","pt":"Vanuatu","nl":"Vanuatu","hr":"Vanuatu","fa":"وانواتو"},"flag":"https://restcountries.eu/data/vut.svg","regionalBlocs":[],"cioc":"VAN"} +{"name":"Venezuela (Bolivarian Republic of)","topLevelDomain":[".ve"],"alpha2Code":"VE","alpha3Code":"VEN","callingCodes":["58"],"capital":"Caracas","altSpellings":["VE","Bolivarian Republic of Venezuela","República Bolivariana de Venezuela"],"region":"Americas","subregion":"South America","population":31028700,"latlng":[8.0,-66.0],"demonym":"Venezuelan","area":916445.0,"gini":44.8,"timezones":["UTC-04:00"],"borders":["BRA","COL","GUY"],"nativeName":"Venezuela","numericCode":"862","currencies":[{"code":"VEF","name":"Venezuelan bolívar","symbol":"Bs F"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Venezuela","es":"Venezuela","fr":"Venezuela","ja":"ベネズエラ・ボリバル共和国","it":"Venezuela","br":"Venezuela","pt":"Venezuela","nl":"Venezuela","hr":"Venezuela","fa":"ونزوئلا"},"flag":"https://restcountries.eu/data/ven.svg","regionalBlocs":[{"acronym":"USAN","name":"Union of South American Nations","otherAcronyms":["UNASUR","UNASUL","UZAN"],"otherNames":["Unión de Naciones Suramericanas","União de Nações Sul-Americanas","Unie van Zuid-Amerikaanse Naties","South American Union"]}],"cioc":"VEN"} +{"name":"Viet Nam","topLevelDomain":[".vn"],"alpha2Code":"VN","alpha3Code":"VNM","callingCodes":["84"],"capital":"Hanoi","altSpellings":["VN","Socialist Republic of Vietnam","Cộng hòa Xã hội chủ nghĩa Việt Nam"],"region":"Asia","subregion":"South-Eastern Asia","population":92700000,"latlng":[16.16666666,107.83333333],"demonym":"Vietnamese","area":331212.0,"gini":35.6,"timezones":["UTC+07:00"],"borders":["KHM","CHN","LAO"],"nativeName":"Việt Nam","numericCode":"704","currencies":[{"code":"VND","name":"Vietnamese đồng","symbol":"₫"}],"languages":[{"iso639_1":"vi","iso639_2":"vie","name":"Vietnamese","nativeName":"Tiếng Việt"}],"translations":{"de":"Vietnam","es":"Vietnam","fr":"Viêt Nam","ja":"ベトナム","it":"Vietnam","br":"Vietnã","pt":"Vietname","nl":"Vietnam","hr":"Vijetnam","fa":"ویتنام"},"flag":"https://restcountries.eu/data/vnm.svg","regionalBlocs":[{"acronym":"ASEAN","name":"Association of Southeast Asian Nations","otherAcronyms":[],"otherNames":[]}],"cioc":"VIE"} +{"name":"Wallis and Futuna","topLevelDomain":[".wf"],"alpha2Code":"WF","alpha3Code":"WLF","callingCodes":["681"],"capital":"Mata-Utu","altSpellings":["WF","Territory of the Wallis and Futuna Islands","Territoire des îles Wallis et Futuna"],"region":"Oceania","subregion":"Polynesia","population":11750,"latlng":[-13.3,-176.2],"demonym":"Wallis and Futuna Islander","area":142.0,"gini":null,"timezones":["UTC+12:00"],"borders":[],"nativeName":"Wallis et Futuna","numericCode":"876","currencies":[{"code":"XPF","name":"CFP franc","symbol":"Fr"}],"languages":[{"iso639_1":"fr","iso639_2":"fra","name":"French","nativeName":"français"}],"translations":{"de":"Wallis und Futuna","es":"Wallis y Futuna","fr":"Wallis-et-Futuna","ja":"ウォリス・フツナ","it":"Wallis e Futuna","br":"Wallis e Futuna","pt":"Wallis e Futuna","nl":"Wallis en Futuna","hr":"Wallis i Fortuna","fa":"والیس و فوتونا"},"flag":"https://restcountries.eu/data/wlf.svg","regionalBlocs":[],"cioc":""} +{"name":"Western Sahara","topLevelDomain":[".eh"],"alpha2Code":"EH","alpha3Code":"ESH","callingCodes":["212"],"capital":"El Aaiún","altSpellings":["EH","Taneẓroft Tutrimt"],"region":"Africa","subregion":"Northern Africa","population":510713,"latlng":[24.5,-13.0],"demonym":"Sahrawi","area":266000.0,"gini":null,"timezones":["UTC+00:00"],"borders":["DZA","MRT","MAR"],"nativeName":"الصحراء الغربية","numericCode":"732","currencies":[{"code":"MAD","name":"Moroccan dirham","symbol":"د.م."},{"code":"DZD","name":"Algerian dinar","symbol":"د.ج"}],"languages":[{"iso639_1":"es","iso639_2":"spa","name":"Spanish","nativeName":"Español"}],"translations":{"de":"Westsahara","es":"Sahara Occidental","fr":"Sahara Occidental","ja":"西サハラ","it":"Sahara Occidentale","br":"Saara Ocidental","pt":"Saara Ocidental","nl":"Westelijke Sahara","hr":"Zapadna Sahara","fa":"جمهوری دموکراتیک عربی صحرا"},"flag":"https://restcountries.eu/data/esh.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":""} +{"name":"Yemen","topLevelDomain":[".ye"],"alpha2Code":"YE","alpha3Code":"YEM","callingCodes":["967"],"capital":"Sana'a","altSpellings":["YE","Yemeni Republic","al-Jumhūriyyah al-Yamaniyyah"],"region":"Asia","subregion":"Western Asia","population":27478000,"latlng":[15.0,48.0],"demonym":"Yemeni","area":527968.0,"gini":37.7,"timezones":["UTC+03:00"],"borders":["OMN","SAU"],"nativeName":"اليَمَن","numericCode":"887","currencies":[{"code":"YER","name":"Yemeni rial","symbol":"﷼"}],"languages":[{"iso639_1":"ar","iso639_2":"ara","name":"Arabic","nativeName":"العربية"}],"translations":{"de":"Jemen","es":"Yemen","fr":"Yémen","ja":"イエメン","it":"Yemen","br":"Iêmen","pt":"Iémen","nl":"Jemen","hr":"Jemen","fa":"یمن"},"flag":"https://restcountries.eu/data/yem.svg","regionalBlocs":[{"acronym":"AL","name":"Arab League","otherAcronyms":[],"otherNames":["جامعة الدول العربية","Jāmiʻat ad-Duwal al-ʻArabīyah","League of Arab States"]}],"cioc":"YEM"} +{"name":"Zambia","topLevelDomain":[".zm"],"alpha2Code":"ZM","alpha3Code":"ZMB","callingCodes":["260"],"capital":"Lusaka","altSpellings":["ZM","Republic of Zambia"],"region":"Africa","subregion":"Eastern Africa","population":15933883,"latlng":[-15.0,30.0],"demonym":"Zambian","area":752612.0,"gini":54.6,"timezones":["UTC+02:00"],"borders":["AGO","BWA","COD","MWI","MOZ","NAM","TZA","ZWE"],"nativeName":"Zambia","numericCode":"894","currencies":[{"code":"ZMW","name":"Zambian kwacha","symbol":"ZK"}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"}],"translations":{"de":"Sambia","es":"Zambia","fr":"Zambie","ja":"ザンビア","it":"Zambia","br":"Zâmbia","pt":"Zâmbia","nl":"Zambia","hr":"Zambija","fa":"زامبیا"},"flag":"https://restcountries.eu/data/zmb.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"ZAM"} {"name":"Zimbabwe","topLevelDomain":[".zw"],"alpha2Code":"ZW","alpha3Code":"ZWE","callingCodes":["263"],"capital":"Harare","altSpellings":["ZW","Republic of Zimbabwe"],"region":"Africa","subregion":"Eastern Africa","population":14240168,"latlng":[-20.0,30.0],"demonym":"Zimbabwean","area":390757.0,"gini":null,"timezones":["UTC+02:00"],"borders":["BWA","MOZ","ZAF","ZMB"],"nativeName":"Zimbabwe","numericCode":"716","currencies":[{"code":"BWP","name":"Botswana pula","symbol":"P"},{"code":"GBP","name":"British pound","symbol":"£"},{"code":"CNY","name":"Chinese yuan","symbol":"¥"},{"code":"EUR","name":"Euro","symbol":"€"},{"code":"INR","name":"Indian rupee","symbol":"₹"},{"code":"JPY","name":"Japanese yen","symbol":"¥"},{"code":"ZAR","name":"South African rand","symbol":"Rs"},{"code":"USD","name":"United States dollar","symbol":"$"},{"code":"(none)","name":null,"symbol":null}],"languages":[{"iso639_1":"en","iso639_2":"eng","name":"English","nativeName":"English"},{"iso639_1":"sn","iso639_2":"sna","name":"Shona","nativeName":"chiShona"},{"iso639_1":"nd","iso639_2":"nde","name":"Northern Ndebele","nativeName":"isiNdebele"}],"translations":{"de":"Simbabwe","es":"Zimbabue","fr":"Zimbabwe","ja":"ジンバブエ","it":"Zimbabwe","br":"Zimbabwe","pt":"Zimbabué","nl":"Zimbabwe","hr":"Zimbabve","fa":"زیمباوه"},"flag":"https://restcountries.eu/data/zwe.svg","regionalBlocs":[{"acronym":"AU","name":"African Union","otherAcronyms":[],"otherNames":["الاتحاد الأفريقي","Union africaine","União Africana","Unión Africana","Umoja wa Afrika"]}],"cioc":"ZIM"} \ No newline at end of file diff --git a/persistence-modules/java-mongodb/README.md b/persistence-modules/java-mongodb/README.md index a58806f743..4f6aca6375 100644 --- a/persistence-modules/java-mongodb/README.md +++ b/persistence-modules/java-mongodb/README.md @@ -7,15 +7,11 @@ This module contains articles about MongoDB in Java. - [A Guide to MongoDB with Java](http://www.baeldung.com/java-mongodb) - [A Simple Tagging Implementation with MongoDB](http://www.baeldung.com/mongodb-tagging) - [MongoDB BSON Guide](https://www.baeldung.com/mongodb-bson) -- [Geospatial Support in MongoDB](https://www.baeldung.com/mongodb-geospatial-support) - [Introduction to Morphia – Java ODM for MongoDB](https://www.baeldung.com/mongodb-morphia) -- [MongoDB Aggregations Using Java](https://www.baeldung.com/java-mongodb-aggregations) - [BSON to JSON Document Conversion in Java](https://www.baeldung.com/java-convert-bson-to-json) -- [How to Check Field Existence in MongoDB?](https://www.baeldung.com/mongodb-check-field-exists) - [Get Last Inserted Document ID in MongoDB With Java Driver](https://www.baeldung.com/java-mongodb-last-inserted-id) - [Update Multiple Fields in a MongoDB Document](https://www.baeldung.com/mongodb-update-multiple-fields) - [Update Documents in MongoDB](https://www.baeldung.com/mongodb-update-documents) - [Check Collection Existence in MongoDB](https://www.baeldung.com/java-check-collection-existence-mongodb) -- [Case Insensitive Sorting in MongoDB](https://www.baeldung.com/java-mongodb-case-insensitive-sorting) - [Push and Set Operations in Same MongoDB Update](https://www.baeldung.com/java-mongodb-push-set) -- [Push Operations in MongoDB](https://www.baeldung.com/mongodb-push-operations) +- More articles: [next -->](../java-mongodb-2) \ No newline at end of file From 007271ec3bc9db6caa97225a7fef0649ef334768 Mon Sep 17 00:00:00 2001 From: Kapil Khandelwal Date: Sat, 2 Apr 2022 03:01:23 +0530 Subject: [PATCH 217/249] BAEL-5357: Retrieve a Value from MongoDB by Its Key Name (#12005) --- .../com/baeldung/mongo/RetrieveValue.java | 118 ++++++++++++++++++ .../baeldung/mongo/RetrieveValueLiveTest.java | 114 +++++++++++++++++ .../src/test/resources/travel.json | 4 + 3 files changed, 236 insertions(+) create mode 100644 persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/RetrieveValue.java create mode 100644 persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/RetrieveValueLiveTest.java create mode 100644 persistence-modules/java-mongodb-2/src/test/resources/travel.json diff --git a/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/RetrieveValue.java b/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/RetrieveValue.java new file mode 100644 index 0000000000..d163a8ca4d --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/RetrieveValue.java @@ -0,0 +1,118 @@ +package com.baeldung.mongo; + +import static com.mongodb.client.model.Aggregates.project; +import static com.mongodb.client.model.Projections.fields; + +import java.util.ArrayList; +import java.util.Arrays; + +import org.bson.Document; +import org.bson.conversions.Bson; + +import com.mongodb.BasicDBObject; +import com.mongodb.DB; +import com.mongodb.DBCollection; +import com.mongodb.DBCursor; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Projections; + +public class RetrieveValue { + + private static MongoClient mongoClient; + private static MongoDatabase database; + private static String testCollectionName; + private static String databaseName; + + public static void setUp() { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + } + + databaseName = "baeldung"; + testCollectionName = "travel"; + + } + + public static void retrieveValueUsingFind() { + + DB database = mongoClient.getDB(databaseName); + DBCollection collection = database.getCollection(testCollectionName); + + BasicDBObject queryFilter = new BasicDBObject(); + + BasicDBObject projection = new BasicDBObject(); + projection.put("passengerId", 1); + projection.put("_id", 0); + + DBCursor dbCursor = collection.find(queryFilter, projection); + while (dbCursor.hasNext()) { + System.out.println(dbCursor.next()); + } + + } + + public static void retrieveValueUsingAggregation() { + + ArrayList response = new ArrayList<>(); + + ArrayList pipeline = new ArrayList<>(Arrays.asList( + + project(fields(Projections.exclude("_id"), Projections.include("passengerId"))))); + + database = mongoClient.getDatabase(databaseName); + + database.getCollection(testCollectionName) + .aggregate(pipeline) + .allowDiskUse(true) + .into(response); + + System.out.println("response:- " + response); + + } + + public static void retrieveValueAggregationUsingDocument() { + + ArrayList response = new ArrayList<>(); + + ArrayList pipeline = new ArrayList<>(Arrays.asList(new Document("$project", new Document("passengerId", 1L)))); + + database = mongoClient.getDatabase(databaseName); + + database.getCollection(testCollectionName) + .aggregate(pipeline) + .allowDiskUse(true) + .into(response); + + System.out.println("response:- " + response); + + } + + public static void main(String args[]) { + + // + // Connect to cluster (default is localhost:27017) + // + setUp(); + + // + // Fetch the data using find query with projected fields + // + + retrieveValueUsingFind(); + + // + // Fetch the data using aggregate pipeline query with projected fields + // + + retrieveValueUsingAggregation(); + + // + // Fetch the data using aggregate pipeline document query with projected fields + // + + retrieveValueAggregationUsingDocument(); + + } +} + diff --git a/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/RetrieveValueLiveTest.java b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/RetrieveValueLiveTest.java new file mode 100644 index 0000000000..fded45e69d --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/RetrieveValueLiveTest.java @@ -0,0 +1,114 @@ +package com.baeldung.mongo; + +import static com.mongodb.client.model.Aggregates.project; +import static com.mongodb.client.model.Projections.fields; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; + +import org.bson.Document; +import org.bson.conversions.Bson; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.mongodb.BasicDBObject; +import com.mongodb.DB; +import com.mongodb.DBCollection; +import com.mongodb.DBCursor; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Projections; + +public class RetrieveValueLiveTest { + + private static MongoClient mongoClient; + private static MongoDatabase database; + private static MongoCollection collection; + private static final String DATASET_JSON = "/travel.json"; + private static DB db; + private static DBCollection dbCollection; + + @BeforeClass + public static void setup() throws IOException { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + database = mongoClient.getDatabase("baeldung"); + db = mongoClient.getDB("baeldung"); + dbCollection = db.getCollection("travel"); + collection = database.getCollection("travel"); + collection.drop(); + + InputStream is = BulkOperationLiveTest.class.getResourceAsStream(DATASET_JSON); + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + reader.lines() + .forEach(line -> collection.insertOne(Document.parse(line))); + reader.close(); + } + } + + @Test + public void givenTravelCollection_whenfetchUsingFindOperations_thenCheckingForDocument() { + + BasicDBObject queryFilter = new BasicDBObject(); + + BasicDBObject projection = new BasicDBObject(); + projection.put("passengerId", 1); + projection.put("_id", 0); + + DBCursor dbCursor = dbCollection.find(queryFilter, projection); + while (dbCursor.hasNext()) { + System.out.println(dbCursor.next()); + } + + Document travelDetail = collection.find(Filters.eq("passengerId", 145)) + .first(); + assertNotNull(travelDetail); + assertFalse(travelDetail.isEmpty()); + + } + + @Test + public void givenTravelCollection_whenfetchUsingAggregationOperations_thenCheckingForDocument() { + + ArrayList response = new ArrayList<>(); + ArrayList pipeline = new ArrayList<>(Arrays.asList(project(fields(Projections.exclude("_id"), Projections.include("passengerId"))))); + collection.aggregate(pipeline) + .allowDiskUse(true) + .into(response); + + Document travelDetail = collection.find(Filters.eq("passengerId", 145)) + .first(); + assertNotNull(travelDetail); + assertFalse(travelDetail.isEmpty()); + } + + @Test + public void givenTravelCollection_whenfetchUsingAggregationUsingDocumentOperations_thenCheckingForDocument() { + + ArrayList response = new ArrayList<>(); + ArrayList pipeline = new ArrayList<>(Arrays.asList(new Document("$project", new Document("passengerId", 1L)))); + collection.aggregate(pipeline) + .allowDiskUse(true) + .into(response); + + Document travelDetail = collection.find(Filters.eq("passengerId", 145)) + .first(); + assertNotNull(travelDetail); + assertFalse(travelDetail.isEmpty()); + } + + @AfterClass + public static void cleanUp() { + mongoClient.close(); + } +} + diff --git a/persistence-modules/java-mongodb-2/src/test/resources/travel.json b/persistence-modules/java-mongodb-2/src/test/resources/travel.json new file mode 100644 index 0000000000..43be8f3e8f --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/test/resources/travel.json @@ -0,0 +1,4 @@ +{ "passengerId":145, "passengerName":"Nathan Green", "passengerAge":25, "sourceStation":"London","destinationStation":"Birmingham","seatType":"Slepper","emailAddress":"nathongreen12@gmail.com"} +{ "passengerId":148,"passengerName":"Kevin Joseph","passengerAge":28,"sourceStation":"Manchester","destinationStation":"London","seatType":"Slepper","emailAddress":"kevin13@gmail.com"} +{"passengerId":154,"passengerName":"Sheldon burns","passengerAge":26,"sourceStation":"Cambridge","destinationStation":"Leeds","seatType":"Slepper","emailAddress":"sheldonnn160@gmail.com"} +{"passengerId":168,"passengerName":"Jack Ferguson","passengerAge":24,"sourceStation":"Cardiff","destinationStation":"Coventry","seatType":"Slepper","emailAddress":"jackfergusion9890@gmail.com"} From a170fff67a2a30d550210f1c29c35edd211bdb51 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Sat, 2 Apr 2022 11:52:07 +0100 Subject: [PATCH 218/249] [JAVA-10627] Move structurizr module to libraries-3 --- libraries-3/README.md | 3 +- libraries-3/pom.xml | 31 +++++++++++- .../structurizr/StructurizrSimple.java | 12 ++--- .../structurizr/spring/GenericComponent.java | 0 .../structurizr/spring/PaymentController.java | 0 .../structurizr/spring/PaymentRepository.java | 0 pom.xml | 2 - structurizr/README.md | 6 --- structurizr/pom.xml | 49 ------------------- structurizr/src/main/resources/logback.xml | 13 ----- 10 files changed, 37 insertions(+), 79 deletions(-) rename {structurizr => libraries-3}/src/main/java/com/baeldung/structurizr/StructurizrSimple.java (99%) rename {structurizr => libraries-3}/src/main/java/com/baeldung/structurizr/spring/GenericComponent.java (100%) rename {structurizr => libraries-3}/src/main/java/com/baeldung/structurizr/spring/PaymentController.java (100%) rename {structurizr => libraries-3}/src/main/java/com/baeldung/structurizr/spring/PaymentRepository.java (100%) delete mode 100644 structurizr/README.md delete mode 100644 structurizr/pom.xml delete mode 100644 structurizr/src/main/resources/logback.xml diff --git a/libraries-3/README.md b/libraries-3/README.md index 4041ac2d86..047d6738a1 100644 --- a/libraries-3/README.md +++ b/libraries-3/README.md @@ -16,4 +16,5 @@ Remember, for advanced libraries like [Jackson](/jackson) and [JUnit](/testing-m - [Introduction to Takes](https://www.baeldung.com/java-takes) - [Using NullAway to Avoid NullPointerExceptions](https://www.baeldung.com/java-nullaway) - [Introduction to Alibaba Arthas](https://www.baeldung.com/java-alibaba-arthas-intro) -- More articles [[<-- prev]](/libraries-2) [[next -->]](/libraries-4) +- [Introduction to Structurizr](https://www.baeldung.com/structurizr) +- More articles [[<-- prev]](../libraries-2) [[next -->]](../libraries-4) diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml index 0ff89b046f..e38aecd879 100644 --- a/libraries-3/pom.xml +++ b/libraries-3/pom.xml @@ -86,6 +86,32 @@ error_prone_core ${errorprone.version} + + + com.structurizr + structurizr-core + ${structurizr.version} + + + com.structurizr + structurizr-spring + ${structurizr.version} + + + com.structurizr + structurizr-client + ${structurizr.version} + + + com.structurizr + structurizr-analysis + ${structurizr.version} + + + com.structurizr + structurizr-plantuml + ${structurizr.version} + @@ -140,7 +166,7 @@ - -XepExcludedPaths:(.*)/test/.*|(.*)/jcabi/.* @@ -153,7 +179,7 @@ plexus-compiler-javac-errorprone 2.8 - com.google.errorprone @@ -229,6 +255,7 @@ 0.3.0 2.8 2.1.3 + 1.0.0 \ No newline at end of file diff --git a/structurizr/src/main/java/com/baeldung/structurizr/StructurizrSimple.java b/libraries-3/src/main/java/com/baeldung/structurizr/StructurizrSimple.java similarity index 99% rename from structurizr/src/main/java/com/baeldung/structurizr/StructurizrSimple.java rename to libraries-3/src/main/java/com/baeldung/structurizr/StructurizrSimple.java index 3f52ea657f..6623aeeb34 100644 --- a/structurizr/src/main/java/com/baeldung/structurizr/StructurizrSimple.java +++ b/libraries-3/src/main/java/com/baeldung/structurizr/StructurizrSimple.java @@ -1,10 +1,5 @@ package com.baeldung.structurizr; -import java.io.File; -import java.io.StringWriter; -import java.util.HashSet; -import java.util.Set; - import com.structurizr.Workspace; import com.structurizr.analysis.ComponentFinder; import com.structurizr.analysis.ReferencedTypesSupportingTypesStrategy; @@ -27,6 +22,11 @@ import com.structurizr.view.SystemContextView; import com.structurizr.view.View; import com.structurizr.view.ViewSet; +import java.io.File; +import java.io.StringWriter; +import java.util.HashSet; +import java.util.Set; + public class StructurizrSimple { public static final String PAYMENT_TERMINAL = "Payment Terminal"; @@ -51,7 +51,7 @@ public class StructurizrSimple { addStyles(workspace.getViews()); //uploadToExternal(workspace); } - + private static View findViewWithKey(ViewSet viewSet, String key) { if (key == null) { throw new IllegalArgumentException("A key must be specified."); diff --git a/structurizr/src/main/java/com/baeldung/structurizr/spring/GenericComponent.java b/libraries-3/src/main/java/com/baeldung/structurizr/spring/GenericComponent.java similarity index 100% rename from structurizr/src/main/java/com/baeldung/structurizr/spring/GenericComponent.java rename to libraries-3/src/main/java/com/baeldung/structurizr/spring/GenericComponent.java diff --git a/structurizr/src/main/java/com/baeldung/structurizr/spring/PaymentController.java b/libraries-3/src/main/java/com/baeldung/structurizr/spring/PaymentController.java similarity index 100% rename from structurizr/src/main/java/com/baeldung/structurizr/spring/PaymentController.java rename to libraries-3/src/main/java/com/baeldung/structurizr/spring/PaymentController.java diff --git a/structurizr/src/main/java/com/baeldung/structurizr/spring/PaymentRepository.java b/libraries-3/src/main/java/com/baeldung/structurizr/spring/PaymentRepository.java similarity index 100% rename from structurizr/src/main/java/com/baeldung/structurizr/spring/PaymentRepository.java rename to libraries-3/src/main/java/com/baeldung/structurizr/spring/PaymentRepository.java diff --git a/pom.xml b/pom.xml index 8d065849a2..39ffc54211 100644 --- a/pom.xml +++ b/pom.xml @@ -704,7 +704,6 @@ static-analysis stripe - structurizr struts-2 tensorflow-java @@ -1186,7 +1185,6 @@ static-analysis stripe - structurizr struts-2 tensorflow-java diff --git a/structurizr/README.md b/structurizr/README.md deleted file mode 100644 index 15331228bd..0000000000 --- a/structurizr/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## Structurizr - -This module contains articles about Structurizr - -### Relevant Articles: -- [Intro to Structurizr](https://www.baeldung.com/structurizr) diff --git a/structurizr/pom.xml b/structurizr/pom.xml deleted file mode 100644 index 85e3fc87d1..0000000000 --- a/structurizr/pom.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - 4.0.0 - structurizr - structurizr - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - com.structurizr - structurizr-core - ${structurizr.version} - - - com.structurizr - structurizr-spring - ${structurizr.version} - - - com.structurizr - structurizr-client - ${structurizr.version} - - - com.structurizr - structurizr-analysis - ${structurizr.version} - - - com.structurizr - structurizr-plantuml - ${structurizr.version} - - - - - 1.8 - 1.8 - 1.0.0 - - - \ No newline at end of file diff --git a/structurizr/src/main/resources/logback.xml b/structurizr/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/structurizr/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file From e6bbac2a78130c3ec39bbdee5ec7296166df2fd7 Mon Sep 17 00:00:00 2001 From: sampadawagde Date: Sun, 3 Apr 2022 16:54:01 +0530 Subject: [PATCH 219/249] fixed typo --- .../com/baeldung/restassured/RestAssuredAdvancedLiveTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredAdvancedLiveTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredAdvancedLiveTest.java index 23fff6a129..22d05742c6 100644 --- a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredAdvancedLiveTest.java +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredAdvancedLiveTest.java @@ -83,7 +83,7 @@ public class RestAssuredAdvancedLiveTest { @Test public void whenUseMultipleHeaders_thenOK(){ - given().header("User-Agent", "MyAppName","Accept-Charset","utf-8").when().get("/users/eugenp").then().statusCode(200); + given().headers("User-Agent", "MyAppName","Accept-Charset","utf-8").when().get("/users/eugenp").then().statusCode(200); } //======= cookie From f345f997a8679cf9c8100ad747e1f0a2c432580d Mon Sep 17 00:00:00 2001 From: KevinGilmore Date: Sun, 3 Apr 2022 08:49:33 -0500 Subject: [PATCH 220/249] BAEL-5386: add link back to article (#12015) --- core-java-modules/core-java-datetime-string/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-datetime-string/README.md b/core-java-modules/core-java-datetime-string/README.md index aac123a884..e22e807591 100644 --- a/core-java-modules/core-java-datetime-string/README.md +++ b/core-java-modules/core-java-datetime-string/README.md @@ -12,3 +12,4 @@ This module contains articles about parsing and formatting Java date and time ob - [Convert between String and Timestamp](https://www.baeldung.com/java-string-to-timestamp) - [Convert String to Date in Java](http://www.baeldung.com/java-string-to-date) - [Format a Milliseconds Duration to HH:MM:SS](https://www.baeldung.com/java-ms-to-hhmmss) +- [Format Instant to String in Java](https://www.baeldung.com/java-instant-to-string) From 5580ebcd98438652305065b81af7f6a36edf1519 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Sun, 3 Apr 2022 23:12:29 +0100 Subject: [PATCH 221/249] [JAVA-10626] Move jta module to spring-persistence --- jta/README.md | 6 -- jta/pom.xml | 55 ------------------- jta/src/main/resources/application.properties | 0 jta/src/main/resources/resources | 13 ----- jta/src/test/resources/logback-test.xml | 12 ---- .../spring-persistence-simple/.gitignore | 1 + .../spring-persistence-simple/README.md | 1 + .../spring-persistence-simple/pom.xml | 23 ++++++-- .../baeldung/jtademo/JtaDemoApplication.java | 4 +- .../com/baeldung/jtademo/dto/TransferLog.java | 0 .../jtademo/services/AuditService.java | 16 ++++-- .../jtademo/services/BankAccountService.java | 10 ++-- .../jtademo/services/TellerService.java | 0 .../baeldung/jtademo/services/TestHelper.java | 4 +- .../src/main/resources/account.sql | 0 .../src/main/resources/application.properties | 1 + .../src/main/resources/audit.sql | 0 .../com/baeldung/jtademo/JtaDemoUnitTest.java | 35 ++++++------ pom.xml | 2 - 19 files changed, 59 insertions(+), 124 deletions(-) delete mode 100644 jta/README.md delete mode 100644 jta/pom.xml delete mode 100644 jta/src/main/resources/application.properties delete mode 100644 jta/src/main/resources/resources delete mode 100644 jta/src/test/resources/logback-test.xml rename {jta => persistence-modules/spring-persistence-simple}/src/main/java/com/baeldung/jtademo/JtaDemoApplication.java (92%) rename {jta => persistence-modules/spring-persistence-simple}/src/main/java/com/baeldung/jtademo/dto/TransferLog.java (100%) rename {jta => persistence-modules/spring-persistence-simple}/src/main/java/com/baeldung/jtademo/services/AuditService.java (68%) rename {jta => persistence-modules/spring-persistence-simple}/src/main/java/com/baeldung/jtademo/services/BankAccountService.java (77%) rename {jta => persistence-modules/spring-persistence-simple}/src/main/java/com/baeldung/jtademo/services/TellerService.java (100%) rename {jta => persistence-modules/spring-persistence-simple}/src/main/java/com/baeldung/jtademo/services/TestHelper.java (94%) rename {jta => persistence-modules/spring-persistence-simple}/src/main/resources/account.sql (100%) create mode 100644 persistence-modules/spring-persistence-simple/src/main/resources/application.properties rename {jta => persistence-modules/spring-persistence-simple}/src/main/resources/audit.sql (100%) rename {jta => persistence-modules/spring-persistence-simple}/src/test/java/com/baeldung/jtademo/JtaDemoUnitTest.java (79%) diff --git a/jta/README.md b/jta/README.md deleted file mode 100644 index 202019118d..0000000000 --- a/jta/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## JTA - -This module contains articles about the Java Transaction API (JTA). - -### Relevant Articles: -- [Guide to Jakarta EE JTA](https://www.baeldung.com/jee-jta) diff --git a/jta/pom.xml b/jta/pom.xml deleted file mode 100644 index 906d28a7ea..0000000000 --- a/jta/pom.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - 4.0.0 - jta - 1.0-SNAPSHOT - jta - jar - JEE JTA demo - - - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../parent-boot-2 - - - - - - org.apache.logging.log4j - log4j-bom - ${log4j2.version} - import - pom - - - - - - - org.springframework.boot - spring-boot-starter-jta-bitronix - - - org.springframework.boot - spring-boot-starter-jdbc - - - org.springframework.boot - spring-boot-starter - - - org.hsqldb - hsqldb - - - - - 2.4.7 - 2.17.1 - - - \ No newline at end of file diff --git a/jta/src/main/resources/application.properties b/jta/src/main/resources/application.properties deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/jta/src/main/resources/resources b/jta/src/main/resources/resources deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/jta/src/main/resources/resources +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/jta/src/test/resources/logback-test.xml b/jta/src/test/resources/logback-test.xml deleted file mode 100644 index 8d4771e308..0000000000 --- a/jta/src/test/resources/logback-test.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n - - - - - - - \ No newline at end of file diff --git a/persistence-modules/spring-persistence-simple/.gitignore b/persistence-modules/spring-persistence-simple/.gitignore index 83c05e60c8..83d8f1a221 100644 --- a/persistence-modules/spring-persistence-simple/.gitignore +++ b/persistence-modules/spring-persistence-simple/.gitignore @@ -6,6 +6,7 @@ /data /src/main/webapp/WEB-INF/classes */META-INF/* +/transaction-logs # Packaged files # *.jar diff --git a/persistence-modules/spring-persistence-simple/README.md b/persistence-modules/spring-persistence-simple/README.md index f118d12f6f..77af323e31 100644 --- a/persistence-modules/spring-persistence-simple/README.md +++ b/persistence-modules/spring-persistence-simple/README.md @@ -8,6 +8,7 @@ - [Transactional Annotations: Spring vs. JTA](https://www.baeldung.com/spring-vs-jta-transactional) - [Test a Mock JNDI Datasource with Spring](https://www.baeldung.com/spring-mock-jndi-datasource) - [Detecting If a Spring Transaction Is Active](https://www.baeldung.com/spring-transaction-active) +- [Guide to Jakarta EE JTA](https://www.baeldung.com/jee-jta) ### Eclipse Config After importing the project into Eclipse, you may see the following error: diff --git a/persistence-modules/spring-persistence-simple/pom.xml b/persistence-modules/spring-persistence-simple/pom.xml index d9b832df2d..c486a95e96 100644 --- a/persistence-modules/spring-persistence-simple/pom.xml +++ b/persistence-modules/spring-persistence-simple/pom.xml @@ -51,6 +51,21 @@ spring-boot-starter ${spring-boot-starter.version} + + org.springframework.boot + spring-boot-starter-jta-atomikos + ${spring-boot-starter.version} + + + org.springframework.boot + spring-boot-starter-jdbc + ${spring-boot-starter.version} + + + org.hsqldb + hsqldb + ${hsqldb.version} + com.h2database h2 @@ -79,15 +94,13 @@ - - 5.2.4.RELEASE - 2.3.3.RELEASE - + 5.3.18 + 2.6.6 2.2 1.3 2.2.7.RELEASE - 0.23.0 + 2.5.2 \ No newline at end of file diff --git a/jta/src/main/java/com/baeldung/jtademo/JtaDemoApplication.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/JtaDemoApplication.java similarity index 92% rename from jta/src/main/java/com/baeldung/jtademo/JtaDemoApplication.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/JtaDemoApplication.java index 4d8779efe5..b2c0b7ff5a 100644 --- a/jta/src/main/java/com/baeldung/jtademo/JtaDemoApplication.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/JtaDemoApplication.java @@ -3,7 +3,7 @@ package com.baeldung.jtademo; import org.hsqldb.jdbc.pool.JDBCXADataSource; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.jta.bitronix.BitronixXADataSourceWrapper; +import org.springframework.boot.jta.atomikos.AtomikosXADataSourceWrapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -32,7 +32,7 @@ public class JtaDemoApplication { JDBCXADataSource dataSource = new JDBCXADataSource(); dataSource.setUrl(connectionUrl); dataSource.setUser("sa"); - BitronixXADataSourceWrapper wrapper = new BitronixXADataSourceWrapper(); + AtomikosXADataSourceWrapper wrapper = new AtomikosXADataSourceWrapper(); return wrapper.wrapDataSource(dataSource); } diff --git a/jta/src/main/java/com/baeldung/jtademo/dto/TransferLog.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/dto/TransferLog.java similarity index 100% rename from jta/src/main/java/com/baeldung/jtademo/dto/TransferLog.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/dto/TransferLog.java diff --git a/jta/src/main/java/com/baeldung/jtademo/services/AuditService.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/services/AuditService.java similarity index 68% rename from jta/src/main/java/com/baeldung/jtademo/services/AuditService.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/services/AuditService.java index f6810e15c8..48890e6957 100644 --- a/jta/src/main/java/com/baeldung/jtademo/services/AuditService.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/services/AuditService.java @@ -4,7 +4,6 @@ import com.baeldung.jtademo.dto.TransferLog; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.stereotype.Service; import java.math.BigDecimal; @@ -24,10 +23,17 @@ public class AuditService { } public TransferLog lastTransferLog() { - return jdbcTemplate.query("select FROM_ACCOUNT,TO_ACCOUNT,AMOUNT from AUDIT_LOG order by ID desc", (ResultSetExtractor) (rs) -> { - if (!rs.next()) - return null; - return new TransferLog(rs.getString(1), rs.getString(2), BigDecimal.valueOf(rs.getDouble(3))); + return jdbcTemplate.query( + "select FROM_ACCOUNT,TO_ACCOUNT,AMOUNT from AUDIT_LOG order by ID desc", + rs -> { + if (!rs.next()) { + return null; + } + return new TransferLog( + rs.getString(1), + rs.getString(2), + BigDecimal.valueOf(rs.getDouble(3)) + ); }); } } diff --git a/jta/src/main/java/com/baeldung/jtademo/services/BankAccountService.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/services/BankAccountService.java similarity index 77% rename from jta/src/main/java/com/baeldung/jtademo/services/BankAccountService.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/services/BankAccountService.java index 0c881edbaa..7ed06e9529 100644 --- a/jta/src/main/java/com/baeldung/jtademo/services/BankAccountService.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/services/BankAccountService.java @@ -3,7 +3,6 @@ package com.baeldung.jtademo.services; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.stereotype.Service; import java.math.BigDecimal; @@ -24,9 +23,12 @@ public class BankAccountService { } public BigDecimal balanceOf(String accountId) { - return jdbcTemplate.query("select BALANCE from ACCOUNT where ID=?", new Object[] { accountId }, (ResultSetExtractor) (rs) -> { + return jdbcTemplate.query( + "select BALANCE from ACCOUNT where ID=?", + new Object[] { accountId }, + rs -> { rs.next(); - return new BigDecimal(rs.getDouble(1)); - }); + return BigDecimal.valueOf(rs.getDouble(1)); + }); } } diff --git a/jta/src/main/java/com/baeldung/jtademo/services/TellerService.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/services/TellerService.java similarity index 100% rename from jta/src/main/java/com/baeldung/jtademo/services/TellerService.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/services/TellerService.java diff --git a/jta/src/main/java/com/baeldung/jtademo/services/TestHelper.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/services/TestHelper.java similarity index 94% rename from jta/src/main/java/com/baeldung/jtademo/services/TestHelper.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/services/TestHelper.java index c1e8e355ec..60bccd4847 100644 --- a/jta/src/main/java/com/baeldung/jtademo/services/TestHelper.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jtademo/services/TestHelper.java @@ -32,10 +32,10 @@ public class TestHelper { runScript("audit.sql", jdbcTemplateAudit.getDataSource()); } - private void runScript(String scriptName, DataSource dataSouorce) throws SQLException { + private void runScript(String scriptName, DataSource dataSource) throws SQLException { DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); Resource script = resourceLoader.getResource(scriptName); - try (Connection con = dataSouorce.getConnection()) { + try (Connection con = dataSource.getConnection()) { ScriptUtils.executeSqlScript(con, script); } } diff --git a/jta/src/main/resources/account.sql b/persistence-modules/spring-persistence-simple/src/main/resources/account.sql similarity index 100% rename from jta/src/main/resources/account.sql rename to persistence-modules/spring-persistence-simple/src/main/resources/account.sql diff --git a/persistence-modules/spring-persistence-simple/src/main/resources/application.properties b/persistence-modules/spring-persistence-simple/src/main/resources/application.properties new file mode 100644 index 0000000000..f3872aa268 --- /dev/null +++ b/persistence-modules/spring-persistence-simple/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.jta.atomikos.properties.log-base-name=atomikos-log diff --git a/jta/src/main/resources/audit.sql b/persistence-modules/spring-persistence-simple/src/main/resources/audit.sql similarity index 100% rename from jta/src/main/resources/audit.sql rename to persistence-modules/spring-persistence-simple/src/main/resources/audit.sql diff --git a/jta/src/test/java/com/baeldung/jtademo/JtaDemoUnitTest.java b/persistence-modules/spring-persistence-simple/src/test/java/com/baeldung/jtademo/JtaDemoUnitTest.java similarity index 79% rename from jta/src/test/java/com/baeldung/jtademo/JtaDemoUnitTest.java rename to persistence-modules/spring-persistence-simple/src/test/java/com/baeldung/jtademo/JtaDemoUnitTest.java index 3f6004262b..c79a42fb4b 100644 --- a/jta/src/test/java/com/baeldung/jtademo/JtaDemoUnitTest.java +++ b/persistence-modules/spring-persistence-simple/src/test/java/com/baeldung/jtademo/JtaDemoUnitTest.java @@ -5,19 +5,19 @@ import com.baeldung.jtademo.services.AuditService; import com.baeldung.jtademo.services.BankAccountService; import com.baeldung.jtademo.services.TellerService; import com.baeldung.jtademo.services.TestHelper; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import java.math.BigDecimal; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -@RunWith(SpringRunner.class) +@ExtendWith(SpringExtension.class) @SpringBootTest(classes = JtaDemoApplication.class) public class JtaDemoUnitTest { @Autowired @@ -32,31 +32,31 @@ public class JtaDemoUnitTest { @Autowired AuditService auditService; - @Before + @BeforeEach public void beforeTest() throws Exception { testHelper.runAuditDbInit(); testHelper.runAccountDbInit(); } @Test - public void givenAnnotationTx_whenNoException_thenAllCommitted() throws Exception { + public void givenAnnotationTx_whenNoException_thenAllCommitted() { tellerService.executeTransfer("a0000001", "a0000002", BigDecimal.valueOf(500)); assertThat(accountService.balanceOf("a0000001")).isEqualByComparingTo(BigDecimal.valueOf(500)); assertThat(accountService.balanceOf("a0000002")).isEqualByComparingTo(BigDecimal.valueOf(2500)); TransferLog lastTransferLog = auditService.lastTransferLog(); - assertThat(lastTransferLog).isNotNull(); + assertThat(lastTransferLog.getFromAccountId()).isEqualTo("a0000001"); assertThat(lastTransferLog.getToAccountId()).isEqualTo("a0000002"); assertThat(lastTransferLog.getAmount()).isEqualByComparingTo(BigDecimal.valueOf(500)); } @Test - public void givenAnnotationTx_whenException_thenAllRolledBack() throws Exception { - assertThatThrownBy(() -> { - tellerService.executeTransfer("a0000002", "a0000001", BigDecimal.valueOf(100000)); - }).hasMessage("Insufficient fund."); + public void givenAnnotationTx_whenException_thenAllRolledBack() { + assertThatThrownBy( + () -> tellerService.executeTransfer("a0000002", "a0000001", BigDecimal.valueOf(100000)) + ).hasMessage("Insufficient fund."); assertThat(accountService.balanceOf("a0000001")).isEqualByComparingTo(BigDecimal.valueOf(1000)); assertThat(accountService.balanceOf("a0000002")).isEqualByComparingTo(BigDecimal.valueOf(2000)); @@ -67,22 +67,21 @@ public class JtaDemoUnitTest { public void givenProgrammaticTx_whenCommit_thenAllCommitted() throws Exception { tellerService.executeTransferProgrammaticTx("a0000001", "a0000002", BigDecimal.valueOf(500)); - BigDecimal result = accountService.balanceOf("a0000001"); assertThat(accountService.balanceOf("a0000001")).isEqualByComparingTo(BigDecimal.valueOf(500)); assertThat(accountService.balanceOf("a0000002")).isEqualByComparingTo(BigDecimal.valueOf(2500)); TransferLog lastTransferLog = auditService.lastTransferLog(); - assertThat(lastTransferLog).isNotNull(); + assertThat(lastTransferLog.getFromAccountId()).isEqualTo("a0000001"); assertThat(lastTransferLog.getToAccountId()).isEqualTo("a0000002"); assertThat(lastTransferLog.getAmount()).isEqualByComparingTo(BigDecimal.valueOf(500)); } @Test - public void givenProgrammaticTx_whenRollback_thenAllRolledBack() throws Exception { - assertThatThrownBy(() -> { - tellerService.executeTransferProgrammaticTx("a0000002", "a0000001", BigDecimal.valueOf(100000)); - }).hasMessage("Insufficient fund."); + public void givenProgrammaticTx_whenRollback_thenAllRolledBack() { + assertThatThrownBy( + () -> tellerService.executeTransferProgrammaticTx("a0000002", "a0000001", BigDecimal.valueOf(100000)) + ).hasMessage("Insufficient fund."); assertThat(accountService.balanceOf("a0000001")).isEqualByComparingTo(BigDecimal.valueOf(1000)); assertThat(accountService.balanceOf("a0000002")).isEqualByComparingTo(BigDecimal.valueOf(2000)); diff --git a/pom.xml b/pom.xml index 8d065849a2..933e386084 100644 --- a/pom.xml +++ b/pom.xml @@ -476,7 +476,6 @@ json-2 json-path jsoup - jta kubernetes ksqldb @@ -964,7 +963,6 @@ json-2 json-path jsoup - jta ksqldb From dbbc6a6a1df0a3d9d1fc5a32324bc403f2d08acd Mon Sep 17 00:00:00 2001 From: priya-soni Date: Tue, 5 Apr 2022 00:14:28 +0530 Subject: [PATCH 222/249] BAEL-5329 Hide a Request Field in Swagger UI (#11992) * BAEL-5329 Hide a Request Field in Swagger UI * Updated indentation --- .../swagger/ArticleApplication.java | 30 +++++++++++ .../controller/ArticlesController.java | 28 ++++++++++ .../springboot/swagger/model/Article.java | 54 +++++++++++++++++++ .../swagger/service/ArticleService.java | 25 +++++++++ 4 files changed, 137 insertions(+) create mode 100644 spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/ArticleApplication.java create mode 100644 spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/controller/ArticlesController.java create mode 100644 spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/model/Article.java create mode 100644 spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/service/ArticleService.java diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/ArticleApplication.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/ArticleApplication.java new file mode 100644 index 0000000000..568d31e8bc --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/ArticleApplication.java @@ -0,0 +1,30 @@ +package com.baeldung.springboot.swagger; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@SpringBootApplication +@EnableSwagger2 +public class ArticleApplication { + + public static void main(String[] args) { + SpringApplication.run(ArticleApplication.class, args); + } + + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build(); + } + +} diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/controller/ArticlesController.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/controller/ArticlesController.java new file mode 100644 index 0000000000..96812e367a --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/controller/ArticlesController.java @@ -0,0 +1,28 @@ +package com.baeldung.springboot.swagger.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import com.baeldung.springboot.swagger.model.Article; +import com.baeldung.springboot.swagger.service.ArticleService; + +@RestController +@RequestMapping("/articles") +public class ArticlesController { + + @Autowired + private ArticleService articleService; + + @GetMapping("") + public List
getAllArticles() { + return articleService.getAllArticles(); + } + + @PostMapping("") + public void addArticle(@RequestBody Article article) { + articleService.addArticle(article); + } + +} diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/model/Article.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/model/Article.java new file mode 100644 index 0000000000..6512b4e1a7 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/model/Article.java @@ -0,0 +1,54 @@ +package com.baeldung.springboot.swagger.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonView; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.annotations.ApiParam; + +public class Article { + + //@JsonIgnore + //@JsonProperty(access = JsonProperty.Access.READ_ONLY) + //@ApiModelProperty(hidden = true) + //@ApiParam(hidden = true) + //@ApiModelProperty(readOnly = true) + private int id; + private String title; + private int numOfWords; + + public Article() { + } + + public Article(int id, String title) { + this.id = id; + this.title = title; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public int getNumOfWords() { + return numOfWords; + } + + public void setNumOfWords(int numOfWords) { + this.numOfWords = numOfWords; + } + +} diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/service/ArticleService.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/service/ArticleService.java new file mode 100644 index 0000000000..04f6e6c6e3 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/service/ArticleService.java @@ -0,0 +1,25 @@ +package com.baeldung.springboot.swagger.service; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.baeldung.springboot.swagger.model.Article; + +@Service +public class ArticleService { + + private List
articles = new ArrayList<>(); + + public List
getAllArticles() { + return articles; + } + + public void addArticle(Article article) { + article.setId(articles.size() + 1); + articles.add(article); + } + + +} From f8a69008e148fdad606b9caf8325ba42fae22482 Mon Sep 17 00:00:00 2001 From: ACHRAF TAITAI <43656331+achraftt@users.noreply.github.com> Date: Mon, 4 Apr 2022 20:48:45 +0200 Subject: [PATCH 223/249] BAEL-3435 - Improve article "Guide to Spring Cloud Stream with Kafka, Apache Avro and Confluent Schema Registry" (#11998) --- .../src/main/java/com/baeldung/AvroKafkaApplication.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/AvroKafkaApplication.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/AvroKafkaApplication.java index 47c060c143..b6e7729009 100644 --- a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/AvroKafkaApplication.java +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/AvroKafkaApplication.java @@ -4,11 +4,11 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.stream.annotation.EnableBinding; import org.springframework.cloud.stream.messaging.Processor; -import org.springframework.cloud.stream.schema.client.EnableSchemaRegistryClient; @SpringBootApplication @EnableBinding(Processor.class) -@EnableSchemaRegistryClient +// The @EnableSchemaRegistryClient annotation needs to be uncommented to use the Spring native method. +// @EnableSchemaRegistryClient public class AvroKafkaApplication { public static void main(String[] args) { From 9759513bf9c8718f28a4ae807adf913fd4bc3b94 Mon Sep 17 00:00:00 2001 From: Parikshit Murria Date: Mon, 4 Apr 2022 15:02:42 -0400 Subject: [PATCH 224/249] BAEL-5417 - implements vs extends (#12011) --- .../baeldung/implementsvsextends/Main.java | 60 +++++++++++++++++++ .../media/model/AudioMedia.java | 41 +++++++++++++ .../media/model/Media.java | 47 +++++++++++++++ .../media/model/VideoMedia.java | 35 +++++++++++ .../media/player/AdvancedPlayerOptions.java | 8 +++ .../media/player/MediaPlayer.java | 8 +++ .../media/player/impl/AudioMediaPlayer.java | 16 +++++ .../media/player/impl/CustomMediaPlayer.java | 17 ++++++ .../media/player/impl/MultiMediaPlayer.java | 27 +++++++++ .../media/player/impl/VideoMediaPlayer.java | 16 +++++ .../model/AudioMediaUnitTest.java | 14 +++++ .../model/VideoMediaUnitTest.java | 14 +++++ .../player/impl/AudioMediaPlayerUnitTest.java | 41 +++++++++++++ .../player/impl/MultiMediaPlayerUnitTest.java | 58 ++++++++++++++++++ .../player/impl/VideoMediaPlayerUnitTest.java | 41 +++++++++++++ 15 files changed, 443 insertions(+) create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/Main.java create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/model/AudioMedia.java create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/model/Media.java create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/model/VideoMedia.java create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/AdvancedPlayerOptions.java create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/MediaPlayer.java create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/AudioMediaPlayer.java create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/CustomMediaPlayer.java create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/MultiMediaPlayer.java create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/VideoMediaPlayer.java create mode 100644 core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/model/AudioMediaUnitTest.java create mode 100644 core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/model/VideoMediaUnitTest.java create mode 100644 core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/player/impl/AudioMediaPlayerUnitTest.java create mode 100644 core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/player/impl/MultiMediaPlayerUnitTest.java create mode 100644 core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/player/impl/VideoMediaPlayerUnitTest.java diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/Main.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/Main.java new file mode 100644 index 0000000000..0ebf3c8427 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/Main.java @@ -0,0 +1,60 @@ +package com.baeldung.implementsvsextends; + +import com.baeldung.implementsvsextends.media.model.AudioMedia; +import com.baeldung.implementsvsextends.media.model.Media; +import com.baeldung.implementsvsextends.media.model.VideoMedia; +import com.baeldung.implementsvsextends.media.player.impl.AudioMediaPlayer; +import com.baeldung.implementsvsextends.media.player.impl.CustomMediaPlayer; +import com.baeldung.implementsvsextends.media.player.impl.MultiMediaPlayer; +import com.baeldung.implementsvsextends.media.player.impl.VideoMediaPlayer; + +public class Main { + + public static void main(String[] args) { + + Media media = new Media(); + media.setId(001); + media.setTitle("Media1"); + media.setArtist("Artist001"); + + AudioMedia audioMedia = new AudioMedia(); + audioMedia.setId(101); + audioMedia.setTitle("Audio1"); + audioMedia.setArtist("Artist101"); + audioMedia.setBitrate(3500); + audioMedia.setFrequency("256kbps"); + + VideoMedia videoMedia = new VideoMedia(); + videoMedia.setId(201); + videoMedia.setTitle("Video1"); + videoMedia.setArtist("Artist201"); + videoMedia.setResolution("1024x768"); + videoMedia.setAspectRatio("16:9"); + + System.out.println(media); + System.out.println(audioMedia); + System.out.println(videoMedia); + + AudioMediaPlayer audioMediaPlayer = new AudioMediaPlayer(); + audioMediaPlayer.play(); + audioMediaPlayer.pause(); + + VideoMediaPlayer videoMediaPlayer = new VideoMediaPlayer(); + videoMediaPlayer.play(); + videoMediaPlayer.pause(); + + MultiMediaPlayer multiMediaPlayer = new MultiMediaPlayer(); + multiMediaPlayer.play(); + multiMediaPlayer.pause(); + multiMediaPlayer.seek(); + multiMediaPlayer.fastForward(); + + CustomMediaPlayer customMediaPlayer = new CustomMediaPlayer(); + customMediaPlayer.play(); + customMediaPlayer.pause(); + customMediaPlayer.setId(301); + customMediaPlayer.setTitle("Custom1"); + customMediaPlayer.setArtist("Artist301"); + System.out.println(customMediaPlayer); + } +} diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/model/AudioMedia.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/model/AudioMedia.java new file mode 100644 index 0000000000..7ede96e83a --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/model/AudioMedia.java @@ -0,0 +1,41 @@ +package com.baeldung.implementsvsextends.media.model; + +public class AudioMedia extends Media { + + private int bitrate; + + private String frequency; + + @Override + public void printTitle() { + System.out.println("AudioMedia Title"); + } + + public int getBitrate() { + return bitrate; + } + + public void setBitrate(int bitrate) { + this.bitrate = bitrate; + } + + public String getFrequency() { + return frequency; + } + + public void setFrequency(String frequency) { + this.frequency = frequency; + } + + + @Override + public String toString() { + return "AudioMedia{" + + "id=" + this.getId() + + ", title='" + this.getTitle() + '\'' + + ", artist='" + this.getArtist() + '\'' + + ", bitrate=" + bitrate + + ", frequency='" + frequency + '\'' + + "} "; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/model/Media.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/model/Media.java new file mode 100644 index 0000000000..9b17bf97c8 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/model/Media.java @@ -0,0 +1,47 @@ +package com.baeldung.implementsvsextends.media.model; + +public class Media { + + private int id; + + private String title; + + private String artist; + + public void printTitle() { + System.out.println("Media Title"); + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getArtist() { + return artist; + } + + public void setArtist(String artist) { + this.artist = artist; + } + + @Override + public String toString() { + return "Media{" + + "id=" + id + + ", title='" + title + '\'' + + ", artist='" + artist + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/model/VideoMedia.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/model/VideoMedia.java new file mode 100644 index 0000000000..f9affc81e0 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/model/VideoMedia.java @@ -0,0 +1,35 @@ +package com.baeldung.implementsvsextends.media.model; + +public class VideoMedia extends Media { + + private String resolution; + + private String aspectRatio; + + public String getResolution() { + return resolution; + } + + public void setResolution(String resolution) { + this.resolution = resolution; + } + + public String getAspectRatio() { + return aspectRatio; + } + + public void setAspectRatio(String aspectRatio) { + this.aspectRatio = aspectRatio; + } + + @Override + public String toString() { + return "VideoMedia{" + + "id=" + this.getId() + + ", title='" + this.getTitle() + '\'' + + ", artist='" + this.getArtist() + '\'' + + "resolution='" + resolution + '\'' + + ", aspectRatio='" + aspectRatio + '\'' + + "} "; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/AdvancedPlayerOptions.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/AdvancedPlayerOptions.java new file mode 100644 index 0000000000..a0e58f7d2e --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/AdvancedPlayerOptions.java @@ -0,0 +1,8 @@ +package com.baeldung.implementsvsextends.media.player; + +public interface AdvancedPlayerOptions { + + void seek(); + + void fastForward(); +} diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/MediaPlayer.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/MediaPlayer.java new file mode 100644 index 0000000000..8c5a2f9165 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/MediaPlayer.java @@ -0,0 +1,8 @@ +package com.baeldung.implementsvsextends.media.player; + +public interface MediaPlayer { + + void play(); + + void pause(); +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/AudioMediaPlayer.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/AudioMediaPlayer.java new file mode 100644 index 0000000000..cebde6f0ce --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/AudioMediaPlayer.java @@ -0,0 +1,16 @@ +package com.baeldung.implementsvsextends.media.player.impl; + +import com.baeldung.implementsvsextends.media.player.MediaPlayer; + +public class AudioMediaPlayer implements MediaPlayer { + + @Override + public void play() { + System.out.println("AudioMediaPlayer is Playing"); + } + + @Override + public void pause() { + System.out.println("AudioMediaPlayer is Paused"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/CustomMediaPlayer.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/CustomMediaPlayer.java new file mode 100644 index 0000000000..0ff01409f7 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/CustomMediaPlayer.java @@ -0,0 +1,17 @@ +package com.baeldung.implementsvsextends.media.player.impl; + +import com.baeldung.implementsvsextends.media.model.Media; +import com.baeldung.implementsvsextends.media.player.MediaPlayer; + +public class CustomMediaPlayer extends Media implements MediaPlayer { + + @Override + public void play() { + System.out.println("CustomMediaPlayer is Playing"); + } + + @Override + public void pause() { + System.out.println("CustomMediaPlayer is Paused"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/MultiMediaPlayer.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/MultiMediaPlayer.java new file mode 100644 index 0000000000..e7da8d0298 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/MultiMediaPlayer.java @@ -0,0 +1,27 @@ +package com.baeldung.implementsvsextends.media.player.impl; + +import com.baeldung.implementsvsextends.media.player.AdvancedPlayerOptions; +import com.baeldung.implementsvsextends.media.player.MediaPlayer; + +public class MultiMediaPlayer implements MediaPlayer, AdvancedPlayerOptions { + + @Override + public void play() { + System.out.println("MultiMediaPlayer is Playing"); + } + + @Override + public void pause() { + System.out.println("MultiMediaPlayer is Paused"); + } + + @Override + public void seek() { + System.out.println("MultiMediaPlayer is being seeked"); + } + + @Override + public void fastForward() { + System.out.println("MultiMediaPlayer is being fast forwarded"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/VideoMediaPlayer.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/VideoMediaPlayer.java new file mode 100644 index 0000000000..5263f21f9a --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/implementsvsextends/media/player/impl/VideoMediaPlayer.java @@ -0,0 +1,16 @@ +package com.baeldung.implementsvsextends.media.player.impl; + +import com.baeldung.implementsvsextends.media.player.MediaPlayer; + +public class VideoMediaPlayer implements MediaPlayer { + + @Override + public void play() { + System.out.println("VideoMediaPlayer is Playing"); + } + + @Override + public void pause() { + System.out.println("VideoMediaPlayer is Paused"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/model/AudioMediaUnitTest.java b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/model/AudioMediaUnitTest.java new file mode 100644 index 0000000000..e1e7b6b3f7 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/model/AudioMediaUnitTest.java @@ -0,0 +1,14 @@ +package com.baeldung.implementsvsextends.media.model; + +import org.hamcrest.CoreMatchers; +import org.junit.Assert; +import org.junit.Test; + +public class AudioMediaUnitTest { + + @Test + public void givenAudioMediaInstance_whenCheckedType_thenIsInstanceOfMedia() { + AudioMedia audioMedia = new AudioMedia(); + Assert.assertThat(audioMedia, CoreMatchers.instanceOf(Media.class)); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/model/VideoMediaUnitTest.java b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/model/VideoMediaUnitTest.java new file mode 100644 index 0000000000..677ed04c40 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/model/VideoMediaUnitTest.java @@ -0,0 +1,14 @@ +package com.baeldung.implementsvsextends.media.model; + +import org.hamcrest.CoreMatchers; +import org.junit.Assert; +import org.junit.Test; + +public class VideoMediaUnitTest { + + @Test + public void givenVideoMediaInstance_whenCheckedType_thenIsInstanceOfMedia() { + VideoMedia videoMedia = new VideoMedia(); + Assert.assertThat(videoMedia, CoreMatchers.instanceOf(Media.class)); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/player/impl/AudioMediaPlayerUnitTest.java b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/player/impl/AudioMediaPlayerUnitTest.java new file mode 100644 index 0000000000..8aee59ecd3 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/player/impl/AudioMediaPlayerUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.implementsvsextends.media.player.impl; + +import org.junit.Assert; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +public class AudioMediaPlayerUnitTest { + + private final PrintStream standardOut = System.out; + private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream(); + + @BeforeEach + public void setUp() { + System.setOut(new PrintStream(outputStreamCaptor)); + } + + @AfterEach + public void tearDown() { + System.setOut(standardOut); + } + + @Test + public void givenAudioMediaPlayer_whenPlay_thenPrintsPlayingString() { + AudioMediaPlayer audioMediaPlayer = new AudioMediaPlayer(); + audioMediaPlayer.play(); + Assert.assertEquals("AudioMediaPlayer is Playing", outputStreamCaptor.toString() + .trim()); + } + + @Test + public void givenAudioMediaPlayer_whenPause_thenPrintsPausedString() { + AudioMediaPlayer audioMediaPlayer = new AudioMediaPlayer(); + audioMediaPlayer.pause(); + Assert.assertEquals("AudioMediaPlayer is Paused", outputStreamCaptor.toString() + .trim()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/player/impl/MultiMediaPlayerUnitTest.java b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/player/impl/MultiMediaPlayerUnitTest.java new file mode 100644 index 0000000000..558f442276 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/player/impl/MultiMediaPlayerUnitTest.java @@ -0,0 +1,58 @@ +package com.baeldung.implementsvsextends.media.player.impl; + +import org.junit.Assert; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +public class MultiMediaPlayerUnitTest { + + private final PrintStream standardOut = System.out; + private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream(); + + @BeforeEach + public void setUp() { + System.setOut(new PrintStream(outputStreamCaptor)); + } + + @AfterEach + public void tearDown() { + System.setOut(standardOut); + } + + @Test + public void givenMultiMediaPlayer_whenPlay_thenPrintsPlayingString() { + MultiMediaPlayer multiMediaPlayer = new MultiMediaPlayer(); + multiMediaPlayer.play(); + Assert.assertEquals("MultiMediaPlayer is Playing", outputStreamCaptor.toString() + .trim()); + } + + @Test + public void givenMultiMediaPlayer_whenPause_thenPrintsPausedString() { + MultiMediaPlayer multiMediaPlayer = new MultiMediaPlayer(); + multiMediaPlayer.pause(); + Assert.assertEquals("MultiMediaPlayer is Paused", outputStreamCaptor.toString() + .trim()); + } + + @Test + public void givenMultiMediaPlayer_whenSeek_thenPrintsPausedString() { + MultiMediaPlayer multiMediaPlayer = new MultiMediaPlayer(); + multiMediaPlayer.seek(); + Assert.assertEquals("MultiMediaPlayer is being seeked", outputStreamCaptor.toString() + .trim()); + } + + @Test + public void givenMultiMediaPlayer_whenFastForward_thenPrintsPausedString() { + MultiMediaPlayer multiMediaPlayer = new MultiMediaPlayer(); + multiMediaPlayer.fastForward(); + Assert.assertEquals("MultiMediaPlayer is being fast forwarded", + outputStreamCaptor.toString() + .trim()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/player/impl/VideoMediaPlayerUnitTest.java b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/player/impl/VideoMediaPlayerUnitTest.java new file mode 100644 index 0000000000..b2c7511323 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/implementsvsextends/player/impl/VideoMediaPlayerUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.implementsvsextends.media.player.impl; + +import org.junit.Assert; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +public class VideoMediaPlayerUnitTest { + + private final PrintStream standardOut = System.out; + private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream(); + + @BeforeEach + public void setUp() { + System.setOut(new PrintStream(outputStreamCaptor)); + } + + @AfterEach + public void tearDown() { + System.setOut(standardOut); + } + + @Test + public void givenVideoMediaPlayer_whenPlay_thenPrintsPlayingString() { + VideoMediaPlayer videoMediaPlayer = new VideoMediaPlayer(); + videoMediaPlayer.play(); + Assert.assertEquals("VideoMediaPlayer is Playing", outputStreamCaptor.toString() + .trim()); + } + + @Test + public void givenVideoMediaPlayer_whenPause_thenPrintsPausedString() { + VideoMediaPlayer videoMediaPlayer = new VideoMediaPlayer(); + videoMediaPlayer.pause(); + Assert.assertEquals("VideoMediaPlayer is Paused", outputStreamCaptor.toString() + .trim()); + } +} \ No newline at end of file From 53421889e3c2f02ceeb36fb498f9e3bae3ba7ee2 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Mon, 4 Apr 2022 20:21:24 +0100 Subject: [PATCH 225/249] [JAVA-10431] Use Wiremock to fix intermittent test failures --- spring-cloud/pom.xml | 2 +- .../spring-cloud-netflix-feign/pom.xml | 7 +- .../feign/client/JSONPlaceHolderClient.java | 4 +- .../src/main/resources/application.properties | 2 + .../netflix/feign/ExampleTestApplication.java | 21 ------ .../netflix/feign/NetflixFeignUnitTest.java | 69 +++++++++++++++++-- 6 files changed, 72 insertions(+), 33 deletions(-) delete mode 100644 spring-cloud/spring-cloud-netflix-feign/src/test/java/com/baeldung/cloud/netflix/feign/ExampleTestApplication.java diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml index c5ebb4116a..a2c4b3509f 100644 --- a/spring-cloud/pom.xml +++ b/spring-cloud/pom.xml @@ -46,7 +46,7 @@ spring-cloud-circuit-breaker spring-cloud-eureka-self-preservation - + spring-cloud-netflix-feign spring-cloud-sentinel spring-cloud-dapr spring-cloud-docker diff --git a/spring-cloud/spring-cloud-netflix-feign/pom.xml b/spring-cloud/spring-cloud-netflix-feign/pom.xml index 8ff09d3070..f519b6316b 100644 --- a/spring-cloud/spring-cloud-netflix-feign/pom.xml +++ b/spring-cloud/spring-cloud-netflix-feign/pom.xml @@ -51,13 +51,16 @@ spring-boot-starter-test test + + org.springframework.cloud + spring-cloud-contract-wiremock + test + Camden.SR7 8.18.0 - - \ No newline at end of file diff --git a/spring-cloud/spring-cloud-netflix-feign/src/main/java/com/baeldung/cloud/netflix/feign/client/JSONPlaceHolderClient.java b/spring-cloud/spring-cloud-netflix-feign/src/main/java/com/baeldung/cloud/netflix/feign/client/JSONPlaceHolderClient.java index 80a455a4c4..454caab38c 100644 --- a/spring-cloud/spring-cloud-netflix-feign/src/main/java/com/baeldung/cloud/netflix/feign/client/JSONPlaceHolderClient.java +++ b/spring-cloud/spring-cloud-netflix-feign/src/main/java/com/baeldung/cloud/netflix/feign/client/JSONPlaceHolderClient.java @@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RequestMethod; import java.util.List; @FeignClient(value = "jplaceholder", - url = "https://jsonplaceholder.typicode.com/", + url = "${external.api.url}", configuration = ClientConfiguration.class, fallback = JSONPlaceHolderFallback.class) public interface JSONPlaceHolderClient { @@ -19,7 +19,7 @@ public interface JSONPlaceHolderClient { @RequestMapping(method = RequestMethod.GET, value = "/posts") List getPosts(); - @RequestMapping(method = RequestMethod.GET, value = "/posts/{postId}", produces = "application/json") Post getPostById(@PathVariable("postId") Long postId); + } diff --git a/spring-cloud/spring-cloud-netflix-feign/src/main/resources/application.properties b/spring-cloud/spring-cloud-netflix-feign/src/main/resources/application.properties index 5927ccb9c1..a8a29dcdd5 100644 --- a/spring-cloud/spring-cloud-netflix-feign/src/main/resources/application.properties +++ b/spring-cloud/spring-cloud-netflix-feign/src/main/resources/application.properties @@ -1,3 +1,5 @@ spring.application.name=netflix-feign logging.level.com.baeldung.cloud.netflix.feign.client=DEBUG feign.hystrix.enabled=true + +external.api.url=https://jsonplaceholder.typicode.com/ \ No newline at end of file diff --git a/spring-cloud/spring-cloud-netflix-feign/src/test/java/com/baeldung/cloud/netflix/feign/ExampleTestApplication.java b/spring-cloud/spring-cloud-netflix-feign/src/test/java/com/baeldung/cloud/netflix/feign/ExampleTestApplication.java deleted file mode 100644 index f3c8459f87..0000000000 --- a/spring-cloud/spring-cloud-netflix-feign/src/test/java/com/baeldung/cloud/netflix/feign/ExampleTestApplication.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.cloud.netflix.feign; - -import com.baeldung.cloud.netflix.feign.config.ClientConfiguration; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -@EnableAutoConfiguration -@ContextConfiguration(classes = { ClientConfiguration.class }) -public class ExampleTestApplication { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-cloud/spring-cloud-netflix-feign/src/test/java/com/baeldung/cloud/netflix/feign/NetflixFeignUnitTest.java b/spring-cloud/spring-cloud-netflix-feign/src/test/java/com/baeldung/cloud/netflix/feign/NetflixFeignUnitTest.java index 880948d6d1..9ee925201d 100644 --- a/spring-cloud/spring-cloud-netflix-feign/src/test/java/com/baeldung/cloud/netflix/feign/NetflixFeignUnitTest.java +++ b/spring-cloud/spring-cloud-netflix-feign/src/test/java/com/baeldung/cloud/netflix/feign/NetflixFeignUnitTest.java @@ -2,42 +2,97 @@ package com.baeldung.cloud.netflix.feign; import com.baeldung.cloud.netflix.feign.model.Post; import com.baeldung.cloud.netflix.feign.service.JSONPlaceHolderService; +import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder; +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.verification.LoggedRequest; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; -import static org.junit.Assert.assertFalse; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.exactly; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; @RunWith(SpringRunner.class) -@SpringBootTest +@SpringBootTest(properties = {"external.api.url=http://localhost:${wiremock.server.port}"}) +@AutoConfigureWireMock(port = 0) public class NetflixFeignUnitTest { @Autowired private JSONPlaceHolderService jsonPlaceHolderService; - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { + @Before + public void setup() { + WireMock.reset(); } @Test - public void whenGetPosts_thenListPostSizeGreaterThanZero() { + public void givenExternalApiAvailable_whenGetPosts_thenPostsReturned() { + + WireMock.stubFor(get(urlEqualTo("/posts")) + .willReturn(okJson("[{ \"userId\": 1, \"id\": 1, \"title\": \"post 1 title\", \"body\": \"post 1 body\" }, " + + "{ \"userId\": 1, \"id\": 2, \"title\": \"post 2 title\", \"body\": \"post 2 body\" }]"))); List posts = jsonPlaceHolderService.getPosts(); - assertFalse(posts.isEmpty()); + assertEquals(2, posts.size()); + verify(exactly(1), getRequestedFor(urlEqualTo("/posts"))); } @Test - public void whenGetPostWithId_thenPostExist() { + public void givenExternalApiUnavailable_whenGetPosts_thenEmpty() { + + WireMock.stubFor(get(urlEqualTo("/posts")) + .willReturn(aResponse().withStatus(500))); + + List posts = jsonPlaceHolderService.getPosts(); + + assertTrue(posts.isEmpty()); + verify(exactly(1), getRequestedFor(urlEqualTo("/posts"))); + } + + @Test + public void givenExternalApiAvailable_whenGetPostWithId_thenPostExists() { + + WireMock.stubFor(get(urlEqualTo("/posts/1")) + .willReturn(okJson("{ \"userId\": 1, \"id\": 1, \"title\": \"post 1 title\", \"body\": \"post 1 body\" }"))); Post post = jsonPlaceHolderService.getPostById(1L); assertNotNull(post); + verify(exactly(1), getRequestedFor(urlEqualTo("/posts/1"))); } + @Test + public void givenExternalApiUnavailable_whenGetPostWithId_thenNull() { + + WireMock.stubFor(get(urlEqualTo("/posts/1")) + .willReturn(aResponse().withStatus(500))); + + Post post = jsonPlaceHolderService.getPostById(1L); + + assertNull(post); + verify(exactly(1), getRequestedFor(urlEqualTo("/posts/1"))); + } + + private static ResponseDefinitionBuilder okJson(String json) { + return aResponse() + .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .withBody(json); + } } From d44c898b580753659adfb317129d46f4539202a4 Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Tue, 5 Apr 2022 08:42:27 +0500 Subject: [PATCH 226/249] Created/Updated README.md Added link back to the article: https://www.baeldung.com/java-feign-send-soap --- feign/src/main/java/com/baeldung/feign/README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 feign/src/main/java/com/baeldung/feign/README.md diff --git a/feign/src/main/java/com/baeldung/feign/README.md b/feign/src/main/java/com/baeldung/feign/README.md new file mode 100644 index 0000000000..307c8f5bb6 --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Send a SOAP Object with Feign Client](https://www.baeldung.com/java-feign-send-soap) From 1e66b4fc577d90fa94653689ede29af4dcfa445d Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Tue, 5 Apr 2022 08:46:33 +0500 Subject: [PATCH 227/249] Updated README.md Added link back to the article: https://www.baeldung.com/spring-security-map-authorities-jwt --- spring-security-modules/spring-security-oidc/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-security-modules/spring-security-oidc/README.md b/spring-security-modules/spring-security-oidc/README.md index 92ba60cad9..8bacc1310f 100644 --- a/spring-security-modules/spring-security-oidc/README.md +++ b/spring-security-modules/spring-security-oidc/README.md @@ -5,6 +5,7 @@ This module contains articles about OpenID with Spring Security ### Relevant articles - [Spring Security and OpenID Connect](https://www.baeldung.com/spring-security-openid-connect) +- [Spring Security – Map Authorities from JWT](https://www.baeldung.com/spring-security-map-authorities-jwt) ### OpenID Connect with Spring Security From 6e9cbd29d3cb2717a48ea44854675f0533ab356d Mon Sep 17 00:00:00 2001 From: Asjad J <97493880+Asjad-J@users.noreply.github.com> Date: Tue, 5 Apr 2022 08:52:44 +0500 Subject: [PATCH 228/249] Updated README.md Added link back to the article: https://www.baeldung.com/mongodb-get-value-by-key-name --- persistence-modules/java-mongodb-2/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/persistence-modules/java-mongodb-2/README.md b/persistence-modules/java-mongodb-2/README.md index c9554413f9..646917b04d 100644 --- a/persistence-modules/java-mongodb-2/README.md +++ b/persistence-modules/java-mongodb-2/README.md @@ -9,4 +9,5 @@ This module contains articles about MongoDB in Java. - [Push Operations in MongoDB](https://www.baeldung.com/mongodb-push-operations) - [Geospatial Support in MongoDB](https://www.baeldung.com/mongodb-geospatial-support) - [MongoDB Aggregations Using Java](https://www.baeldung.com/java-mongodb-aggregations) -- More articles: [[<-- prev]](../java-mongodb) \ No newline at end of file +- [Retrieve a Value from MongoDB by Its Key Name](https://www.baeldung.com/mongodb-get-value-by-key-name) +- More articles: [[<-- prev]](../java-mongodb) From bacd580822e555bb97d414a855dedb02eb04a815 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 5 Apr 2022 14:08:25 +0530 Subject: [PATCH 229/249] JAVA-8360 Split or move spring-5-security module --- .../spring-5-security/README.md | 1 - .../spring-security-web-login/README.md | 1 + .../spring-security-web-login/pom.xml | 34 ++++ .../CustomAuthenticationFilter.java | 100 +++++----- .../CustomAuthenticationToken.java | 56 +++--- ...stomUserDetailsAuthenticationProvider.java | 184 +++++++++--------- .../CustomUserDetailsService.java | 20 +- .../CustomUserDetailsServiceImpl.java | 60 +++--- .../CustomUserRepository.java | 66 +++---- .../ExtraLoginFieldsApplication.java | 0 .../PasswordEncoderConfiguration.java | 0 .../SecurityConfig.java | 126 ++++++------ .../baeldung/loginextrafieldscustom/User.java | 46 ++--- .../UserRepository.java | 14 +- .../loginextrafieldscustom/WebController.java | 102 +++++----- .../ExtraLoginFieldsApplication.java | 0 .../PasswordEncoderConfiguration.java | 0 .../SecurityConfig.java | 132 ++++++------- .../SimpleAuthenticationFilter.java | 108 +++++----- .../SimpleUserDetailsService.java | 64 +++--- .../SimpleUserRepository.java | 66 +++---- .../baeldung/loginextrafieldssimple/User.java | 42 ++-- .../UserRepository.java | 14 +- .../loginextrafieldssimple/WebController.java | 102 +++++----- .../application-extrafields.properties | 0 .../src/main/resources/application.properties | 7 + .../src/main/resources/static/css/main.css | 0 .../resources/templatesextrafields/index.html | 0 .../resources/templatesextrafields/login.html | 0 .../templatesextrafields/user/index.html | 0 ...stractExtraLoginFieldsIntegrationTest.java | 92 ++++----- .../LoginFieldsFullIntegrationTest.java | 144 +++++++------- .../LoginFieldsSimpleIntegrationTest.java | 144 +++++++------- 33 files changed, 883 insertions(+), 842 deletions(-) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationFilter.java (97%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationToken.java (97%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsAuthenticationProvider.java (97%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsService.java (97%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsServiceImpl.java (97%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserRepository.java (92%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldscustom/ExtraLoginFieldsApplication.java (100%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldscustom/PasswordEncoderConfiguration.java (100%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldscustom/SecurityConfig.java (97%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldscustom/User.java (97%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldscustom/UserRepository.java (95%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldscustom/WebController.java (96%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldssimple/ExtraLoginFieldsApplication.java (100%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldssimple/PasswordEncoderConfiguration.java (100%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldssimple/SecurityConfig.java (97%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldssimple/SimpleAuthenticationFilter.java (97%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserDetailsService.java (97%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserRepository.java (96%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldssimple/User.java (97%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldssimple/UserRepository.java (95%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/java/com/baeldung/loginextrafieldssimple/WebController.java (96%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/resources/application-extrafields.properties (100%) create mode 100644 spring-security-modules/spring-security-web-login/src/main/resources/application.properties rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/resources/static/css/main.css (100%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/resources/templatesextrafields/index.html (100%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/resources/templatesextrafields/login.html (100%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/main/resources/templatesextrafields/user/index.html (100%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/test/java/com/baeldung/loginextrafields/AbstractExtraLoginFieldsIntegrationTest.java (97%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/test/java/com/baeldung/loginextrafields/LoginFieldsFullIntegrationTest.java (97%) rename spring-security-modules/{spring-5-security => spring-security-web-login}/src/test/java/com/baeldung/loginextrafields/LoginFieldsSimpleIntegrationTest.java (97%) diff --git a/spring-security-modules/spring-5-security/README.md b/spring-security-modules/spring-5-security/README.md index bad99c22d4..dac2d0f6b8 100644 --- a/spring-security-modules/spring-5-security/README.md +++ b/spring-security-modules/spring-5-security/README.md @@ -4,7 +4,6 @@ This module contains articles about Spring Security 5 ## Relevant articles: -- [Extra Login Fields with Spring Security](https://www.baeldung.com/spring-security-extra-login-fields) - [A Custom Spring SecurityConfigurer](https://www.baeldung.com/spring-security-custom-configurer) - [New Password Storage In Spring Security 5](https://www.baeldung.com/spring-security-5-password-storage) - [Default Password Encoder in Spring Security 5](https://www.baeldung.com/spring-security-5-default-password-encoder) diff --git a/spring-security-modules/spring-security-web-login/README.md b/spring-security-modules/spring-security-web-login/README.md index 8b9c1583f6..bbef468944 100644 --- a/spring-security-modules/spring-security-web-login/README.md +++ b/spring-security-modules/spring-security-web-login/README.md @@ -12,6 +12,7 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com - [Spring Security – Customize the 403 Forbidden/Access Denied Page](https://www.baeldung.com/spring-security-custom-access-denied-page) - [Spring Security – Redirect to the Previous URL After Login](https://www.baeldung.com/spring-security-redirect-login) - [Spring Security Custom AuthenticationFailureHandler](https://www.baeldung.com/spring-security-custom-authentication-failure-handler) +- [Extra Login Fields with Spring Security](https://www.baeldung.com/spring-security-extra-login-fields) ### Build the Project ``` diff --git a/spring-security-modules/spring-security-web-login/pom.xml b/spring-security-modules/spring-security-web-login/pom.xml index 3d9947c519..346338cbcd 100644 --- a/spring-security-modules/spring-security-web-login/pom.xml +++ b/spring-security-modules/spring-security-web-login/pom.xml @@ -16,6 +16,26 @@ + + org.springframework.boot + spring-boot-starter-web + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-security + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-thymeleaf + ${spring-boot.version} + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity5 + ${thymeleaf-extras-springsecurity5.version} + org.springframework.security @@ -98,6 +118,12 @@ runtime + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + test + org.springframework spring-test @@ -110,6 +136,11 @@ ${spring-security.version} test + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + @@ -153,6 +184,9 @@ 1.9.9 + 2.6.4 + 3.0.4.RELEASE + 3.11 \ No newline at end of file diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationFilter.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationFilter.java similarity index 97% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationFilter.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationFilter.java index 2a5c5f0368..9e7ecdb2cc 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationFilter.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationFilter.java @@ -1,50 +1,50 @@ -package com.baeldung.loginextrafieldscustom; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.authentication.AuthenticationServiceException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; - -public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter { - - public static final String SPRING_SECURITY_FORM_DOMAIN_KEY = "domain"; - - @Override - public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) - throws AuthenticationException { - - if (!request.getMethod().equals("POST")) { - throw new AuthenticationServiceException("Authentication method not supported: " - + request.getMethod()); - } - - CustomAuthenticationToken authRequest = getAuthRequest(request); - setDetails(request, authRequest); - return this.getAuthenticationManager().authenticate(authRequest); - } - - private CustomAuthenticationToken getAuthRequest(HttpServletRequest request) { - String username = obtainUsername(request); - String password = obtainPassword(request); - String domain = obtainDomain(request); - - if (username == null) { - username = ""; - } - if (password == null) { - password = ""; - } - if (domain == null) { - domain = ""; - } - - return new CustomAuthenticationToken(username, password, domain); - } - - private String obtainDomain(HttpServletRequest request) { - return request.getParameter(SPRING_SECURITY_FORM_DOMAIN_KEY); - } -} +package com.baeldung.loginextrafieldscustom; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter { + + public static final String SPRING_SECURITY_FORM_DOMAIN_KEY = "domain"; + + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) + throws AuthenticationException { + + if (!request.getMethod().equals("POST")) { + throw new AuthenticationServiceException("Authentication method not supported: " + + request.getMethod()); + } + + CustomAuthenticationToken authRequest = getAuthRequest(request); + setDetails(request, authRequest); + return this.getAuthenticationManager().authenticate(authRequest); + } + + private CustomAuthenticationToken getAuthRequest(HttpServletRequest request) { + String username = obtainUsername(request); + String password = obtainPassword(request); + String domain = obtainDomain(request); + + if (username == null) { + username = ""; + } + if (password == null) { + password = ""; + } + if (domain == null) { + domain = ""; + } + + return new CustomAuthenticationToken(username, password, domain); + } + + private String obtainDomain(HttpServletRequest request) { + return request.getParameter(SPRING_SECURITY_FORM_DOMAIN_KEY); + } +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationToken.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationToken.java similarity index 97% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationToken.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationToken.java index 50995169a1..fd7624d965 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationToken.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomAuthenticationToken.java @@ -1,28 +1,28 @@ -package com.baeldung.loginextrafieldscustom; - -import java.util.Collection; - -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.GrantedAuthority; - -public class CustomAuthenticationToken extends UsernamePasswordAuthenticationToken { - - private String domain; - - public CustomAuthenticationToken(Object principal, Object credentials, String domain) { - super(principal, credentials); - this.domain = domain; - super.setAuthenticated(false); - } - - public CustomAuthenticationToken(Object principal, Object credentials, String domain, - Collection authorities) { - super(principal, credentials, authorities); - this.domain = domain; - super.setAuthenticated(true); // must use super, as we override - } - - public String getDomain() { - return this.domain; - } -} +package com.baeldung.loginextrafieldscustom; + +import java.util.Collection; + +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; + +public class CustomAuthenticationToken extends UsernamePasswordAuthenticationToken { + + private String domain; + + public CustomAuthenticationToken(Object principal, Object credentials, String domain) { + super(principal, credentials); + this.domain = domain; + super.setAuthenticated(false); + } + + public CustomAuthenticationToken(Object principal, Object credentials, String domain, + Collection authorities) { + super(principal, credentials, authorities); + this.domain = domain; + super.setAuthenticated(true); // must use super, as we override + } + + public String getDomain() { + return this.domain; + } +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsAuthenticationProvider.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsAuthenticationProvider.java similarity index 97% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsAuthenticationProvider.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsAuthenticationProvider.java index 693900d843..85d768aaab 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsAuthenticationProvider.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsAuthenticationProvider.java @@ -1,92 +1,92 @@ -package com.baeldung.loginextrafieldscustom; - -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.InternalAuthenticationServiceException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.util.Assert; - -public class CustomUserDetailsAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { - - /** - * The plaintext password used to perform - * PasswordEncoder#matches(CharSequence, String)} on when the user is - * not found to avoid SEC-2056. - */ - private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword"; - - private PasswordEncoder passwordEncoder; - private CustomUserDetailsService userDetailsService; - - /** - * The password used to perform - * {@link PasswordEncoder#matches(CharSequence, String)} on when the user is - * not found to avoid SEC-2056. This is necessary, because some - * {@link PasswordEncoder} implementations will short circuit if the password is not - * in a valid format. - */ - private String userNotFoundEncodedPassword; - - public CustomUserDetailsAuthenticationProvider(PasswordEncoder passwordEncoder, CustomUserDetailsService userDetailsService) { - this.passwordEncoder = passwordEncoder; - this.userDetailsService = userDetailsService; - } - - @Override - protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) - throws AuthenticationException { - - if (authentication.getCredentials() == null) { - logger.debug("Authentication failed: no credentials provided"); - throw new BadCredentialsException( - messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); - } - - String presentedPassword = authentication.getCredentials() - .toString(); - - if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) { - logger.debug("Authentication failed: password does not match stored value"); - throw new BadCredentialsException( - messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); - } - } - - @Override - protected void doAfterPropertiesSet() throws Exception { - Assert.notNull(this.userDetailsService, "A UserDetailsService must be set"); - this.userNotFoundEncodedPassword = this.passwordEncoder.encode(USER_NOT_FOUND_PASSWORD); - } - - @Override - protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) - throws AuthenticationException { - CustomAuthenticationToken auth = (CustomAuthenticationToken) authentication; - UserDetails loadedUser; - - try { - loadedUser = this.userDetailsService.loadUserByUsernameAndDomain(auth.getPrincipal() - .toString(), auth.getDomain()); - } catch (UsernameNotFoundException notFound) { - if (authentication.getCredentials() != null) { - String presentedPassword = authentication.getCredentials() - .toString(); - passwordEncoder.matches(presentedPassword, userNotFoundEncodedPassword); - } - throw notFound; - } catch (Exception repositoryProblem) { - throw new InternalAuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem); - } - - if (loadedUser == null) { - throw new InternalAuthenticationServiceException("UserDetailsService returned null, " - + "which is an interface contract violation"); - } - return loadedUser; - } - -} +package com.baeldung.loginextrafieldscustom; + +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.InternalAuthenticationServiceException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.util.Assert; + +public class CustomUserDetailsAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { + + /** + * The plaintext password used to perform + * PasswordEncoder#matches(CharSequence, String)} on when the user is + * not found to avoid SEC-2056. + */ + private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword"; + + private PasswordEncoder passwordEncoder; + private CustomUserDetailsService userDetailsService; + + /** + * The password used to perform + * {@link PasswordEncoder#matches(CharSequence, String)} on when the user is + * not found to avoid SEC-2056. This is necessary, because some + * {@link PasswordEncoder} implementations will short circuit if the password is not + * in a valid format. + */ + private String userNotFoundEncodedPassword; + + public CustomUserDetailsAuthenticationProvider(PasswordEncoder passwordEncoder, CustomUserDetailsService userDetailsService) { + this.passwordEncoder = passwordEncoder; + this.userDetailsService = userDetailsService; + } + + @Override + protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) + throws AuthenticationException { + + if (authentication.getCredentials() == null) { + logger.debug("Authentication failed: no credentials provided"); + throw new BadCredentialsException( + messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); + } + + String presentedPassword = authentication.getCredentials() + .toString(); + + if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) { + logger.debug("Authentication failed: password does not match stored value"); + throw new BadCredentialsException( + messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); + } + } + + @Override + protected void doAfterPropertiesSet() throws Exception { + Assert.notNull(this.userDetailsService, "A UserDetailsService must be set"); + this.userNotFoundEncodedPassword = this.passwordEncoder.encode(USER_NOT_FOUND_PASSWORD); + } + + @Override + protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) + throws AuthenticationException { + CustomAuthenticationToken auth = (CustomAuthenticationToken) authentication; + UserDetails loadedUser; + + try { + loadedUser = this.userDetailsService.loadUserByUsernameAndDomain(auth.getPrincipal() + .toString(), auth.getDomain()); + } catch (UsernameNotFoundException notFound) { + if (authentication.getCredentials() != null) { + String presentedPassword = authentication.getCredentials() + .toString(); + passwordEncoder.matches(presentedPassword, userNotFoundEncodedPassword); + } + throw notFound; + } catch (Exception repositoryProblem) { + throw new InternalAuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem); + } + + if (loadedUser == null) { + throw new InternalAuthenticationServiceException("UserDetailsService returned null, " + + "which is an interface contract violation"); + } + return loadedUser; + } + +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsService.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsService.java similarity index 97% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsService.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsService.java index 358129173d..fa690edade 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsService.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsService.java @@ -1,10 +1,10 @@ -package com.baeldung.loginextrafieldscustom; - -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UsernameNotFoundException; - -public interface CustomUserDetailsService { - - UserDetails loadUserByUsernameAndDomain(String username, String domain) throws UsernameNotFoundException; - -} +package com.baeldung.loginextrafieldscustom; + +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +public interface CustomUserDetailsService { + + UserDetails loadUserByUsernameAndDomain(String username, String domain) throws UsernameNotFoundException; + +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsServiceImpl.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsServiceImpl.java similarity index 97% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsServiceImpl.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsServiceImpl.java index ea979e2fab..056bd47b20 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsServiceImpl.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserDetailsServiceImpl.java @@ -1,30 +1,30 @@ -package com.baeldung.loginextrafieldscustom; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Service; - -@Service("userDetailsService") -public class CustomUserDetailsServiceImpl implements CustomUserDetailsService { - - private UserRepository userRepository; - - public CustomUserDetailsServiceImpl(UserRepository userRepository) { - this.userRepository = userRepository; - } - - @Override - public UserDetails loadUserByUsernameAndDomain(String username, String domain) throws UsernameNotFoundException { - if (StringUtils.isAnyBlank(username, domain)) { - throw new UsernameNotFoundException("Username and domain must be provided"); - } - User user = userRepository.findUser(username, domain); - if (user == null) { - throw new UsernameNotFoundException( - String.format("Username not found for domain, username=%s, domain=%s", - username, domain)); - } - return user; - } -} +package com.baeldung.loginextrafieldscustom; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +@Service("userDetailsService") +public class CustomUserDetailsServiceImpl implements CustomUserDetailsService { + + private UserRepository userRepository; + + public CustomUserDetailsServiceImpl(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @Override + public UserDetails loadUserByUsernameAndDomain(String username, String domain) throws UsernameNotFoundException { + if (StringUtils.isAnyBlank(username, domain)) { + throw new UsernameNotFoundException("Username and domain must be provided"); + } + User user = userRepository.findUser(username, domain); + if (user == null) { + throw new UsernameNotFoundException( + String.format("Username not found for domain, username=%s, domain=%s", + username, domain)); + } + return user; + } +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserRepository.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserRepository.java similarity index 92% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserRepository.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserRepository.java index effc750940..fbc2851dc1 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserRepository.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/CustomUserRepository.java @@ -1,33 +1,33 @@ -package com.baeldung.loginextrafieldscustom; - -import java.util.ArrayList; -import java.util.Collection; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Repository; - -@Repository("userRepository") -public class CustomUserRepository implements UserRepository { - - private PasswordEncoder passwordEncoder; - - public CustomUserRepository(PasswordEncoder passwordEncoder) { - this.passwordEncoder = passwordEncoder; - } - - @Override - public User findUser(String username, String domain) { - if (StringUtils.isAnyBlank(username, domain)) { - return null; - } else { - Collection authorities = new ArrayList<>(); - User user = new User(username, domain, - passwordEncoder.encode("secret"), true, - true, true, true, authorities); - return user; - } - } - -} +package com.baeldung.loginextrafieldscustom; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Repository; + +@Repository("userRepository") +public class CustomUserRepository implements UserRepository { + + private PasswordEncoder passwordEncoder; + + public CustomUserRepository(PasswordEncoder passwordEncoder) { + this.passwordEncoder = passwordEncoder; + } + + @Override + public User findUser(String username, String domain) { + if (StringUtils.isAnyBlank(username, domain)) { + return null; + } else { + Collection authorities = new ArrayList<>(); + User user = new User(username, domain, + passwordEncoder.encode("secret"), true, + true, true, true, authorities); + return user; + } + } + +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/ExtraLoginFieldsApplication.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/ExtraLoginFieldsApplication.java similarity index 100% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/ExtraLoginFieldsApplication.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/ExtraLoginFieldsApplication.java diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/PasswordEncoderConfiguration.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/PasswordEncoderConfiguration.java similarity index 100% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/PasswordEncoderConfiguration.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/PasswordEncoderConfiguration.java diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/SecurityConfig.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/SecurityConfig.java similarity index 97% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/SecurityConfig.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/SecurityConfig.java index e7b56e5763..d20b7a10dc 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/SecurityConfig.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/SecurityConfig.java @@ -1,63 +1,63 @@ -package com.baeldung.loginextrafieldscustom; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.PropertySource; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; - -@EnableWebSecurity -@PropertySource("classpath:/application-extrafields.properties") -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Autowired - private CustomUserDetailsService userDetailsService; - - @Autowired - private PasswordEncoder passwordEncoder; - - @Override - protected void configure(HttpSecurity http) throws Exception { - - http - .addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class) - .authorizeRequests() - .antMatchers("/css/**", "/index").permitAll() - .antMatchers("/user/**").authenticated() - .and() - .formLogin().loginPage("/login") - .and() - .logout() - .logoutUrl("/logout"); - } - - public CustomAuthenticationFilter authenticationFilter() throws Exception { - CustomAuthenticationFilter filter = new CustomAuthenticationFilter(); - filter.setAuthenticationManager(authenticationManagerBean()); - filter.setAuthenticationFailureHandler(failureHandler()); - return filter; - } - - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - auth.authenticationProvider(authProvider()); - } - - public AuthenticationProvider authProvider() { - CustomUserDetailsAuthenticationProvider provider - = new CustomUserDetailsAuthenticationProvider(passwordEncoder, userDetailsService); - return provider; - } - - public SimpleUrlAuthenticationFailureHandler failureHandler() { - return new SimpleUrlAuthenticationFailureHandler("/login?error=true"); - } - -} +package com.baeldung.loginextrafieldscustom; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.PropertySource; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +@EnableWebSecurity +@PropertySource("classpath:/application-extrafields.properties") +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private CustomUserDetailsService userDetailsService; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Override + protected void configure(HttpSecurity http) throws Exception { + + http + .addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class) + .authorizeRequests() + .antMatchers("/css/**", "/index").permitAll() + .antMatchers("/user/**").authenticated() + .and() + .formLogin().loginPage("/login") + .and() + .logout() + .logoutUrl("/logout"); + } + + public CustomAuthenticationFilter authenticationFilter() throws Exception { + CustomAuthenticationFilter filter = new CustomAuthenticationFilter(); + filter.setAuthenticationManager(authenticationManagerBean()); + filter.setAuthenticationFailureHandler(failureHandler()); + return filter; + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.authenticationProvider(authProvider()); + } + + public AuthenticationProvider authProvider() { + CustomUserDetailsAuthenticationProvider provider + = new CustomUserDetailsAuthenticationProvider(passwordEncoder, userDetailsService); + return provider; + } + + public SimpleUrlAuthenticationFailureHandler failureHandler() { + return new SimpleUrlAuthenticationFailureHandler("/login?error=true"); + } + +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/User.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/User.java similarity index 97% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/User.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/User.java index aa03f15b6a..be4730592b 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/User.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/User.java @@ -1,23 +1,23 @@ -package com.baeldung.loginextrafieldscustom; - -import java.util.Collection; - -import org.springframework.security.core.GrantedAuthority; - -public class User extends org.springframework.security.core.userdetails.User { - - private static final long serialVersionUID = 1L; - - private String domain; - - public User(String username, String domain, String password, boolean enabled, - boolean accountNonExpired, boolean credentialsNonExpired, - boolean accountNonLocked, Collection authorities) { - super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); - this.domain = domain; - } - - public String getDomain() { - return domain; - } -} +package com.baeldung.loginextrafieldscustom; + +import java.util.Collection; + +import org.springframework.security.core.GrantedAuthority; + +public class User extends org.springframework.security.core.userdetails.User { + + private static final long serialVersionUID = 1L; + + private String domain; + + public User(String username, String domain, String password, boolean enabled, + boolean accountNonExpired, boolean credentialsNonExpired, + boolean accountNonLocked, Collection authorities) { + super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); + this.domain = domain; + } + + public String getDomain() { + return domain; + } +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/UserRepository.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/UserRepository.java similarity index 95% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/UserRepository.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/UserRepository.java index e2358e055b..a6dea786f0 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/UserRepository.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/UserRepository.java @@ -1,7 +1,7 @@ -package com.baeldung.loginextrafieldscustom; - -public interface UserRepository { - - public User findUser(String username, String domain); - -} +package com.baeldung.loginextrafieldscustom; + +public interface UserRepository { + + public User findUser(String username, String domain); + +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/WebController.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/WebController.java similarity index 96% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/WebController.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/WebController.java index b5e0b511ac..4f0d4013ff 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldscustom/WebController.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldscustom/WebController.java @@ -1,51 +1,51 @@ -package com.baeldung.loginextrafieldscustom; - -import java.util.Optional; - -import org.springframework.security.authentication.AnonymousAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; - -@Controller -public class WebController { - - @RequestMapping("/") - public String root() { - return "redirect:/index"; - } - - @RequestMapping("/index") - public String index(Model model) { - getDomain().ifPresent(d -> { - model.addAttribute("domain", d); - }); - return "index"; - } - - @RequestMapping("/user/index") - public String userIndex(Model model) { - getDomain().ifPresent(d -> { - model.addAttribute("domain", d); - }); - return "user/index"; - } - - @RequestMapping("/login") - public String login() { - return "login"; - } - - private Optional getDomain() { - Authentication auth = SecurityContextHolder.getContext() - .getAuthentication(); - String domain = null; - if (auth != null && !auth.getClass().equals(AnonymousAuthenticationToken.class)) { - User user = (User) auth.getPrincipal(); - domain = user.getDomain(); - } - return Optional.ofNullable(domain); - } -} +package com.baeldung.loginextrafieldscustom; + +import java.util.Optional; + +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class WebController { + + @RequestMapping("/") + public String root() { + return "redirect:/index"; + } + + @RequestMapping("/index") + public String index(Model model) { + getDomain().ifPresent(d -> { + model.addAttribute("domain", d); + }); + return "index"; + } + + @RequestMapping("/user/index") + public String userIndex(Model model) { + getDomain().ifPresent(d -> { + model.addAttribute("domain", d); + }); + return "user/index"; + } + + @RequestMapping("/login") + public String login() { + return "login"; + } + + private Optional getDomain() { + Authentication auth = SecurityContextHolder.getContext() + .getAuthentication(); + String domain = null; + if (auth != null && !auth.getClass().equals(AnonymousAuthenticationToken.class)) { + User user = (User) auth.getPrincipal(); + domain = user.getDomain(); + } + return Optional.ofNullable(domain); + } +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/ExtraLoginFieldsApplication.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/ExtraLoginFieldsApplication.java similarity index 100% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/ExtraLoginFieldsApplication.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/ExtraLoginFieldsApplication.java diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/PasswordEncoderConfiguration.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/PasswordEncoderConfiguration.java similarity index 100% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/PasswordEncoderConfiguration.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/PasswordEncoderConfiguration.java diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/SecurityConfig.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/SecurityConfig.java similarity index 97% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/SecurityConfig.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/SecurityConfig.java index 6d3d51ad30..2989a4bbc6 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/SecurityConfig.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/SecurityConfig.java @@ -1,66 +1,66 @@ -package com.baeldung.loginextrafieldssimple; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.PropertySource; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.authentication.dao.DaoAuthenticationProvider; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; - -@EnableWebSecurity -@PropertySource("classpath:/application-extrafields.properties") -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Autowired - private UserDetailsService userDetailsService; - - @Autowired - private PasswordEncoder passwordEncoder; - - @Override - protected void configure(HttpSecurity http) throws Exception { - - http - .addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class) - .authorizeRequests() - .antMatchers("/css/**", "/index").permitAll() - .antMatchers("/user/**").authenticated() - .and() - .formLogin().loginPage("/login") - .and() - .logout() - .logoutUrl("/logout"); - } - - public SimpleAuthenticationFilter authenticationFilter() throws Exception { - SimpleAuthenticationFilter filter = new SimpleAuthenticationFilter(); - filter.setAuthenticationManager(authenticationManagerBean()); - filter.setAuthenticationFailureHandler(failureHandler()); - return filter; - } - - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - auth.authenticationProvider(authProvider()); - } - - public AuthenticationProvider authProvider() { - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setUserDetailsService(userDetailsService); - provider.setPasswordEncoder(passwordEncoder); - return provider; - } - - public SimpleUrlAuthenticationFailureHandler failureHandler() { - return new SimpleUrlAuthenticationFailureHandler("/login?error=true"); - } - -} +package com.baeldung.loginextrafieldssimple; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.PropertySource; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +@EnableWebSecurity +@PropertySource("classpath:/application-extrafields.properties") +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private UserDetailsService userDetailsService; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Override + protected void configure(HttpSecurity http) throws Exception { + + http + .addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class) + .authorizeRequests() + .antMatchers("/css/**", "/index").permitAll() + .antMatchers("/user/**").authenticated() + .and() + .formLogin().loginPage("/login") + .and() + .logout() + .logoutUrl("/logout"); + } + + public SimpleAuthenticationFilter authenticationFilter() throws Exception { + SimpleAuthenticationFilter filter = new SimpleAuthenticationFilter(); + filter.setAuthenticationManager(authenticationManagerBean()); + filter.setAuthenticationFailureHandler(failureHandler()); + return filter; + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.authenticationProvider(authProvider()); + } + + public AuthenticationProvider authProvider() { + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setUserDetailsService(userDetailsService); + provider.setPasswordEncoder(passwordEncoder); + return provider; + } + + public SimpleUrlAuthenticationFailureHandler failureHandler() { + return new SimpleUrlAuthenticationFailureHandler("/login?error=true"); + } + +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/SimpleAuthenticationFilter.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/SimpleAuthenticationFilter.java similarity index 97% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/SimpleAuthenticationFilter.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/SimpleAuthenticationFilter.java index 9dcb524157..7e21e1b82e 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/SimpleAuthenticationFilter.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/SimpleAuthenticationFilter.java @@ -1,54 +1,54 @@ -package com.baeldung.loginextrafieldssimple; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.authentication.AuthenticationServiceException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; - -public class SimpleAuthenticationFilter extends UsernamePasswordAuthenticationFilter { - - public static final String SPRING_SECURITY_FORM_DOMAIN_KEY = "domain"; - - @Override - public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) - throws AuthenticationException { - - if (!request.getMethod() - .equals("POST")) { - throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); - } - - UsernamePasswordAuthenticationToken authRequest = getAuthRequest(request); - setDetails(request, authRequest); - return this.getAuthenticationManager() - .authenticate(authRequest); - } - - private UsernamePasswordAuthenticationToken getAuthRequest(HttpServletRequest request) { - String username = obtainUsername(request); - String password = obtainPassword(request); - String domain = obtainDomain(request); - - if (username == null) { - username = ""; - } - if (password == null) { - password = ""; - } - if (domain == null) { - domain = ""; - } - - String usernameDomain = String.format("%s%s%s", username.trim(), - String.valueOf(Character.LINE_SEPARATOR), domain); - return new UsernamePasswordAuthenticationToken(usernameDomain, password); - } - - private String obtainDomain(HttpServletRequest request) { - return request.getParameter(SPRING_SECURITY_FORM_DOMAIN_KEY); - } -} +package com.baeldung.loginextrafieldssimple; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +public class SimpleAuthenticationFilter extends UsernamePasswordAuthenticationFilter { + + public static final String SPRING_SECURITY_FORM_DOMAIN_KEY = "domain"; + + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) + throws AuthenticationException { + + if (!request.getMethod() + .equals("POST")) { + throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); + } + + UsernamePasswordAuthenticationToken authRequest = getAuthRequest(request); + setDetails(request, authRequest); + return this.getAuthenticationManager() + .authenticate(authRequest); + } + + private UsernamePasswordAuthenticationToken getAuthRequest(HttpServletRequest request) { + String username = obtainUsername(request); + String password = obtainPassword(request); + String domain = obtainDomain(request); + + if (username == null) { + username = ""; + } + if (password == null) { + password = ""; + } + if (domain == null) { + domain = ""; + } + + String usernameDomain = String.format("%s%s%s", username.trim(), + String.valueOf(Character.LINE_SEPARATOR), domain); + return new UsernamePasswordAuthenticationToken(usernameDomain, password); + } + + private String obtainDomain(HttpServletRequest request) { + return request.getParameter(SPRING_SECURITY_FORM_DOMAIN_KEY); + } +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserDetailsService.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserDetailsService.java similarity index 97% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserDetailsService.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserDetailsService.java index 2fad50ad01..25fc5c3572 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserDetailsService.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserDetailsService.java @@ -1,32 +1,32 @@ -package com.baeldung.loginextrafieldssimple; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Service; - -@Service("userDetailsService") -public class SimpleUserDetailsService implements UserDetailsService { - - private UserRepository userRepository; - - public SimpleUserDetailsService(UserRepository userRepository) { - this.userRepository = userRepository; - } - - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - String[] usernameAndDomain = StringUtils.split(username, String.valueOf(Character.LINE_SEPARATOR)); - if (usernameAndDomain == null || usernameAndDomain.length != 2) { - throw new UsernameNotFoundException("Username and domain must be provided"); - } - User user = userRepository.findUser(usernameAndDomain[0], usernameAndDomain[1]); - if (user == null) { - throw new UsernameNotFoundException( - String.format("Username not found for domain, username=%s, domain=%s", - usernameAndDomain[0], usernameAndDomain[1])); - } - return user; - } -} +package com.baeldung.loginextrafieldssimple; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +@Service("userDetailsService") +public class SimpleUserDetailsService implements UserDetailsService { + + private UserRepository userRepository; + + public SimpleUserDetailsService(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + String[] usernameAndDomain = StringUtils.split(username, String.valueOf(Character.LINE_SEPARATOR)); + if (usernameAndDomain == null || usernameAndDomain.length != 2) { + throw new UsernameNotFoundException("Username and domain must be provided"); + } + User user = userRepository.findUser(usernameAndDomain[0], usernameAndDomain[1]); + if (user == null) { + throw new UsernameNotFoundException( + String.format("Username not found for domain, username=%s, domain=%s", + usernameAndDomain[0], usernameAndDomain[1])); + } + return user; + } +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserRepository.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserRepository.java similarity index 96% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserRepository.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserRepository.java index 44929c6189..4a597c7146 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserRepository.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/SimpleUserRepository.java @@ -1,33 +1,33 @@ -package com.baeldung.loginextrafieldssimple; - -import java.util.ArrayList; -import java.util.Collection; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Repository; - -@Repository("userRepository") -public class SimpleUserRepository implements UserRepository { - - private PasswordEncoder passwordEncoder; - - public SimpleUserRepository(PasswordEncoder passwordEncoder) { - this.passwordEncoder = passwordEncoder; - } - - @Override - public User findUser(String username, String domain) { - if (StringUtils.isAnyBlank(username, domain)) { - return null; - } else { - Collection authorities = new ArrayList<>(); - User user = new User(username, domain, - passwordEncoder.encode("secret"), true, - true, true, true, authorities); - return user; - } - } - -} +package com.baeldung.loginextrafieldssimple; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Repository; + +@Repository("userRepository") +public class SimpleUserRepository implements UserRepository { + + private PasswordEncoder passwordEncoder; + + public SimpleUserRepository(PasswordEncoder passwordEncoder) { + this.passwordEncoder = passwordEncoder; + } + + @Override + public User findUser(String username, String domain) { + if (StringUtils.isAnyBlank(username, domain)) { + return null; + } else { + Collection authorities = new ArrayList<>(); + User user = new User(username, domain, + passwordEncoder.encode("secret"), true, + true, true, true, authorities); + return user; + } + } + +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/User.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/User.java similarity index 97% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/User.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/User.java index b76da65638..b5c790d2bc 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/User.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/User.java @@ -1,21 +1,21 @@ -package com.baeldung.loginextrafieldssimple; - -import java.util.Collection; - -import org.springframework.security.core.GrantedAuthority; - -public class User extends org.springframework.security.core.userdetails.User { - - private String domain; - - public User(String username, String domain, String password, boolean enabled, - boolean accountNonExpired, boolean credentialsNonExpired, - boolean accountNonLocked, Collection authorities) { - super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); - this.domain = domain; - } - - public String getDomain() { - return domain; - } -} +package com.baeldung.loginextrafieldssimple; + +import java.util.Collection; + +import org.springframework.security.core.GrantedAuthority; + +public class User extends org.springframework.security.core.userdetails.User { + + private String domain; + + public User(String username, String domain, String password, boolean enabled, + boolean accountNonExpired, boolean credentialsNonExpired, + boolean accountNonLocked, Collection authorities) { + super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); + this.domain = domain; + } + + public String getDomain() { + return domain; + } +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/UserRepository.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/UserRepository.java similarity index 95% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/UserRepository.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/UserRepository.java index 919e611b9c..02dfe9779a 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/UserRepository.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/UserRepository.java @@ -1,7 +1,7 @@ -package com.baeldung.loginextrafieldssimple; - -public interface UserRepository { - - public User findUser(String username, String domain); - -} +package com.baeldung.loginextrafieldssimple; + +public interface UserRepository { + + public User findUser(String username, String domain); + +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/WebController.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/WebController.java similarity index 96% rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/WebController.java rename to spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/WebController.java index 1b17de7bec..82add8f2e6 100644 --- a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/loginextrafieldssimple/WebController.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/loginextrafieldssimple/WebController.java @@ -1,51 +1,51 @@ -package com.baeldung.loginextrafieldssimple; - -import java.util.Optional; - -import org.springframework.security.authentication.AnonymousAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; - -@Controller -public class WebController { - - @RequestMapping("/") - public String root() { - return "redirect:/index"; - } - - @RequestMapping("/index") - public String index(Model model) { - getDomain().ifPresent(d -> { - model.addAttribute("domain", d); - }); - return "index"; - } - - @RequestMapping("/user/index") - public String userIndex(Model model) { - getDomain().ifPresent(d -> { - model.addAttribute("domain", d); - }); - return "user/index"; - } - - @RequestMapping("/login") - public String login() { - return "login"; - } - - private Optional getDomain() { - Authentication auth = SecurityContextHolder.getContext() - .getAuthentication(); - String domain = null; - if (auth != null && !auth.getClass().equals(AnonymousAuthenticationToken.class)) { - User user = (User) auth.getPrincipal(); - domain = user.getDomain(); - } - return Optional.ofNullable(domain); - } -} +package com.baeldung.loginextrafieldssimple; + +import java.util.Optional; + +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class WebController { + + @RequestMapping("/") + public String root() { + return "redirect:/index"; + } + + @RequestMapping("/index") + public String index(Model model) { + getDomain().ifPresent(d -> { + model.addAttribute("domain", d); + }); + return "index"; + } + + @RequestMapping("/user/index") + public String userIndex(Model model) { + getDomain().ifPresent(d -> { + model.addAttribute("domain", d); + }); + return "user/index"; + } + + @RequestMapping("/login") + public String login() { + return "login"; + } + + private Optional getDomain() { + Authentication auth = SecurityContextHolder.getContext() + .getAuthentication(); + String domain = null; + if (auth != null && !auth.getClass().equals(AnonymousAuthenticationToken.class)) { + User user = (User) auth.getPrincipal(); + domain = user.getDomain(); + } + return Optional.ofNullable(domain); + } +} diff --git a/spring-security-modules/spring-5-security/src/main/resources/application-extrafields.properties b/spring-security-modules/spring-security-web-login/src/main/resources/application-extrafields.properties similarity index 100% rename from spring-security-modules/spring-5-security/src/main/resources/application-extrafields.properties rename to spring-security-modules/spring-security-web-login/src/main/resources/application-extrafields.properties diff --git a/spring-security-modules/spring-security-web-login/src/main/resources/application.properties b/spring-security-modules/spring-security-web-login/src/main/resources/application.properties new file mode 100644 index 0000000000..8159ace060 --- /dev/null +++ b/spring-security-modules/spring-security-web-login/src/main/resources/application.properties @@ -0,0 +1,7 @@ +server.port=8081 + +logging.level.root=INFO + +logging.level.com.baeldung.dsl.ClientErrorLoggingFilter=DEBUG + +logging.level.org.springframework.security=DEBUG \ No newline at end of file diff --git a/spring-security-modules/spring-5-security/src/main/resources/static/css/main.css b/spring-security-modules/spring-security-web-login/src/main/resources/static/css/main.css similarity index 100% rename from spring-security-modules/spring-5-security/src/main/resources/static/css/main.css rename to spring-security-modules/spring-security-web-login/src/main/resources/static/css/main.css diff --git a/spring-security-modules/spring-5-security/src/main/resources/templatesextrafields/index.html b/spring-security-modules/spring-security-web-login/src/main/resources/templatesextrafields/index.html similarity index 100% rename from spring-security-modules/spring-5-security/src/main/resources/templatesextrafields/index.html rename to spring-security-modules/spring-security-web-login/src/main/resources/templatesextrafields/index.html diff --git a/spring-security-modules/spring-5-security/src/main/resources/templatesextrafields/login.html b/spring-security-modules/spring-security-web-login/src/main/resources/templatesextrafields/login.html similarity index 100% rename from spring-security-modules/spring-5-security/src/main/resources/templatesextrafields/login.html rename to spring-security-modules/spring-security-web-login/src/main/resources/templatesextrafields/login.html diff --git a/spring-security-modules/spring-5-security/src/main/resources/templatesextrafields/user/index.html b/spring-security-modules/spring-security-web-login/src/main/resources/templatesextrafields/user/index.html similarity index 100% rename from spring-security-modules/spring-5-security/src/main/resources/templatesextrafields/user/index.html rename to spring-security-modules/spring-security-web-login/src/main/resources/templatesextrafields/user/index.html diff --git a/spring-security-modules/spring-5-security/src/test/java/com/baeldung/loginextrafields/AbstractExtraLoginFieldsIntegrationTest.java b/spring-security-modules/spring-security-web-login/src/test/java/com/baeldung/loginextrafields/AbstractExtraLoginFieldsIntegrationTest.java similarity index 97% rename from spring-security-modules/spring-5-security/src/test/java/com/baeldung/loginextrafields/AbstractExtraLoginFieldsIntegrationTest.java rename to spring-security-modules/spring-security-web-login/src/test/java/com/baeldung/loginextrafields/AbstractExtraLoginFieldsIntegrationTest.java index c46cbd8113..f8b1097b7a 100644 --- a/spring-security-modules/spring-5-security/src/test/java/com/baeldung/loginextrafields/AbstractExtraLoginFieldsIntegrationTest.java +++ b/spring-security-modules/spring-security-web-login/src/test/java/com/baeldung/loginextrafields/AbstractExtraLoginFieldsIntegrationTest.java @@ -1,46 +1,46 @@ -package com.baeldung.loginextrafields; - -import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.web.FilterChainProxy; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -public abstract class AbstractExtraLoginFieldsIntegrationTest { - - @Autowired - private FilterChainProxy springSecurityFilterChain; - - @Autowired - private WebApplicationContext wac; - - protected MockMvc mockMvc; - - @Before - public void setup() { - this.mockMvc = MockMvcBuilders.webAppContextSetup(wac) - .apply(springSecurity(springSecurityFilterChain)) - .build(); - } - - @Test - public void givenRootPathAccess_thenRedirectToIndex() throws Exception { - this.mockMvc.perform(get("/")) - .andExpect(status().is3xxRedirection()) - .andExpect(redirectedUrlPattern("/index*")); - } - - @Test - public void givenSecuredResource_whenAccessUnauthenticated_thenRequiresAuthentication() throws Exception { - this.mockMvc.perform(get("/user/index")) - .andExpect(status().is3xxRedirection()) - .andExpect(redirectedUrlPattern("**/login")); - } -} +package com.baeldung.loginextrafields; + +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +public abstract class AbstractExtraLoginFieldsIntegrationTest { + + @Autowired + private FilterChainProxy springSecurityFilterChain; + + @Autowired + private WebApplicationContext wac; + + protected MockMvc mockMvc; + + @Before + public void setup() { + this.mockMvc = MockMvcBuilders.webAppContextSetup(wac) + .apply(springSecurity(springSecurityFilterChain)) + .build(); + } + + @Test + public void givenRootPathAccess_thenRedirectToIndex() throws Exception { + this.mockMvc.perform(get("/")) + .andExpect(status().is3xxRedirection()) + .andExpect(redirectedUrlPattern("/index*")); + } + + @Test + public void givenSecuredResource_whenAccessUnauthenticated_thenRequiresAuthentication() throws Exception { + this.mockMvc.perform(get("/user/index")) + .andExpect(status().is3xxRedirection()) + .andExpect(redirectedUrlPattern("**/login")); + } +} diff --git a/spring-security-modules/spring-5-security/src/test/java/com/baeldung/loginextrafields/LoginFieldsFullIntegrationTest.java b/spring-security-modules/spring-security-web-login/src/test/java/com/baeldung/loginextrafields/LoginFieldsFullIntegrationTest.java similarity index 97% rename from spring-security-modules/spring-5-security/src/test/java/com/baeldung/loginextrafields/LoginFieldsFullIntegrationTest.java rename to spring-security-modules/spring-security-web-login/src/test/java/com/baeldung/loginextrafields/LoginFieldsFullIntegrationTest.java index 54aece3b03..63c4e98505 100644 --- a/spring-security-modules/spring-5-security/src/test/java/com/baeldung/loginextrafields/LoginFieldsFullIntegrationTest.java +++ b/spring-security-modules/spring-security-web-login/src/test/java/com/baeldung/loginextrafields/LoginFieldsFullIntegrationTest.java @@ -1,72 +1,72 @@ -package com.baeldung.loginextrafields; - -import static org.junit.Assert.assertEquals; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.util.ArrayList; -import java.util.Collection; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.mock.web.MockHttpSession; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.web.context.HttpSessionSecurityContextRepository; -import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MvcResult; -import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; - -import com.baeldung.loginextrafieldscustom.ExtraLoginFieldsApplication; -import com.baeldung.loginextrafieldscustom.User; - -@RunWith(SpringRunner.class) -@SpringJUnitWebConfig -@SpringBootTest(classes = ExtraLoginFieldsApplication.class) -public class LoginFieldsFullIntegrationTest extends AbstractExtraLoginFieldsIntegrationTest { - - @Test - public void givenAccessSecuredResource_whenAuthenticated_thenAuthHasExtraFields() throws Exception { - MockHttpServletRequestBuilder securedResourceAccess = get("/user/index"); - MvcResult unauthenticatedResult = mockMvc.perform(securedResourceAccess) - .andExpect(status().is3xxRedirection()) - .andReturn(); - - MockHttpSession session = (MockHttpSession) unauthenticatedResult.getRequest() - .getSession(); - String loginUrl = unauthenticatedResult.getResponse() - .getRedirectedUrl(); - - User user = getUser(); - - mockMvc.perform(post(loginUrl) - .param("username", user.getUsername()) - .param("password", user.getPassword()) - .param("domain", user.getDomain()) - .session(session) - .with(csrf())) - .andExpect(status().is3xxRedirection()) - .andExpect(redirectedUrlPattern("**/user/index")) - .andReturn(); - - mockMvc.perform(securedResourceAccess.session(session)) - .andExpect(status().isOk()); - - SecurityContext securityContext - = (SecurityContext) session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY); - Authentication auth = securityContext.getAuthentication(); - assertEquals(((User)auth.getPrincipal()).getDomain(), user.getDomain()); - } - - private User getUser() { - Collection authorities = new ArrayList<>(); - return new User("myusername", "mydomain", "secret", true, true, true, true, authorities); - } - -} +package com.baeldung.loginextrafields; + +import static org.junit.Assert.assertEquals; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.ArrayList; +import java.util.Collection; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; + +import com.baeldung.loginextrafieldscustom.ExtraLoginFieldsApplication; +import com.baeldung.loginextrafieldscustom.User; + +@RunWith(SpringRunner.class) +@SpringJUnitWebConfig +@SpringBootTest(classes = ExtraLoginFieldsApplication.class) +public class LoginFieldsFullIntegrationTest extends AbstractExtraLoginFieldsIntegrationTest { + + @Test + public void givenAccessSecuredResource_whenAuthenticated_thenAuthHasExtraFields() throws Exception { + MockHttpServletRequestBuilder securedResourceAccess = get("/user/index"); + MvcResult unauthenticatedResult = mockMvc.perform(securedResourceAccess) + .andExpect(status().is3xxRedirection()) + .andReturn(); + + MockHttpSession session = (MockHttpSession) unauthenticatedResult.getRequest() + .getSession(); + String loginUrl = unauthenticatedResult.getResponse() + .getRedirectedUrl(); + + User user = getUser(); + + mockMvc.perform(post(loginUrl) + .param("username", user.getUsername()) + .param("password", user.getPassword()) + .param("domain", user.getDomain()) + .session(session) + .with(csrf())) + .andExpect(status().is3xxRedirection()) + .andExpect(redirectedUrlPattern("**/user/index")) + .andReturn(); + + mockMvc.perform(securedResourceAccess.session(session)) + .andExpect(status().isOk()); + + SecurityContext securityContext + = (SecurityContext) session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY); + Authentication auth = securityContext.getAuthentication(); + assertEquals(((User)auth.getPrincipal()).getDomain(), user.getDomain()); + } + + private User getUser() { + Collection authorities = new ArrayList<>(); + return new User("myusername", "mydomain", "secret", true, true, true, true, authorities); + } + +} diff --git a/spring-security-modules/spring-5-security/src/test/java/com/baeldung/loginextrafields/LoginFieldsSimpleIntegrationTest.java b/spring-security-modules/spring-security-web-login/src/test/java/com/baeldung/loginextrafields/LoginFieldsSimpleIntegrationTest.java similarity index 97% rename from spring-security-modules/spring-5-security/src/test/java/com/baeldung/loginextrafields/LoginFieldsSimpleIntegrationTest.java rename to spring-security-modules/spring-security-web-login/src/test/java/com/baeldung/loginextrafields/LoginFieldsSimpleIntegrationTest.java index 63167b04fa..2348afeb84 100644 --- a/spring-security-modules/spring-5-security/src/test/java/com/baeldung/loginextrafields/LoginFieldsSimpleIntegrationTest.java +++ b/spring-security-modules/spring-security-web-login/src/test/java/com/baeldung/loginextrafields/LoginFieldsSimpleIntegrationTest.java @@ -1,72 +1,72 @@ -package com.baeldung.loginextrafields; - -import static org.junit.Assert.assertEquals; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.util.ArrayList; -import java.util.Collection; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.mock.web.MockHttpSession; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.web.context.HttpSessionSecurityContextRepository; -import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MvcResult; -import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; - -import com.baeldung.loginextrafieldssimple.ExtraLoginFieldsApplication; -import com.baeldung.loginextrafieldssimple.User; - -@RunWith(SpringRunner.class) -@SpringJUnitWebConfig -@SpringBootTest(classes = ExtraLoginFieldsApplication.class) -public class LoginFieldsSimpleIntegrationTest extends AbstractExtraLoginFieldsIntegrationTest { - - @Test - public void givenAccessSecuredResource_whenAuthenticated_thenAuthHasExtraFields() throws Exception { - MockHttpServletRequestBuilder securedResourceAccess = get("/user/index"); - MvcResult unauthenticatedResult = mockMvc.perform(securedResourceAccess) - .andExpect(status().is3xxRedirection()) - .andReturn(); - - MockHttpSession session = (MockHttpSession) unauthenticatedResult.getRequest() - .getSession(); - String loginUrl = unauthenticatedResult.getResponse() - .getRedirectedUrl(); - - User user = getUser(); - - mockMvc.perform(post(loginUrl) - .param("username", user.getUsername()) - .param("password", user.getPassword()) - .param("domain", user.getDomain()) - .session(session) - .with(csrf())) - .andExpect(status().is3xxRedirection()) - .andExpect(redirectedUrlPattern("**/user/index")) - .andReturn(); - - mockMvc.perform(securedResourceAccess.session(session)) - .andExpect(status().isOk()); - - SecurityContext securityContext - = (SecurityContext) session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY); - Authentication auth = securityContext.getAuthentication(); - assertEquals(((User)auth.getPrincipal()).getDomain(), user.getDomain()); - } - - private User getUser() { - Collection authorities = new ArrayList<>(); - return new User("myusername", "mydomain", "secret", true, true, true, true, authorities); - } - -} +package com.baeldung.loginextrafields; + +import static org.junit.Assert.assertEquals; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.ArrayList; +import java.util.Collection; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; + +import com.baeldung.loginextrafieldssimple.ExtraLoginFieldsApplication; +import com.baeldung.loginextrafieldssimple.User; + +@RunWith(SpringRunner.class) +@SpringJUnitWebConfig +@SpringBootTest(classes = ExtraLoginFieldsApplication.class) +public class LoginFieldsSimpleIntegrationTest extends AbstractExtraLoginFieldsIntegrationTest { + + @Test + public void givenAccessSecuredResource_whenAuthenticated_thenAuthHasExtraFields() throws Exception { + MockHttpServletRequestBuilder securedResourceAccess = get("/user/index"); + MvcResult unauthenticatedResult = mockMvc.perform(securedResourceAccess) + .andExpect(status().is3xxRedirection()) + .andReturn(); + + MockHttpSession session = (MockHttpSession) unauthenticatedResult.getRequest() + .getSession(); + String loginUrl = unauthenticatedResult.getResponse() + .getRedirectedUrl(); + + User user = getUser(); + + mockMvc.perform(post(loginUrl) + .param("username", user.getUsername()) + .param("password", user.getPassword()) + .param("domain", user.getDomain()) + .session(session) + .with(csrf())) + .andExpect(status().is3xxRedirection()) + .andExpect(redirectedUrlPattern("**/user/index")) + .andReturn(); + + mockMvc.perform(securedResourceAccess.session(session)) + .andExpect(status().isOk()); + + SecurityContext securityContext + = (SecurityContext) session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY); + Authentication auth = securityContext.getAuthentication(); + assertEquals(((User)auth.getPrincipal()).getDomain(), user.getDomain()); + } + + private User getUser() { + Collection authorities = new ArrayList<>(); + return new User("myusername", "mydomain", "secret", true, true, true, true, authorities); + } + +} From 8eb4c96fca00de1e716b59eaf9214f8e36f69534 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 19:33:43 +0800 Subject: [PATCH 230/249] Update README.md --- httpclient/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient/README.md b/httpclient/README.md index 3c5b0b3376..4f3fb8c671 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -14,7 +14,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [HttpClient 4 – Follow Redirects for POST](https://www.baeldung.com/httpclient-redirect-on-http-post) - [Multipart Upload with HttpClient 4](https://www.baeldung.com/httpclient-multipart-upload) - [HttpAsyncClient Tutorial](https://www.baeldung.com/httpasyncclient-tutorial) -- [HttpClient 4 Tutorial](https://www.baeldung.com/httpclient-guide) +- [Apache HttpClient Tutorial](https://www.baeldung.com/httpclient-guide) - [Advanced HttpClient Configuration](https://www.baeldung.com/httpclient-advanced-config) - [HttpClient 4 – Do Not Follow Redirects](https://www.baeldung.com/httpclient-stop-follow-redirect) - [Custom User-Agent in HttpClient 4](https://www.baeldung.com/httpclient-user-agent-header) From 776a59d89d75b3ff01604cc3139908b884ccc06a Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 19:38:29 +0800 Subject: [PATCH 231/249] Update README.md --- httpclient-simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient-simple/README.md b/httpclient-simple/README.md index 8875af1ea0..fa3be5e72d 100644 --- a/httpclient-simple/README.md +++ b/httpclient-simple/README.md @@ -10,7 +10,7 @@ This module contains articles about HTTPClient that are part of the HTTPClient E - [HttpClient 4 – Send Custom Cookie](https://www.baeldung.com/httpclient-4-cookies) - [Custom HTTP Header with the HttpClient](https://www.baeldung.com/httpclient-custom-http-header) - [HttpClient Basic Authentication](https://www.baeldung.com/httpclient-4-basic-authentication) -- [Posting with HttpClient](https://www.baeldung.com/httpclient-post-http-request) +- [Posting with Apache HttpClient](https://www.baeldung.com/httpclient-post-http-request) - [Adding Parameters to HttpClient Requests](https://www.baeldung.com/apache-httpclient-parameters) From 20dee2296401a250597397b2c466320610fa1d91 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 19:41:06 +0800 Subject: [PATCH 232/249] Update README.md --- httpclient/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient/README.md b/httpclient/README.md index 4f3fb8c671..43e2b14915 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -13,7 +13,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Unshorten URLs with HttpClient](https://www.baeldung.com/unshorten-url-httpclient) - [HttpClient 4 – Follow Redirects for POST](https://www.baeldung.com/httpclient-redirect-on-http-post) - [Multipart Upload with HttpClient 4](https://www.baeldung.com/httpclient-multipart-upload) -- [HttpAsyncClient Tutorial](https://www.baeldung.com/httpasyncclient-tutorial) +- [Apache HttpAsyncClient Tutorial](https://www.baeldung.com/httpasyncclient-tutorial) - [Apache HttpClient Tutorial](https://www.baeldung.com/httpclient-guide) - [Advanced HttpClient Configuration](https://www.baeldung.com/httpclient-advanced-config) - [HttpClient 4 – Do Not Follow Redirects](https://www.baeldung.com/httpclient-stop-follow-redirect) From 06ce4256f68ff5f6965335e085fe117b8cf07fa8 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 19:45:54 +0800 Subject: [PATCH 233/249] Update README.md --- httpclient/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient/README.md b/httpclient/README.md index 43e2b14915..49cee36ba1 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -12,7 +12,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [HttpClient 4 Cookbook](https://www.baeldung.com/httpclient4) - [Unshorten URLs with HttpClient](https://www.baeldung.com/unshorten-url-httpclient) - [HttpClient 4 – Follow Redirects for POST](https://www.baeldung.com/httpclient-redirect-on-http-post) -- [Multipart Upload with HttpClient 4](https://www.baeldung.com/httpclient-multipart-upload) +- [Multipart Upload with Apache HttpClient](https://www.baeldung.com/httpclient-multipart-upload) - [Apache HttpAsyncClient Tutorial](https://www.baeldung.com/httpasyncclient-tutorial) - [Apache HttpClient Tutorial](https://www.baeldung.com/httpclient-guide) - [Advanced HttpClient Configuration](https://www.baeldung.com/httpclient-advanced-config) From df5ed73ad60405b86259b7a5c793897b9c9e7237 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 19:50:02 +0800 Subject: [PATCH 234/249] Update README.md --- httpclient-simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient-simple/README.md b/httpclient-simple/README.md index fa3be5e72d..47293f2234 100644 --- a/httpclient-simple/README.md +++ b/httpclient-simple/README.md @@ -8,7 +8,7 @@ This module contains articles about HTTPClient that are part of the HTTPClient E - [HttpClient with SSL](https://www.baeldung.com/httpclient-ssl) - [HttpClient Timeout](https://www.baeldung.com/httpclient-timeout) - [HttpClient 4 – Send Custom Cookie](https://www.baeldung.com/httpclient-4-cookies) -- [Custom HTTP Header with the HttpClient](https://www.baeldung.com/httpclient-custom-http-header) +- [Custom HTTP Header with the Apache HttpClient](https://www.baeldung.com/httpclient-custom-http-header) - [HttpClient Basic Authentication](https://www.baeldung.com/httpclient-4-basic-authentication) - [Posting with Apache HttpClient](https://www.baeldung.com/httpclient-post-http-request) - [Adding Parameters to HttpClient Requests](https://www.baeldung.com/apache-httpclient-parameters) From 66047a7c017515a9e5148a088763bfa5f66a7def Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 19:57:40 +0800 Subject: [PATCH 235/249] Update README.md --- httpclient/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient/README.md b/httpclient/README.md index 49cee36ba1..61e50721f9 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -11,7 +11,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [HttpClient 4 – Cancel Request](https://www.baeldung.com/httpclient-cancel-request) - [HttpClient 4 Cookbook](https://www.baeldung.com/httpclient4) - [Unshorten URLs with HttpClient](https://www.baeldung.com/unshorten-url-httpclient) -- [HttpClient 4 – Follow Redirects for POST](https://www.baeldung.com/httpclient-redirect-on-http-post) +- [Apache HttpClient – Follow Redirects for POST](https://www.baeldung.com/httpclient-redirect-on-http-post) - [Multipart Upload with Apache HttpClient](https://www.baeldung.com/httpclient-multipart-upload) - [Apache HttpAsyncClient Tutorial](https://www.baeldung.com/httpasyncclient-tutorial) - [Apache HttpClient Tutorial](https://www.baeldung.com/httpclient-guide) From f1d79a2aee78a7eafde96cd6b6de26e4f340da42 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 20:01:22 +0800 Subject: [PATCH 236/249] Update README.md --- httpclient/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient/README.md b/httpclient/README.md index 61e50721f9..9eed8eaff2 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -16,7 +16,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Apache HttpAsyncClient Tutorial](https://www.baeldung.com/httpasyncclient-tutorial) - [Apache HttpClient Tutorial](https://www.baeldung.com/httpclient-guide) - [Advanced HttpClient Configuration](https://www.baeldung.com/httpclient-advanced-config) -- [HttpClient 4 – Do Not Follow Redirects](https://www.baeldung.com/httpclient-stop-follow-redirect) +- [Apache HttpClient – Do Not Follow Redirects](https://www.baeldung.com/httpclient-stop-follow-redirect) - [Custom User-Agent in HttpClient 4](https://www.baeldung.com/httpclient-user-agent-header) - [Apache HttpClient Connection Management](https://www.baeldung.com/httpclient-connection-management) - More articles: [[next -->]](../httpclient-2) From 6e5744c2cfa55a32583f0f0466b4bfb95318c8ed Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 20:04:11 +0800 Subject: [PATCH 237/249] Update README.md --- httpclient-simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient-simple/README.md b/httpclient-simple/README.md index 47293f2234..58d881e3ba 100644 --- a/httpclient-simple/README.md +++ b/httpclient-simple/README.md @@ -4,7 +4,7 @@ This module contains articles about HTTPClient that are part of the HTTPClient E ### Relevant Articles -- [HttpClient 4 – Get the Status Code](https://www.baeldung.com/httpclient-status-code) +- [Apache HttpClient – Get the Status Code](https://www.baeldung.com/httpclient-status-code) - [HttpClient with SSL](https://www.baeldung.com/httpclient-ssl) - [HttpClient Timeout](https://www.baeldung.com/httpclient-timeout) - [HttpClient 4 – Send Custom Cookie](https://www.baeldung.com/httpclient-4-cookies) From cd4813666b1911884e4e63c1e98303617e90f5c1 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 20:07:20 +0800 Subject: [PATCH 238/249] Update README.md --- httpclient/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient/README.md b/httpclient/README.md index 9eed8eaff2..8ab5200765 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -8,7 +8,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: -- [HttpClient 4 – Cancel Request](https://www.baeldung.com/httpclient-cancel-request) +- [Apache HttpClient – Cancel Request](https://www.baeldung.com/httpclient-cancel-request) - [HttpClient 4 Cookbook](https://www.baeldung.com/httpclient4) - [Unshorten URLs with HttpClient](https://www.baeldung.com/unshorten-url-httpclient) - [Apache HttpClient – Follow Redirects for POST](https://www.baeldung.com/httpclient-redirect-on-http-post) From 83518bc95eb1c789fb9a6c8f53c6adf2823105c5 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 20:10:03 +0800 Subject: [PATCH 239/249] Update README.md --- httpclient/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient/README.md b/httpclient/README.md index 8ab5200765..d350426b38 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -17,6 +17,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Apache HttpClient Tutorial](https://www.baeldung.com/httpclient-guide) - [Advanced HttpClient Configuration](https://www.baeldung.com/httpclient-advanced-config) - [Apache HttpClient – Do Not Follow Redirects](https://www.baeldung.com/httpclient-stop-follow-redirect) -- [Custom User-Agent in HttpClient 4](https://www.baeldung.com/httpclient-user-agent-header) +- [Custom User-Agent in Apache HttpClient](https://www.baeldung.com/httpclient-user-agent-header) - [Apache HttpClient Connection Management](https://www.baeldung.com/httpclient-connection-management) - More articles: [[next -->]](../httpclient-2) From d36b55e3537d54f00a60816433868710aeb07d17 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 20:11:25 +0800 Subject: [PATCH 240/249] Update README.md --- httpclient/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient/README.md b/httpclient/README.md index d350426b38..c9e4673d0f 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -9,7 +9,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [Apache HttpClient – Cancel Request](https://www.baeldung.com/httpclient-cancel-request) -- [HttpClient 4 Cookbook](https://www.baeldung.com/httpclient4) +- [Apache HttpClient 4 Cookbook](https://www.baeldung.com/httpclient4) - [Unshorten URLs with HttpClient](https://www.baeldung.com/unshorten-url-httpclient) - [Apache HttpClient – Follow Redirects for POST](https://www.baeldung.com/httpclient-redirect-on-http-post) - [Multipart Upload with Apache HttpClient](https://www.baeldung.com/httpclient-multipart-upload) From 7e4b7a11276dfaa673084057ef11f45fa7e6d157 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 20:13:51 +0800 Subject: [PATCH 241/249] Update README.md --- httpclient/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient/README.md b/httpclient/README.md index c9e4673d0f..067ed6d0b4 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -10,7 +10,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Apache HttpClient – Cancel Request](https://www.baeldung.com/httpclient-cancel-request) - [Apache HttpClient 4 Cookbook](https://www.baeldung.com/httpclient4) -- [Unshorten URLs with HttpClient](https://www.baeldung.com/unshorten-url-httpclient) +- [Unshorten URLs with Apache HttpClient](https://www.baeldung.com/unshorten-url-httpclient) - [Apache HttpClient – Follow Redirects for POST](https://www.baeldung.com/httpclient-redirect-on-http-post) - [Multipart Upload with Apache HttpClient](https://www.baeldung.com/httpclient-multipart-upload) - [Apache HttpAsyncClient Tutorial](https://www.baeldung.com/httpasyncclient-tutorial) From 33eb2bad8ec34456f0260cd045760f5e16959753 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 20:16:14 +0800 Subject: [PATCH 242/249] Update README.md --- httpclient-simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient-simple/README.md b/httpclient-simple/README.md index 58d881e3ba..476071e616 100644 --- a/httpclient-simple/README.md +++ b/httpclient-simple/README.md @@ -5,7 +5,7 @@ This module contains articles about HTTPClient that are part of the HTTPClient E ### Relevant Articles - [Apache HttpClient – Get the Status Code](https://www.baeldung.com/httpclient-status-code) -- [HttpClient with SSL](https://www.baeldung.com/httpclient-ssl) +- [Apache HttpClient with SSL](https://www.baeldung.com/httpclient-ssl) - [HttpClient Timeout](https://www.baeldung.com/httpclient-timeout) - [HttpClient 4 – Send Custom Cookie](https://www.baeldung.com/httpclient-4-cookies) - [Custom HTTP Header with the Apache HttpClient](https://www.baeldung.com/httpclient-custom-http-header) From 0d08ee67ada016130dbf96a777b6f5ccbb756e53 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 20:19:17 +0800 Subject: [PATCH 243/249] Update README.md --- httpclient-simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient-simple/README.md b/httpclient-simple/README.md index 476071e616..c37d87f005 100644 --- a/httpclient-simple/README.md +++ b/httpclient-simple/README.md @@ -6,7 +6,7 @@ This module contains articles about HTTPClient that are part of the HTTPClient E - [Apache HttpClient – Get the Status Code](https://www.baeldung.com/httpclient-status-code) - [Apache HttpClient with SSL](https://www.baeldung.com/httpclient-ssl) -- [HttpClient Timeout](https://www.baeldung.com/httpclient-timeout) +- [Apache HttpClient Timeout](https://www.baeldung.com/httpclient-timeout) - [HttpClient 4 – Send Custom Cookie](https://www.baeldung.com/httpclient-4-cookies) - [Custom HTTP Header with the Apache HttpClient](https://www.baeldung.com/httpclient-custom-http-header) - [HttpClient Basic Authentication](https://www.baeldung.com/httpclient-4-basic-authentication) From eaf16d4e99ae77e8e58edf3f03858ea755fe3953 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 22:55:00 +0800 Subject: [PATCH 244/249] Update README.md --- persistence-modules/hibernate-annotations/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/hibernate-annotations/README.md b/persistence-modules/hibernate-annotations/README.md index c7efe77e22..9b68579151 100644 --- a/persistence-modules/hibernate-annotations/README.md +++ b/persistence-modules/hibernate-annotations/README.md @@ -9,4 +9,4 @@ This module contains articles about Annotations used in Hibernate. - [Hibernate One to Many Annotation Tutorial](https://www.baeldung.com/hibernate-one-to-many) - [Hibernate @WhereJoinTable Annotation](https://www.baeldung.com/hibernate-wherejointable) - [Usage of the Hibernate @LazyCollection Annotation](https://www.baeldung.com/hibernate-lazycollection) -- [@Immutable in Hibernate](http://www.baeldung.com/hibernate-immutable) +- [@Immutable in Hibernate](https://www.baeldung.com/hibernate-immutable) From 4d6d1bf6fa5234427577bca8f795785ba0fb0077 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Tue, 5 Apr 2022 23:26:50 +0800 Subject: [PATCH 245/249] Update README.md --- httpclient-simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient-simple/README.md b/httpclient-simple/README.md index c37d87f005..4ee4d12f47 100644 --- a/httpclient-simple/README.md +++ b/httpclient-simple/README.md @@ -11,7 +11,7 @@ This module contains articles about HTTPClient that are part of the HTTPClient E - [Custom HTTP Header with the Apache HttpClient](https://www.baeldung.com/httpclient-custom-http-header) - [HttpClient Basic Authentication](https://www.baeldung.com/httpclient-4-basic-authentication) - [Posting with Apache HttpClient](https://www.baeldung.com/httpclient-post-http-request) -- [Adding Parameters to HttpClient Requests](https://www.baeldung.com/apache-httpclient-parameters) +- [Adding Parameters to Apache HttpClient Requests](https://www.baeldung.com/apache-httpclient-parameters) ### Running the Tests From 21b37a43468e3ffc27388d3ba4df4fe9590c537a Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 6 Apr 2022 00:16:19 +0800 Subject: [PATCH 246/249] Update README.md --- persistence-modules/java-mongodb-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-mongodb-2/README.md b/persistence-modules/java-mongodb-2/README.md index 646917b04d..bee5439ab1 100644 --- a/persistence-modules/java-mongodb-2/README.md +++ b/persistence-modules/java-mongodb-2/README.md @@ -10,4 +10,5 @@ This module contains articles about MongoDB in Java. - [Geospatial Support in MongoDB](https://www.baeldung.com/mongodb-geospatial-support) - [MongoDB Aggregations Using Java](https://www.baeldung.com/java-mongodb-aggregations) - [Retrieve a Value from MongoDB by Its Key Name](https://www.baeldung.com/mongodb-get-value-by-key-name) +- [Push and Set Operations in Same MongoDB Update](https://www.baeldung.com/java-mongodb-push-set) - More articles: [[<-- prev]](../java-mongodb) From 131ef763099ac84f8057c5935b01c7fee91de30a Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 6 Apr 2022 00:22:28 +0800 Subject: [PATCH 247/249] Update README.md --- httpclient-simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient-simple/README.md b/httpclient-simple/README.md index 4ee4d12f47..546401a4f6 100644 --- a/httpclient-simple/README.md +++ b/httpclient-simple/README.md @@ -9,7 +9,7 @@ This module contains articles about HTTPClient that are part of the HTTPClient E - [Apache HttpClient Timeout](https://www.baeldung.com/httpclient-timeout) - [HttpClient 4 – Send Custom Cookie](https://www.baeldung.com/httpclient-4-cookies) - [Custom HTTP Header with the Apache HttpClient](https://www.baeldung.com/httpclient-custom-http-header) -- [HttpClient Basic Authentication](https://www.baeldung.com/httpclient-4-basic-authentication) +- [Apache HttpClient Basic Authentication](https://www.baeldung.com/httpclient-basic-authentication) - [Posting with Apache HttpClient](https://www.baeldung.com/httpclient-post-http-request) - [Adding Parameters to Apache HttpClient Requests](https://www.baeldung.com/apache-httpclient-parameters) From c7065537eee91d3aee249efdf5abba5f110af747 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 6 Apr 2022 00:26:14 +0800 Subject: [PATCH 248/249] Update README.md --- httpclient-simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpclient-simple/README.md b/httpclient-simple/README.md index 546401a4f6..2960037ece 100644 --- a/httpclient-simple/README.md +++ b/httpclient-simple/README.md @@ -7,7 +7,7 @@ This module contains articles about HTTPClient that are part of the HTTPClient E - [Apache HttpClient – Get the Status Code](https://www.baeldung.com/httpclient-status-code) - [Apache HttpClient with SSL](https://www.baeldung.com/httpclient-ssl) - [Apache HttpClient Timeout](https://www.baeldung.com/httpclient-timeout) -- [HttpClient 4 – Send Custom Cookie](https://www.baeldung.com/httpclient-4-cookies) +- [Apache HttpClient – Send Custom Cookie](https://www.baeldung.com/httpclient-cookies) - [Custom HTTP Header with the Apache HttpClient](https://www.baeldung.com/httpclient-custom-http-header) - [Apache HttpClient Basic Authentication](https://www.baeldung.com/httpclient-basic-authentication) - [Posting with Apache HttpClient](https://www.baeldung.com/httpclient-post-http-request) From 8cb2197c8578441df2d2e12272e598f00cb4c483 Mon Sep 17 00:00:00 2001 From: sebx59 Date: Wed, 6 Apr 2022 14:15:10 +0200 Subject: [PATCH 249/249] BAEL-4674 - Basic Authentication in JMeter (#11882) * BAEL-4674 - Basic Authentication in JMeter Test plans & resources for article Basic Authentication in JMeter Server classes to test basic auth against local server * handled comments * updated following feedback Co-authored-by: Sebastien HARDEMAN --- jmeter/pom.xml | 4 + .../WebSecurityConfiguration.java | 52 ++++++ .../controller/SecuredUuidController.java | 24 +++ .../Basic Authentication - JSR223.jmx | 164 +++++++++++++++++ ...ation - authorization manager with CSV.jmx | 166 ++++++++++++++++++ ...Authentication - authorization manager.jmx | 159 +++++++++++++++++ .../main/resources/Basic Authentication.jmx | 139 +++++++++++++++ jmeter/src/main/resources/credentials.csv | 10 ++ 8 files changed, 718 insertions(+) create mode 100644 jmeter/src/main/java/com/baeldung/configuration/WebSecurityConfiguration.java create mode 100644 jmeter/src/main/java/com/baeldung/controller/SecuredUuidController.java create mode 100644 jmeter/src/main/resources/Basic Authentication - JSR223.jmx create mode 100644 jmeter/src/main/resources/Basic Authentication - authorization manager with CSV.jmx create mode 100644 jmeter/src/main/resources/Basic Authentication - authorization manager.jmx create mode 100644 jmeter/src/main/resources/Basic Authentication.jmx create mode 100644 jmeter/src/main/resources/credentials.csv diff --git a/jmeter/pom.xml b/jmeter/pom.xml index 199d95e0d6..b2e4197dfc 100644 --- a/jmeter/pom.xml +++ b/jmeter/pom.xml @@ -33,6 +33,10 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-starter-security + diff --git a/jmeter/src/main/java/com/baeldung/configuration/WebSecurityConfiguration.java b/jmeter/src/main/java/com/baeldung/configuration/WebSecurityConfiguration.java new file mode 100644 index 0000000000..8700dc3df4 --- /dev/null +++ b/jmeter/src/main/java/com/baeldung/configuration/WebSecurityConfiguration.java @@ -0,0 +1,52 @@ +package com.baeldung.configuration; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + + PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); + + auth.inMemoryAuthentication() + .withUser("admin").password(encoder.encode("admin")).roles("USER", "ADMIN") + .and() + .withUser("user1").password(encoder.encode("password1")).roles("USER") + .and() + .withUser("user2").password(encoder.encode("password2")).roles("USER") + .and() + .withUser("user3").password(encoder.encode("password3")).roles("USER") + .and() + .withUser("user4").password(encoder.encode("password4")).roles("USER") + .and() + .withUser("user5").password(encoder.encode("password5")).roles("USER") + .and() + .withUser("user6").password(encoder.encode("password6")).roles("USER") + .and() + .withUser("user7").password(encoder.encode("password7")).roles("USER") + .and() + .withUser("user8").password(encoder.encode("password8")).roles("USER") + .and() + .withUser("user9").password(encoder.encode("password9")).roles("USER") + .and() + .withUser("user10").password(encoder.encode("password10")).roles("USER"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + + http + .authorizeRequests() + .antMatchers("/secured/**").authenticated() + .anyRequest().permitAll() + .and() + .httpBasic(); + } +} diff --git a/jmeter/src/main/java/com/baeldung/controller/SecuredUuidController.java b/jmeter/src/main/java/com/baeldung/controller/SecuredUuidController.java new file mode 100644 index 0000000000..fa6570ff6f --- /dev/null +++ b/jmeter/src/main/java/com/baeldung/controller/SecuredUuidController.java @@ -0,0 +1,24 @@ +package com.baeldung.controller; + +import java.util.UUID; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.model.Response; + +@RestController +public class SecuredUuidController { + + private static final Logger LOGGER = LoggerFactory.getLogger(SecuredUuidController.class); + + @GetMapping("/secured/uuid") + public Response uuid() { + + LOGGER.info("Returning response"); + + return new Response(String.format("Secured test message... %s.", UUID.randomUUID())); + } +} diff --git a/jmeter/src/main/resources/Basic Authentication - JSR223.jmx b/jmeter/src/main/resources/Basic Authentication - JSR223.jmx new file mode 100644 index 0000000000..b15b625b95 --- /dev/null +++ b/jmeter/src/main/resources/Basic Authentication - JSR223.jmx @@ -0,0 +1,164 @@ + + + + + + false + false + + + + + + + + + + host + localhost + = + Host of Webservice + + + port + 8080 + Port of web server + = + + + username + user1 + = + + + password + password1 + = + + + + + + continue + + false + 1 + + 1 + 1 + 1375525852000 + 1375525852000 + false + + + false + + + + + + + ${host} + ${port} + + + /secured/uuid + GET + false + false + false + false + + + + + + + false + + + import org.apache.commons.codec.binary.Base64; + +String username = vars.get("username"); +String password = vars.get("password"); +String credentials = username + ":" + password; +byte[] encodedUsernamePassword = Base64.encodeBase64(credentials.getBytes()); +vars.put("base64Credentials", new String(encodedUsernamePassword)); + + java + + + + + + Content-Type + text/xml; charset=utf-8 + + + Authorization + basic ${base64Credentials} + + + + + + + 200 + + + Assertion.response_code + false + 8 + + + + + Secured test message... + + Verify content in response + Assertion.response_data + false + 16 + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + false + false + true + false + false + false + false + true + false + false + true + true + 0 + true + true + true + true + + + + + + + + diff --git a/jmeter/src/main/resources/Basic Authentication - authorization manager with CSV.jmx b/jmeter/src/main/resources/Basic Authentication - authorization manager with CSV.jmx new file mode 100644 index 0000000000..8309cfd6f5 --- /dev/null +++ b/jmeter/src/main/resources/Basic Authentication - authorization manager with CSV.jmx @@ -0,0 +1,166 @@ + + + + + + false + false + + + + + + + + + + host + localhost + = + Host of Webservice + + + port + 8080 + Port of web server + = + + + csvFileLocation + D:\\work\\credentials.csv + = + + + + + + + + Content-Type + text/xml; charset=utf-8 + + + + + + continue + + false + 20 + + 1 + 0 + 1375525852000 + 1375525852000 + false + + + false + + + + , + + ${csvFileLocation} + false + false + true + shareMode.all + false + username,password + + + + + + http://${host}:${port}/secured/uuid + ${username} + ${password} + + + + + false + true + + + + + + + ${host} + ${port} + + + /secured/uuid + GET + false + false + false + false + + + + + + + + 200 + + + Assertion.response_code + false + 8 + + + + + Secured test message... + + Verify content in response + Assertion.response_data + false + 16 + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + false + false + true + false + false + false + false + true + false + false + true + true + 0 + true + true + true + true + + + + + + + + diff --git a/jmeter/src/main/resources/Basic Authentication - authorization manager.jmx b/jmeter/src/main/resources/Basic Authentication - authorization manager.jmx new file mode 100644 index 0000000000..7d48a4c097 --- /dev/null +++ b/jmeter/src/main/resources/Basic Authentication - authorization manager.jmx @@ -0,0 +1,159 @@ + + + + + + false + false + + + + + + + + + + host + localhost + = + Host of Webservice + + + port + 8080 + Port of web server + = + + + username + user1 + = + + + password + password1 + = + + + + + + + + Content-Type + text/xml; charset=utf-8 + + + + + + continue + + false + 1 + + 1 + 0 + 1375525852000 + 1375525852000 + false + + + false + + + + + + http://${host}:${port}/secured/uuid + ${username} + ${password} + + + + + false + true + + + + + + + ${host} + ${port} + + + /secured/uuid + GET + false + false + false + false + + + + + + + + 200 + + + Assertion.response_code + false + 8 + + + + + Secured test message... + + Verify content in response + Assertion.response_data + false + 16 + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + false + false + true + false + false + false + false + true + false + false + true + true + 0 + true + true + true + true + + + + + + + + diff --git a/jmeter/src/main/resources/Basic Authentication.jmx b/jmeter/src/main/resources/Basic Authentication.jmx new file mode 100644 index 0000000000..e23d47717d --- /dev/null +++ b/jmeter/src/main/resources/Basic Authentication.jmx @@ -0,0 +1,139 @@ + + + + + + false + false + + + + + + + + + + host + localhost + = + Host of Webservice + + + port + 8080 + Port of web server + = + + + + + + continue + + false + 2 + + 5 + 5 + 1375525852000 + 1375525852000 + false + + + false + + + + + + + ${host} + ${port} + + + /secured/uuid + GET + false + false + false + false + + + + + + + + + Content-Type + text/xml; charset=utf-8 + + + Authorization + dXNlcjE6cGFzc3dvcmQx + + + + + + + 200 + + + Assertion.response_code + false + 8 + + + + + Secured test message... + + Verify content in response + Assertion.response_data + false + 16 + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + false + false + true + false + false + false + false + true + false + false + true + true + 0 + true + true + true + true + + + + + + + + diff --git a/jmeter/src/main/resources/credentials.csv b/jmeter/src/main/resources/credentials.csv new file mode 100644 index 0000000000..9aba7cf181 --- /dev/null +++ b/jmeter/src/main/resources/credentials.csv @@ -0,0 +1,10 @@ +user1,password1 +user2,password2 +user3,password3 +user4,password4 +user5,password5 +user6,password6 +user7,password7 +user8,password8 +user9,password9 +user10,password10 \ No newline at end of file